[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdev-clang] /: Correctly build parent context for out-of-line methods
From:       Sergey Kalinichev <kalinichev.so.0 () gmail ! com>
Date:       2015-07-31 19:12:19
Message-ID: E1ZLFj9-00072O-Ik () scm ! kde ! org
[Download RAW message or body]

Git commit 31daed5ca71b5a42197d69066f1038e7417ab79e by Sergey Kalinichev.
Committed on 31/07/2015 at 18:00.
Pushed by skalinichev into branch 'master'.

Correctly build parent context for out-of-line methods

Use a helper context for that.

REVIEW: 124513

M  +21   -4    codecompletion/context.cpp
M  +1    -1    duchain/builder.cpp
M  +1    -1    tests/files/outofline.cpp
M  +1    -2    tests/test_codecompletion.cpp

http://commits.kde.org/kdev-clang/31daed5ca71b5a42197d69066f1038e7417ab79e

diff --git a/codecompletion/context.cpp b/codecompletion/context.cpp
index dafad2e..1d52021 100644
--- a/codecompletion/context.cpp
+++ b/codecompletion/context.cpp
@@ -510,13 +510,29 @@ Declaration* findDeclaration(const QualifiedIdentifier& qid, \
const DUContextPoin  }
 
 /// If any parent of this context is a class, the closest class declaration is \
                returned, nullptr otherwise
-Declaration* classDeclarationForContext(const DUContextPointer& context)
+Declaration* classDeclarationForContext(const DUContextPointer& context, const \
CursorInRevision& position, const QMultiHash<QualifiedIdentifier, Declaration*>& \
declarationsCache)  {
     auto parent = context;
     while (parent) {
         if (parent->type() == DUContext::Class) {
             break;
         }
+
+        if (auto owner = parent->owner()) {
+            // Work-around for out-of-line methods. They have Helper context instead \
of Class context +            if (owner->context() && owner->context()->type() == \
DUContext::Helper) { +                auto qid = owner->qualifiedIdentifier();
+                qid.pop();
+
+                QSet<Declaration*> tmp;
+                auto decl = findDeclaration(qid, context, position, \
declarationsCache, tmp); +
+                if (decl && decl->internalContext() && \
decl->internalContext()->type() == DUContext::Class) { +                    parent = \
decl->internalContext(); +                    break;
+                }
+            }
+        }
         parent = parent->parentContext();
     }
 
@@ -634,7 +650,9 @@ QList<CompletionTreeItemPointer> \
ClangCodeCompletionContext::completionItems(boo  continue;
         }
 
-        if (availability == CXAvailability_NotAccessible && (!isDeclaration || \
!classDeclarationForContext(ctx))) { +        // If ctx is/inside the Class context, \
this represents that context. +        auto currentClassContext = \
classDeclarationForContext(ctx, m_position, declarationsCache); +        if \
(availability == CXAvailability_NotAccessible && (!isDeclaration || \
!currentClassContext)) {  continue;
         }
 
@@ -743,8 +761,7 @@ QList<CompletionTreeItemPointer> \
ClangCodeCompletionContext::completionItems(boo  continue;
                         }
 
-                        auto declarationClassContext = \
                classDeclarationForContext(DUContextPointer(found->context()));
-                        auto currentClassContext = classDeclarationForContext(ctx);
+                        auto declarationClassContext = \
classDeclarationForContext(DUContextPointer(found->context()), m_position, \
declarationsCache);  
                         uint steps = 10;
                         auto inheriters = \
                DUChainUtils::getInheriters(declarationClassContext, steps);
diff --git a/duchain/builder.cpp b/duchain/builder.cpp
index b3ed590..f0b17f6 100644
--- a/duchain/builder.cpp
+++ b/duchain/builder.cpp
@@ -946,7 +946,7 @@ CXChildVisitResult Visitor::buildDeclaration(CXCursor cursor)
     // Code path for class declarations that may be defined "out-of-line", e.g.
     // "SomeNameSpace::SomeClass {};"
     QScopedPointer<CurrentContext> helperContext;
-    if (CursorKindTraits::isClass(CK)) {
+    if (CursorKindTraits::isClass(CK) || CursorKindTraits::isFunction(CK)) {
         const auto lexicalParent = clang_getCursorLexicalParent(cursor);
         const auto semanticParent = clang_getCursorSemanticParent(cursor);
         const bool isOutOfLine = !clang_equalCursors(lexicalParent, semanticParent);
diff --git a/tests/files/outofline.cpp b/tests/files/outofline.cpp
index 30e14f7..ad65a3f 100644
--- a/tests/files/outofline.cpp
+++ b/tests/files/outofline.cpp
@@ -4,7 +4,7 @@ class foo
     /// "isDefinition": false,
     /// "definition": {
     ///     "range": "[(11, 9), (11, 12)]",
-    ///     "qualifiedIdentifier": "foo::bar", "EXPECT_FAIL": \
{"qualifiedIdentifier": "the parent context is not set properly"} +    ///     \
"qualifiedIdentifier": "foo::bar"  /// }
     int bar();
 };
diff --git a/tests/test_codecompletion.cpp b/tests/test_codecompletion.cpp
index 1b569f0..fca922d 100644
--- a/tests/test_codecompletion.cpp
+++ b/tests/test_codecompletion.cpp
@@ -177,7 +177,6 @@ void executeCompletionPriorityTest(const QString& code, const \
CompletionPriority  
     for(const auto& declaration : expectedCompletionItems.completions){
         const auto declarationItem = tester.findItem(declaration.name);
-        QEXPECT_FAIL("protected-access2", \
declaration.failMessage.toUtf8().constData(), Abort);  QVERIFY(declarationItem);
         QVERIFY(declarationItem->declaration());
 
@@ -724,5 +723,5 @@ void TestCodeCompletion::testCompletionPriority_data()
         << "class Base { protected: int m_protected; };"
            "class Derived: public Base {public: void f();};"
            "void Derived::f(){\n }"
-        << CompletionPriorityItems{{1,0}, {{"m_protected", 0, 37, \
QStringLiteral("Out of line methods have wrong parent context attached (Global \
instead of Class)")}}}; +        << CompletionPriorityItems{{1,0}, {{"m_protected", \
0, 37}}};  }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic