[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