diff --git a/pythonlanguagesupport.cpp b/pythonlanguagesupport.cpp index 5954ceee..32d54b43 100644 --- a/pythonlanguagesupport.cpp +++ b/pythonlanguagesupport.cpp @@ -1,194 +1,199 @@ /***************************************************************************** * Copyright (c) 2007 Andreas Pakulat * * Copyright (c) 2007 Piyush verma * * Copyright (c) 2012 Sven Brauch * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************** */ #include "pythonlanguagesupport.h" #include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pythonparsejob.h" #include "pythonhighlighting.h" #include "duchain/pythoneditorintegrator.h" #include "codecompletion/model.h" #include "codegen/refactoring.h" #include "codegen/correctionfilegenerator.h" #include "kdevpythonversion.h" #include "pep8kcm/kcm_pep8.h" #include "docfilekcm/kcm_docfiles.h" #include #include "pythondebug.h" using namespace KDevelop; K_PLUGIN_FACTORY_WITH_JSON( KDevPythonSupportFactory, "kdevpythonsupport.json", registerPlugin(); ) namespace Python { LanguageSupport* LanguageSupport::m_self = 0; KDevelop::ContextMenuExtension LanguageSupport::contextMenuExtension(KDevelop::Context* context) { ContextMenuExtension cm; EditorContext *ec = dynamic_cast(context); if (ec && ICore::self()->languageController()->languagesForUrl(ec->url()).contains(this)) { // It's a Python file, let's add our context menu. m_refactoring->fillContextMenu(cm, context); TypeCorrection::self().doContextMenu(cm, context); } return cm; } LanguageSupport::LanguageSupport( QObject* parent, const QVariantList& /*args*/ ) : KDevelop::IPlugin("pythonlanguagesupport", parent ) , KDevelop::ILanguageSupport() , m_highlighting( new Highlighting( this ) ) , m_refactoring( new Refactoring( this ) ) { KDEV_USE_EXTENSION_INTERFACE( KDevelop::ILanguageSupport ) KDEV_USE_EXTENSION_INTERFACE( KDevelop::ILanguageCheckProvider ) m_self = this; PythonCodeCompletionModel* codeCompletion = new PythonCodeCompletionModel(this); new KDevelop::CodeCompletion(this, codeCompletion, "Python"); auto assistantsManager = core()->languageController()->staticAssistantsManager(); assistantsManager->registerAssistant(StaticAssistant::Ptr(new RenameAssistant(this))); QObject::connect(ICore::self()->documentController(), &IDocumentController::documentOpened, this, &LanguageSupport::documentOpened); } void LanguageSupport::documentOpened(IDocument* doc) { if ( ! ICore::self()->languageController()->languagesForUrl(doc->url()).contains(this) ) { // not a python file return; } DUChainReadLocker lock; TopDUContextPointer topContext = TopDUContextPointer(DUChain::self()->chainForDocument(doc->url())); lock.unlock(); ParseJob::eventuallyDoPEP8Checking(IndexedString(doc->url()), topContext.data()); } LanguageSupport::~LanguageSupport() { + parseLock()->lockForWrite(); + // By locking the parse-mutexes, we make sure that parse jobs get a chance to finish in a good state + parseLock()->unlock(); + delete m_highlighting; m_highlighting = 0; } KDevelop::ParseJob *LanguageSupport::createParseJob( const IndexedString& url ) { return new ParseJob(url, this); } QString LanguageSupport::name() const { return "Python"; } LanguageSupport* LanguageSupport::self() { return m_self; } SourceFormatterItemList LanguageSupport::sourceFormatterItems() const { SourceFormatterStyle autopep8("autopep8"); autopep8.setCaption("autopep8"); autopep8.setDescription(i18n("Format source with the autopep8 formatter.")); autopep8.setOverrideSample("class klass:\n def method(arg1,arg2):\n a=3+5\n" "def function(arg,*vararg,**kwargs): return arg+kwarg[0]\nfunction(3, 5, 7)"); using P = SourceFormatterStyle::MimeHighlightPair; autopep8.setMimeTypes(SourceFormatterStyle::MimeList{ P{"text/x-python", "Python"} }); QString autopep8path = QStandardPaths::findExecutable("autopep8"); if (autopep8path.isEmpty()) { // TODO: proper error handling/user notification qWarning() << "Could not find the autopep8 executable"; autopep8path = "/usr/bin/autopep8"; } autopep8.setContent(autopep8path + " -i $TMPFILE"); return SourceFormatterItemList{SourceFormatterStyleItem{"customscript", autopep8}}; } KDevelop::ICodeHighlighting* LanguageSupport::codeHighlighting() const { return m_highlighting; } BasicRefactoring* LanguageSupport::refactoring() const { return m_refactoring; } ILanguageSupport::WhitespaceSensitivity LanguageSupport::whitespaceSensititivy() const { return ILanguageSupport::IndentOnly; } QList LanguageSupport::providedChecks() { return {}; } int LanguageSupport::configPages() const { return 2; } KDevelop::ConfigPage* LanguageSupport::configPage(int number, QWidget* parent) { if (number == 0) { return new PEP8KCModule(this, parent); } else if (number == 1) { return new DocfilesKCModule(this, parent); } return nullptr; } } #include "pythonlanguagesupport.moc"