From 81218043d058101fe1bfb7096df916c3df8c7fe3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 11 Feb 2022 13:08:20 +0100 Subject: [PATCH] ClangCodeModel: Fix mis-highlighting of lambda calls Calls to lambdas without arguments that are declared as const variables were erroneously displayed as output arguments. Change-Id: Ibd914431a34157606694f85d8e00c0dd1db1a618 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 14 +++++++++++- .../clangcodemodel/test/clangdtests.cpp | 8 +++++++ .../test/data/highlighting/highlighting.cpp | 22 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index a03e8960c9a..f2824230977 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2683,10 +2683,22 @@ static void semanticHighlighter(QFutureInterface &future, // where the user sees that it's being written. if (it->kind() == "CXXOperatorCall") { const QList children = it->children().value_or(QList()); + + // Child 1 is the call itself, Child 2 is the named entity on which the call happens + // (a lambda or a class instance), after that follow the actual call arguments. if (children.size() < 2) return false; - if (!children.last().range().contains(range)) + + // The call itself is never modifiable. + if (children.first().range() == range) return false; + + // The callable is never displayed as an output parameter. + // TODO: A good argument can be made to display objects on which a non-const + // operator or function is called as output parameters. + if (children.at(1).range() == range) + return false; + QList firstChildTree{children.first()}; while (!firstChildTree.isEmpty()) { const AstNode n = firstChildTree.takeFirst(); diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 6ed6163a6bd..36eb57ed55b 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1285,6 +1285,14 @@ void ClangdTestHighlighting::test_data() << QList{C_LOCAL} << 0; QTest::newRow("const member as function argument") << 868 << 32 << 868 << 43 << QList{C_FIELD} << 0; + QTest::newRow("lambda call without arguments (const var)") << 887 << 5 << 887 << 12 + << QList{C_LOCAL} << 0; + QTest::newRow("lambda call without arguments (non-const var)") << 889 << 5 << 889 << 12 + << QList{C_LOCAL} << 0; + QTest::newRow("non-const operator()") << 898 << 5 << 898 << 7 + << QList{C_LOCAL} << 0; + QTest::newRow("const operator()") << 903 << 5 << 903 << 7 + << QList{C_LOCAL} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index 7ebc39d433f..44ee7ac8686 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -880,3 +880,25 @@ void constMemberAsFunctionArg() #if 0 #define BAR # endif + +void lambdaCall() +{ + const auto lambda1 = [] {}; + lambda1(); + auto lambda2 = [] {}; + lambda2(); +} + +void callOperators() +{ + struct Callable1 { + void operator()() {}; + }; + Callable1 c1; + c1(); + struct Callable2 { + void operator()() const {}; + }; + Callable2 c2; + c2(); +}