From 82d0650b116e0607e24021b0930e57759c53b449 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Thu, 10 Aug 2017 09:57:18 +0200 Subject: [PATCH] Clang: fix findStartOfName handling ... of templates and qualified names Change-Id: Ic8c2dec35cb74484f474c0c608857e7cf48c7468 Reviewed-by: Nikolai Kosjar --- ...langactivationsequencecontextprocessor.cpp | 23 +++++++++++++++++++ ...ctivationsequencecontextprocessor-test.cpp | 8 +++++++ .../clangcompletioncontextanalyzer-test.cpp | 7 ++++++ 3 files changed, 38 insertions(+) diff --git a/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp index 80b42c11b43..62573c70fde 100644 --- a/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp +++ b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp @@ -247,10 +247,33 @@ int ActivationSequenceContextProcessor::findStartOfName( { int position = startPosition; QChar character; + if (position > 2 && assistInterface->characterAt(position - 1) == '>' + && assistInterface->characterAt(position - 2) != '-') { + uint unbalancedLessGreater = 1; + --position; + while (unbalancedLessGreater > 0 && position > 2) { + character = assistInterface->characterAt(--position); + // Do not count -> usage inside temlate argument list + if (character == '<') + --unbalancedLessGreater; + else if (character == '>' && assistInterface->characterAt(position-1) != '-') + ++unbalancedLessGreater; + } + position = skipPrecedingWhitespace(assistInterface, position) - 1; + } + do { character = assistInterface->characterAt(--position); } while (isValidIdentifierChar(character)); + int prevPosition = skipPrecedingWhitespace(assistInterface, position); + if (assistInterface->characterAt(prevPosition) == ':' + && assistInterface->characterAt(prevPosition - 1) == ':') { + // Handle :: case - go recursive + prevPosition = skipPrecedingWhitespace(assistInterface, prevPosition - 2); + return findStartOfName(assistInterface, prevPosition + 1); + } + return position + 1; } diff --git a/tests/unit/unittest/activationsequencecontextprocessor-test.cpp b/tests/unit/unittest/activationsequencecontextprocessor-test.cpp index aca0ae4e976..5ccc7d500a6 100644 --- a/tests/unit/unittest/activationsequencecontextprocessor-test.cpp +++ b/tests/unit/unittest/activationsequencecontextprocessor-test.cpp @@ -144,6 +144,14 @@ TEST(ActivationSequenceContextProcessor, TemplateFunctionLeftParen) ASSERT_THAT(processor.completionKind(), CPlusPlus::T_LPAREN); } +TEST(ActivationSequenceContextProcessor, TemplateFunctionSecondParameter) +{ + ClangCompletionAssistInterface interface("foo(", 7); + int startOfname = ContextProcessor::findStartOfName(&interface, 6); + + ASSERT_THAT(startOfname, 0); +} + TEST(ActivationSequenceContextProcessor, ExpressionLeftParen) { ClangCompletionAssistInterface interface("x * (", 5); diff --git a/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp b/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp index 5ca579a1d40..ae0c412ad74 100644 --- a/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp +++ b/tests/unit/unittest/clangcompletioncontextanalyzer-test.cpp @@ -490,4 +490,11 @@ TEST_F(ClangCompletionContextAnalyzer, AsteriskLeftParen) ASSERT_THAT(analyzer, IsPassThroughToClang()); } +TEST_F(ClangCompletionContextAnalyzer, TemplatedFunctionSecondArgument) +{ + auto analyzer = runAnalyzer("f < decltype(bar -> member) > (1, @"); + + ASSERT_THAT(analyzer, HasResult(CCA::PassThroughToLibClangAfterLeftParen, -3, -3, positionInText)); +} + }