From 421f5323f17be2e5c30d085173b6e0890065c5e9 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Mon, 11 Jan 2010 13:47:15 +0100
Subject: [PATCH] Split CppCodeCompletion::startCompletion().

---
 src/plugins/cpptools/cppcodecompletion.cpp | 151 ++++++++++++++-------
 src/plugins/cpptools/cppcodecompletion.h   |  15 +-
 2 files changed, 113 insertions(+), 53 deletions(-)

diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 8726a4300be..883aae29e88 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 &macroName, 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 &macro, doc->definedMacros()) {
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index a83e29ebfc1..f15ddf8f103 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;
 
-- 
GitLab