From f9a05d9cedf5596e72f65f635fc0fd42dd01c358 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Wed, 12 May 2010 14:52:24 +0200
Subject: [PATCH] Reimplemented resolve base expression.

---
 src/libs/cplusplus/ResolveExpression.cpp   | 32 +++++++++++
 src/libs/cplusplus/ResolveExpression.h     | 20 ++++---
 src/plugins/cpptools/cppcodecompletion.cpp | 66 ++++++++++------------
 3 files changed, 74 insertions(+), 44 deletions(-)

diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index ed0253b6a7b..a9b86e978ee 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -49,6 +49,8 @@ using namespace CPlusPlus;
 
 namespace {
 
+const bool debug = ! qgetenv("CPLUSPLUS_DEBUG").isEmpty();
+
 template <typename _Tp>
 static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
 {
@@ -563,6 +565,36 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
     return false;
 }
 
+ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
+                                                    int accessOp,
+                                                    bool *replacedDotOperator) const
+{
+    foreach (const LookupItem &r, baseResults) {
+        FullySpecifiedType ty = r.type().simplified();
+
+        if (accessOp == T_DOT) {
+            if (PointerType *ptrTy = ty->asPointerType()) {
+                ty = ptrTy->elementType();
+
+                if (replacedDotOperator)
+                    *replacedDotOperator = true;
+            }
+        }
+
+        if (Class *klass = ty->asClassType()) {
+            if (ClassOrNamespace *binding = _context.classOrNamespace(klass))
+                return binding;
+
+        } else if (NamedType *namedTy = ty->asNamedType()) {
+            if (ClassOrNamespace *binding = _context.classOrNamespace(namedTy->name(), r.scope()))
+                return binding;
+        }
+    }
+
+    return 0;
+}
+
+
 QList<LookupItem>
 ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, int accessOp,
                                          bool *replacedDotOperator) const
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index 95538ceba6f..52bbd6eb994 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -47,14 +47,18 @@ public:
     QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope);
     QList<LookupItem> resolve(ExpressionAST *ast, Scope *scope);
 
-    QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults,
-                                              unsigned accessOp,
-                                              const Name *memberName,
-                                              bool *replacedDotOperator = 0) const;
-
-    QList<LookupItem> resolveBaseExpression(const QList<LookupItem> &baseResults,
-                                            int accessOp,
-                                            bool *replacedDotOperator = 0) const;
+    ClassOrNamespace *baseExpression(const QList<LookupItem> &baseResults,
+                                     int accessOp,
+                                     bool *replacedDotOperator = 0) const;
+
+    Q_DECL_DEPRECATED QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults,
+                                                                unsigned accessOp,
+                                                                const Name *memberName,
+                                                                bool *replacedDotOperator = 0) const;
+
+    Q_DECL_DEPRECATED QList<LookupItem> resolveBaseExpression(const QList<LookupItem> &baseResults,
+                                                              int accessOp,
+                                                              bool *replacedDotOperator = 0) const;
 
 protected:
     QList<LookupItem> resolve(ExpressionAST *ast);
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index bd2c4f87a1e..84492fec2b5 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -79,6 +79,11 @@
 #include <QtGui/QToolButton>
 #include <QtGui/QVBoxLayout>
 
+
+namespace {
+    const bool debug = ! qgetenv("CPLUSPLUS_DEBUG").isEmpty();
+}
+
 using namespace CPlusPlus;
 
 namespace CppTools {
@@ -757,7 +762,14 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
     Scope *scope = thisDocument->scopeAt(line, column);
     Q_ASSERT(scope != 0);
 
+    if (debug)
+        qDebug() << "scope:" << scope->owner()->fileName() << scope->owner()->line() << scope->owner()->column();
+
     QList<LookupItem> results = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
+
+    if (debug)
+        qDebug() << "got:" << results.size() << "results";
+
     LookupContext context = typeOfExpression.lookupContext();
 
     if (results.isEmpty()) {
@@ -1053,54 +1065,36 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
 bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
                                        const LookupContext &context)
 {
+    if (debug)
+        qDebug() << Q_FUNC_INFO << __LINE__;
+
     if (baseResults.isEmpty())
         return false;
 
     ResolveExpression resolveExpression(context);
 
     bool replacedDotOperator = false;
-    const QList<LookupItem> classObjectResults =
-            resolveExpression.resolveBaseExpression(baseResults,
-                                                    m_completionOperator,
-                                                    &replacedDotOperator);
-
-    ClassOrNamespace *classOrNamespace = 0;
-
-    foreach (const LookupItem &r, classObjectResults) {
-        FullySpecifiedType ty = r.type().simplified();
 
-        if (Class *klass = ty->asClassType()) {
-            if (ClassOrNamespace *b = context.classOrNamespace(klass)) {
-                classOrNamespace = b;
-                break;
-            }
+    if (ClassOrNamespace *binding = resolveExpression.baseExpression(baseResults,
+                                                                     m_completionOperator,
+                                                                     &replacedDotOperator)) {
+        if (debug)
+            qDebug() << "cool we got a binding for the base expression";
+
+        if (replacedDotOperator && binding) {
+            // Replace . with ->
+            int length = m_editor->position() - m_startPosition + 1;
+            m_editor->setCurPos(m_startPosition - 1);
+            m_editor->replace(length, QLatin1String("->"));
+            ++m_startPosition;
         }
 
-        else if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.scope())) {
-                classOrNamespace = b;
-                break;
-            }  else {
-                Overview oo;
-                qDebug() << "*** no class for" << oo(namedTy->name());
-            }
-        }
-    }
+        if (binding)
+            completeClass(binding, context, /*static lookup = */ false);
 
-    if (replacedDotOperator && classOrNamespace) {
-        // Replace . with ->
-        int length = m_editor->position() - m_startPosition + 1;
-        m_editor->setCurPos(m_startPosition - 1);
-        m_editor->replace(length, QLatin1String("->"));
-        ++m_startPosition;
+        return ! m_completions.isEmpty();
     }
 
-    if (classOrNamespace)
-        completeClass(classOrNamespace, context, /*static lookup = */ false);
-
-    if (! m_completions.isEmpty())
-        return true;
-
     return false;
 }
 
-- 
GitLab