diff --git a/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp index 80b42c11b4348c56dd0c3103c69c676c7209ff91..62573c70fdee657f8cc12ec4eccca61d6fd83418 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 aca0ae4e976c777327750ae3e979261b3bb0605e..5ccc7d500a668c9d8c0d265ac6f62f465e8751d0 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<X>(", 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 5ca579a1d40bc71d291dd43e016ed42b408e0791..ae0c412ad746c4acd1f5db7bfce809e67eddf8cf 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)); +} + }