diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index 8726a4300be2330a6731288ad4ad590c67b23034..883aae29e88ca263310a29a8350655f38746c8c8 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -693,9 +693,9 @@ bool CppCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor) bool CppCodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor) { const int pos = editor->position(); - if (startOfOperator(editor, pos, /*token =*/ 0, - /*want function call=*/ true) != pos) + if (startOfOperator(editor, pos, /*token =*/ 0, /*want function call=*/ true) != pos) { return true; + } return false; } @@ -707,6 +707,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) return -1; m_editor = editor; + const int startOfName = findStartOfName(); m_startPosition = startOfName; m_completionOperator = T_EOF_SYMBOL; @@ -790,64 +791,52 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) } //qDebug() << "***** expression:" << expression; + return startCompletionInternal(edit, fileName, line, column, expression, endOfExpression); +} +int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit, + const QString fileName, + unsigned line, unsigned column, + const QString &expr, + int endOfExpression) +{ + QString expression = expr.trimmed(); const Snapshot snapshot = m_manager->snapshot(); - if (Document::Ptr thisDocument = snapshot.document(fileName)) { - Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column); - typeOfExpression.setSnapshot(m_manager->snapshot()); - - QList<LookupItem> resolvedTypes = typeOfExpression(expression, thisDocument, lastVisibleSymbol, - TypeOfExpression::Preprocess); - LookupContext context = typeOfExpression.lookupContext(); - - if (!typeOfExpression.expressionAST() && (! m_completionOperator || - m_completionOperator == T_COLON_COLON)) { - if (!m_completionOperator) { - addKeywords(); - addMacros(context); - } + Document::Ptr thisDocument = snapshot.document(fileName); + if (! thisDocument) + return -1; - const QList<Scope *> scopes = context.expand(context.visibleScopes()); - foreach (Scope *scope, scopes) { - for (unsigned i = 0; i < scope->symbolCount(); ++i) { - addCompletionItem(scope->symbolAt(i)); - } - } - return m_startPosition; - } + Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column); - // qDebug() << "found" << resolvedTypes.count() << "symbols for expression:" << expression; + if (expression.isEmpty()) { + if (m_completionOperator == T_EOF_SYMBOL || m_completionOperator == T_COLON_COLON) + return globalCompletion(lastVisibleSymbol, thisDocument, snapshot); - if (resolvedTypes.isEmpty() && (m_completionOperator == T_SIGNAL || - m_completionOperator == T_SLOT)) { + else if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { // Apply signal/slot completion on 'this' expression = QLatin1String("this"); - resolvedTypes = typeOfExpression(expression, thisDocument, lastVisibleSymbol); - context = typeOfExpression.lookupContext(); } + } - if (! resolvedTypes.isEmpty()) { - if (m_completionOperator == T_LPAREN && - completeConstructorOrFunction(resolvedTypes, context, endOfExpression, false)) { - return m_startPosition; - } else if ((m_completionOperator == T_DOT || m_completionOperator == T_ARROW) && - completeMember(resolvedTypes, context)) { - return m_startPosition; + typeOfExpression.setSnapshot(m_manager->snapshot()); + QList<LookupItem> results = typeOfExpression(expression, thisDocument, lastVisibleSymbol); + LookupContext context = typeOfExpression.lookupContext(); - } else if (m_completionOperator == T_COLON_COLON && completeScope(resolvedTypes, context)) { - return m_startPosition; + if (results.isEmpty()) { + if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { + if (! (expression.isEmpty() || expression == QLatin1String("this"))) { + expression = QLatin1String("this"); + results = typeOfExpression(expression, thisDocument, lastVisibleSymbol); + } - } else if (m_completionOperator == T_SIGNAL && completeSignal(resolvedTypes, context)) { - return m_startPosition; + if (results.isEmpty()) + return -1; - } else if (m_completionOperator == T_SLOT && completeSlot(resolvedTypes, context)) { - return m_startPosition; - } - } + context = typeOfExpression.lookupContext(); - if (m_completionOperator == T_LPAREN) { + } else if (m_completionOperator == T_LPAREN) { // Find the expression that precedes the current name int index = endOfExpression; while (m_editor->characterAt(index - 1).isSpace()) @@ -857,6 +846,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) QTextCursor tc(edit->document()); tc.setPosition(index); + ExpressionUnderCursor expressionUnderCursor; const QString baseExpression = expressionUnderCursor(tc); // Resolve the type of this expression @@ -870,16 +860,76 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) if (result.type()->isClassType()) { if (completeConstructorOrFunction(results, context, endOfExpression, true)) return m_startPosition; + break; } } + return -1; + + } else { + // nothing to do. + return -1; + } } + switch (m_completionOperator) { + case T_LPAREN: + if (completeConstructorOrFunction(results, context, endOfExpression, false)) + return m_startPosition; + break; + + case T_DOT: + case T_ARROW: + if (completeMember(results, context)) + return m_startPosition; + break; + + case T_COLON_COLON: + if (completeScope(results, context)) + return m_startPosition; + break; + + case T_SIGNAL: + if (completeSignal(results, context)) + return m_startPosition; + break; + + case T_SLOT: + if (completeSlot(results, context)) + return m_startPosition; + break; + + default: + break; + } // end of switch + // nothing to do. return -1; } +int CppCodeCompletion::globalCompletion(Symbol *lastVisibleSymbol, + Document::Ptr thisDocument, + const Snapshot &snapshot) +{ + if (m_completionOperator == T_EOF_SYMBOL) { + addKeywords(); + addMacros(thisDocument->fileName(), snapshot); + } + + Document::Ptr exprDoc = Document::create(QLatin1String("<expression>")); + const LookupContext context(lastVisibleSymbol, exprDoc, thisDocument, snapshot); + const QList<Scope *> scopes = context.expand(context.visibleScopes()); + + foreach (Scope *scope, scopes) { + for (unsigned i = 0; i < scope->symbolCount(); ++i) { + addCompletionItem(scope->symbolAt(i)); + } + } + + return m_startPosition; +} + bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &results, const LookupContext &context, int endOfExpression, bool toolTipOnly) @@ -1156,13 +1206,12 @@ void CppCodeCompletion::addKeywords() } } -void CppCodeCompletion::addMacros(const LookupContext &context) +void CppCodeCompletion::addMacros(const QString &fileName, const Snapshot &snapshot) { QSet<QString> processed; QSet<QString> definedMacros; - addMacros_helper(context, context.thisDocument()->fileName(), - &processed, &definedMacros); + addMacros_helper(snapshot, fileName, &processed, &definedMacros); foreach (const QString ¯oName, definedMacros) { TextEditor::CompletionItem item(this); @@ -1172,12 +1221,12 @@ void CppCodeCompletion::addMacros(const LookupContext &context) } } -void CppCodeCompletion::addMacros_helper(const LookupContext &context, +void CppCodeCompletion::addMacros_helper(const Snapshot &snapshot, const QString &fileName, QSet<QString> *processed, QSet<QString> *definedMacros) { - Document::Ptr doc = context.document(fileName); + Document::Ptr doc = snapshot.document(fileName); if (! doc || processed->contains(doc->fileName())) return; @@ -1185,7 +1234,7 @@ void CppCodeCompletion::addMacros_helper(const LookupContext &context, processed->insert(doc->fileName()); foreach (const Document::Include &i, doc->includes()) { - addMacros_helper(context, i.fileName(), processed, definedMacros); + addMacros_helper(snapshot, i.fileName(), processed, definedMacros); } foreach (const Macro ¯o, doc->definedMacros()) { diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h index a83e29ebfc1bbde839535ffdc44626ec98045a16..f15ddf8f103bea2b1acb160bc174ed6f4188ae38 100644 --- a/src/plugins/cpptools/cppcodecompletion.h +++ b/src/plugins/cpptools/cppcodecompletion.h @@ -47,6 +47,7 @@ QT_END_NAMESPACE namespace TextEditor { class ITextEditor; +class BaseTextEditor; } namespace CppTools { @@ -93,8 +94,8 @@ public: private: void addKeywords(); - void addMacros(const CPlusPlus::LookupContext &context); - void addMacros_helper(const CPlusPlus::LookupContext &context, + void addMacros(const QString &fileName, const CPlusPlus::Snapshot &snapshot); + void addMacros_helper(const CPlusPlus::Snapshot &snapshot, const QString &fileName, QSet<QString> *processed, QSet<QString> *definedMacros); @@ -102,6 +103,10 @@ private: bool completeInclude(const QTextCursor &cursor); + int globalCompletion(CPlusPlus::Symbol *lastVisibleSymbol, + CPlusPlus::Document::Ptr thisDocument, + const CPlusPlus::Snapshot &snapshot); + bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &, const CPlusPlus::LookupContext &, int endOfExpression, bool toolTipOnly); @@ -135,6 +140,12 @@ private: int findStartOfName(int pos = -1) const; + int startCompletionInternal(TextEditor::BaseTextEditor *edit, + const QString fileName, + unsigned line, unsigned column, + const QString &expression, + int endOfExpression); + private: bool objcKeywordsWanted() const;