diff --git a/language/codecompletion/codecompletionworker.cpp b/language/codecompletion/codecompletionworker.cpp index b2ff0642ab..f420b7bc98 100644 --- a/language/codecompletion/codecompletionworker.cpp +++ b/language/codecompletion/codecompletionworker.cpp @@ -1,223 +1,225 @@ /* * KDevelop Generic Code Completion Support * * Copyright 2006-2008 Hamish Rodda * Copyright 2007-2008 David Nolden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library 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, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "codecompletionworker.h" #include #include #include #include #include "../duchain/ducontext.h" #include "../duchain/duchainlock.h" #include "../duchain/duchain.h" #include "codecompletion.h" #include "codecompletionitem.h" #include "codecompletionmodel.h" #include "codecompletionitemgrouper.h" #include using namespace KTextEditor; using namespace KDevelop; CodeCompletionWorker::CodeCompletionWorker(KDevelop::CodeCompletionModel* model) : m_hasFoundDeclarations(false) , m_mutex(new QMutex()) , m_abort(false) , m_fullCompletion(true) , m_model(model) { } CodeCompletionWorker::~CodeCompletionWorker() { delete m_mutex; } void CodeCompletionWorker::setFullCompletion(bool full) { m_fullCompletion = full; } bool CodeCompletionWorker::fullCompletion() const { return m_fullCompletion; } void CodeCompletionWorker::failed() { foundDeclarations( QList >(), KSharedPtr() ); } void KDevelop::CodeCompletionWorker::foundDeclarations(QList< KSharedPtr< KDevelop::CompletionTreeElement > > items, KSharedPtr< KDevelop::CodeCompletionContext > completionContext) { m_hasFoundDeclarations = true; emit foundDeclarationsReal(items, completionContext); } void CodeCompletionWorker::computeCompletions(KDevelop::DUContextPointer context, const KTextEditor::Cursor& position, KTextEditor::View* view) { { QMutexLocker lock(m_mutex); m_abort = false; } ///@todo It's not entirely safe to pass KTextEditor::View* through a queued connection // We access the view/document which is not thread-safe, so we need the foreground lock ForegroundLock foreground; //Compute the text we should complete on KTextEditor::Document* doc = view->document(); if( !doc ) { kDebug() << "No document for completion"; failed(); return; } KTextEditor::Range range; QString text; { QMutexLocker lock(m_mutex); DUChainReadLocker lockDUChain; if(context) { kDebug() << context->localScopeIdentifier().toString(); range = KTextEditor::Range(context->rangeInCurrentRevision().start.textCursor(), position); } else range = KTextEditor::Range(KTextEditor::Cursor(position.line(), 0), position); updateContextRange(range, view, context); text = doc->text(range); } if( position.column() == 0 ) //Seems like when the cursor is a the beginning of a line, kate does not give the \n text += '\n'; if (aborting()) { failed(); return; } m_hasFoundDeclarations = false; KTextEditor::Cursor cursorPosition = view->cursorPosition(); QString followingText; //followingText may contain additional text that stands for the current item. For example in the case "QString|", QString is in addedText. if(position < cursorPosition) followingText = view->document()->text( KTextEditor::Range( position, cursorPosition ) ); foreground.unlock(); computeCompletions(context, position, followingText, range, text); if(!m_hasFoundDeclarations) failed(); } void KDevelop::CodeCompletionWorker::doSpecialProcessing(uint) { } CodeCompletionContext* CodeCompletionWorker::createCompletionContext(KDevelop::DUContextPointer context, const QString& contextText, const QString& followingText, const KDevelop::CursorInRevision& position) const { Q_UNUSED(context); Q_UNUSED(contextText); Q_UNUSED(followingText); Q_UNUSED(position); return 0; } void CodeCompletionWorker::computeCompletions(KDevelop::DUContextPointer context, const KTextEditor::Cursor& position, QString followingText, const KTextEditor::Range& contextRange, const QString& contextText) { Q_UNUSED(contextRange); kDebug() << "added text:" << followingText; CodeCompletionContext::Ptr completionContext( createCompletionContext( context, contextText, followingText, CursorInRevision::castFromSimpleCursor(SimpleCursor(position)) ) ); if (KDevelop::CodeCompletionModel* m = model()) m->setCompletionContext(KDevelop::CodeCompletionContext::Ptr::staticCast(completionContext)); if( completionContext && completionContext->isValid() ) { - DUChainReadLocker lock(DUChain::lock()); - - if (!context) { - failed(); - kDebug() << "Completion context disappeared before completions could be calculated"; - return; + { + DUChainReadLocker lock(DUChain::lock()); + + if (!context) { + failed(); + kDebug() << "Completion context disappeared before completions could be calculated"; + return; + } } QList items = completionContext->completionItems(aborting(), fullCompletion()); if (aborting()) { failed(); return; } QList > tree = computeGroups( items, completionContext ); if(aborting()) { failed(); return; } tree += completionContext->ungroupedElements(); foundDeclarations( tree, KSharedPtr::staticCast(completionContext) ); } else { kDebug() << "setContext: Invalid code-completion context"; } } QList > CodeCompletionWorker::computeGroups(QList items, KSharedPtr completionContext) { Q_UNUSED(completionContext); QList > tree; /** * 1. Group by argument-hint depth * 2. Group by inheritance depth * 3. Group by simplified attributes * */ CodeCompletionItemGrouper > > argumentHintDepthGrouper(tree, 0, items); return tree; } void CodeCompletionWorker::abortCurrentCompletion() { QMutexLocker lock(m_mutex); m_abort = true; } bool& CodeCompletionWorker::aborting() { return m_abort; } KDevelop::CodeCompletionModel* CodeCompletionWorker::model() const { return m_model; } void CodeCompletionWorker::updateContextRange(Range& contextRange, View* view, DUContextPointer context) const { Q_UNUSED(contextRange); Q_UNUSED(view); Q_UNUSED(context); } #include "codecompletionworker.moc"