From 056db856579b53f195965fd00d522de5ea745835 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Sun, 10 Nov 2013 23:14:17 +0200
Subject: [PATCH] CppEditor: Accept LookupContext in virtual function lookup

Required for correct resolving of first virtual appearance

Change-Id: I2307027f769fb2f4c0942f4aa4e0d2b5327562b5
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
---
 .../cppeditor/cppfollowsymbolundercursor.cpp  |  6 ++-
 .../cppvirtualfunctionassistprovider.cpp      | 47 +++++++++----------
 .../cppvirtualfunctionassistprovider.h        |  4 +-
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
index 19a5a3a5e59..6b566f9f418 100644
--- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
+++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
@@ -128,11 +128,13 @@ bool VirtualFunctionHelper::canLookupVirtualFunctionOverrides(Function *function
     if (IdExpressionAST *idExpressionAST = m_baseExpressionAST->asIdExpression()) {
         NameAST *name = idExpressionAST->name;
         const bool nameIsQualified = name && name->asQualifiedName();
-        result = !nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot);
+        result = !nameIsQualified && FunctionHelper::isVirtualFunction(
+                    function, LookupContext(m_document, m_snapshot));
     } else if (MemberAccessAST *memberAccessAST = m_baseExpressionAST->asMemberAccess()) {
         NameAST *name = memberAccessAST->member_name;
         const bool nameIsQualified = name && name->asQualifiedName();
-        if (!nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot)) {
+        if (!nameIsQualified && FunctionHelper::isVirtualFunction(
+                    function, LookupContext(m_document, m_snapshot))) {
             TranslationUnit *unit = m_expressionDocument->translationUnit();
             QTC_ASSERT(unit, return false);
             m_accessTokenKind = unit->tokenKind(memberAccessAST->access_token);
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
index 1e0f45334fb..48482754662 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
+++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
@@ -210,7 +210,7 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const
 enum VirtualType { Virtual, PureVirtual };
 
 static bool isVirtualFunction_helper(const Function *function,
-                                     const Snapshot &snapshot,
+                                     const LookupContext &context,
                                      VirtualType virtualType)
 {
     if (!function)
@@ -222,24 +222,20 @@ static bool isVirtualFunction_helper(const Function *function,
     if (function->isVirtual())
         return true;
 
-    const QString filePath = QString::fromUtf8(function->fileName(), function->fileNameLength());
-    if (Document::Ptr document = snapshot.document(filePath)) {
-        LookupContext context(document, snapshot);
-        QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
-        if (!results.isEmpty()) {
-            const bool isDestructor = function->name()->isDestructorNameId();
-            foreach (const LookupItem &item, results) {
-                if (Symbol *symbol = item.declaration()) {
-                    if (Function *functionType = symbol->type()->asFunctionType()) {
-                        if (functionType->name()->isDestructorNameId() != isDestructor)
-                            continue;
-                        if (functionType == function) // already tested
-                            continue;
-                        if (functionType->isFinal())
-                            return false;
-                        if (functionType->isVirtual())
-                            return true;
-                    }
+    QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
+    if (!results.isEmpty()) {
+        const bool isDestructor = function->name()->isDestructorNameId();
+        foreach (const LookupItem &item, results) {
+            if (Symbol *symbol = item.declaration()) {
+                if (Function *functionType = symbol->type()->asFunctionType()) {
+                    if (functionType->name()->isDestructorNameId() != isDestructor)
+                        continue;
+                    if (functionType == function) // already tested
+                        continue;
+                    if (functionType->isFinal())
+                        return false;
+                    if (functionType->isVirtual())
+                        return true;
                 }
             }
         }
@@ -248,14 +244,14 @@ static bool isVirtualFunction_helper(const Function *function,
     return false;
 }
 
-bool FunctionHelper::isVirtualFunction(const Function *function, const Snapshot &snapshot)
+bool FunctionHelper::isVirtualFunction(const Function *function, const LookupContext &context)
 {
-    return isVirtualFunction_helper(function, snapshot, Virtual);
+    return isVirtualFunction_helper(function, context, Virtual);
 }
 
-bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snapshot &snapshot)
+bool FunctionHelper::isPureVirtualFunction(const Function *function, const LookupContext &context)
 {
-    return isVirtualFunction_helper(function, snapshot, PureVirtual);
+    return isVirtualFunction_helper(function, context, PureVirtual);
 }
 
 QList<Symbol *> FunctionHelper::overrides(Function *function, Class *functionsClass,
@@ -342,6 +338,7 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions()
     // Iterate through Function symbols
     Snapshot snapshot;
     snapshot.insert(document);
+    const LookupContext context(document, snapshot);
     Control *control = document->translationUnit()->control();
     Symbol **end = control->lastSymbol();
     for (Symbol **it = control->firstSymbol(); it != end; ++it) {
@@ -349,8 +346,8 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions()
         if (const Function *function = symbol->asFunction()) {
             QTC_ASSERT(!virtualityList.isEmpty(), return);
             Virtuality virtuality = virtualityList.takeFirst();
-            if (FunctionHelper::isVirtualFunction(function, snapshot)) {
-                if (FunctionHelper::isPureVirtualFunction(function, snapshot))
+            if (FunctionHelper::isVirtualFunction(function, context)) {
+                if (FunctionHelper::isPureVirtualFunction(function, context))
                     QCOMPARE(virtuality, PureVirtual);
                 else
                     QCOMPARE(virtuality, Virtual);
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h
index 3a99fc37f86..f07e061dfda 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h
+++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h
@@ -74,10 +74,10 @@ class FunctionHelper
 {
 public:
     static bool isVirtualFunction(const CPlusPlus::Function *function,
-                                  const CPlusPlus::Snapshot &snapshot);
+                                  const CPlusPlus::LookupContext &context);
 
     static bool isPureVirtualFunction(const CPlusPlus::Function *function,
-                                      const CPlusPlus::Snapshot &snapshot);
+                                      const CPlusPlus::LookupContext &context);
 
     static QList<CPlusPlus::Symbol *> overrides(CPlusPlus::Function *function,
                                                 CPlusPlus::Class *functionsClass,
-- 
GitLab