forked from qt-creator/qt-creator
ClangCodeModel: Use newly implemented clangd support for operators
We now get a semantic token "operator" from clangd; see https://reviews.llvm.org/D136594. As a side effect, this results in the following subtle changes in what exactly gets highlighted, both of which make sense: - The type part of a conversion operator is now highlighted as a type, not an operator. - We no longer add special highlighting for the brackets in operator new[] and operator delete[]. Change-Id: Ic149487496768762728a712c9fbcde5c9516529c Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -266,8 +266,7 @@ void doSemanticHighlighting(
|
||||
};
|
||||
|
||||
const std::function<HighlightingResult(const ExpandedSemanticToken &)> toResult
|
||||
= [&ast, &isOutputParameter, &tokenRange, clangdMajorVersion]
|
||||
(const ExpandedSemanticToken &token) {
|
||||
= [&](const ExpandedSemanticToken &token) {
|
||||
TextStyles styles;
|
||||
if (token.type == "variable") {
|
||||
if (token.modifiers.contains(QLatin1String("functionScope"))) {
|
||||
@@ -338,6 +337,29 @@ void doSemanticHighlighting(
|
||||
// but the latter can be distinguished by the readonly modifier.
|
||||
styles.mainStyle = token.modifiers.contains(QLatin1String("readonly"))
|
||||
? C_PARAMETER : C_TYPE;
|
||||
} else if (token.type == "operator") {
|
||||
const int pos = Utils::Text::positionInText(&doc, token.line, token.column);
|
||||
QTC_ASSERT(pos >= 0 || pos < docContents.size(), return HighlightingResult());
|
||||
const QChar firstChar = docContents.at(pos);
|
||||
if (firstChar.isLetter())
|
||||
styles.mainStyle = C_KEYWORD;
|
||||
else
|
||||
styles.mainStyle = C_PUNCTUATION;
|
||||
styles.mixinStyles.push_back(C_OPERATOR);
|
||||
if (token.modifiers.contains("userDefined"))
|
||||
styles.mixinStyles.push_back(C_OVERLOADED_OPERATOR);
|
||||
else if (token.modifiers.contains("declaration")) {
|
||||
styles.mixinStyles.push_back(C_OVERLOADED_OPERATOR);
|
||||
styles.mixinStyles.push_back(C_DECLARATION);
|
||||
}
|
||||
HighlightingResult result(token.line, token.column, token.length, styles);
|
||||
if (token.length == 1) {
|
||||
if (firstChar == '?')
|
||||
result.kind = CppEditor::SemanticHighlighter::TernaryIf;
|
||||
else if (firstChar == ':')
|
||||
result.kind = CppEditor::SemanticHighlighter::TernaryElse;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (token.modifiers.contains(QLatin1String("declaration")))
|
||||
styles.mixinStyles.push_back(C_DECLARATION);
|
||||
@@ -494,14 +516,6 @@ void ExtraHighlightingResultsCollector::insertResult(const HighlightingResult &r
|
||||
m_results.insert(it, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// This is for conversion operators, whose type part is only reported as a type by clangd.
|
||||
if ((it->textStyles.mainStyle == C_TYPE
|
||||
|| it->textStyles.mainStyle == C_PRIMITIVE_TYPE)
|
||||
&& !result.textStyles.mixinStyles.empty()
|
||||
&& result.textStyles.mixinStyles.at(0) == C_OPERATOR) {
|
||||
it->textStyles.mixinStyles = result.textStyles.mixinStyles;
|
||||
}
|
||||
}
|
||||
|
||||
void ExtraHighlightingResultsCollector::insertResult(const ClangdAstNode &node, TextStyle style)
|
||||
@@ -598,7 +612,7 @@ void ExtraHighlightingResultsCollector::collectFromNode(const ClangdAstNode &nod
|
||||
const QList<ClangdAstNode> children = node.children().value_or(QList<ClangdAstNode>());
|
||||
|
||||
// Match question mark and colon in ternary operators.
|
||||
if (isExpression && node.kind() == "ConditionalOperator") {
|
||||
if (m_clangdVersion < 16 && isExpression && node.kind() == "ConditionalOperator") {
|
||||
if (children.size() != 3)
|
||||
return;
|
||||
|
||||
@@ -761,6 +775,9 @@ void ExtraHighlightingResultsCollector::collectFromNode(const ClangdAstNode &nod
|
||||
if (!isExpression && !isDeclaration)
|
||||
return;
|
||||
|
||||
if (m_clangdVersion >= 16)
|
||||
return;
|
||||
|
||||
// Operators, overloaded ones in particular.
|
||||
static const QString operatorPrefix = "operator";
|
||||
QString detail = node.detail().value_or(QString());
|
||||
@@ -782,15 +799,14 @@ void ExtraHighlightingResultsCollector::collectFromNode(const ClangdAstNode &nod
|
||||
if (!isCallToNew && !isCallToDelete)
|
||||
detail.remove(0, operatorPrefix.length());
|
||||
|
||||
if (node.kind() == "CXXConversion")
|
||||
return;
|
||||
|
||||
HighlightingResult result;
|
||||
result.useTextSyles = true;
|
||||
const bool isConversionOp = node.kind() == "CXXConversion";
|
||||
const bool isOverloaded = !isConversionOp
|
||||
&& (isDeclaration || ((!isCallToNew && !isCallToDelete)
|
||||
|| node.arcanaContains("CXXMethod")));
|
||||
result.textStyles.mainStyle = isConversionOp
|
||||
? C_PRIMITIVE_TYPE
|
||||
: isCallToNew || isCallToDelete || detail.at(0).isSpace()
|
||||
const bool isOverloaded = isDeclaration || ((!isCallToNew && !isCallToDelete)
|
||||
|| node.arcanaContains("CXXMethod"));
|
||||
result.textStyles.mainStyle = isCallToNew || isCallToDelete || detail.at(0).isSpace()
|
||||
? C_KEYWORD : C_PUNCTUATION;
|
||||
result.textStyles.mixinStyles.push_back(C_OPERATOR);
|
||||
if (isOverloaded)
|
||||
|
@@ -719,9 +719,9 @@ void ClangdTestHighlighting::test_data()
|
||||
<< QList<int>{C_FUNCTION} << 0;
|
||||
QTest::newRow("function call") << 64 << 5 << 64 << 13 << QList<int>{C_FUNCTION} << 0;
|
||||
QTest::newRow("type conversion function (struct)") << 68 << 14 << 68 << 17
|
||||
<< QList<int>{C_TYPE, C_OPERATOR, C_DECLARATION} << 0;
|
||||
<< QList<int>{C_TYPE} << 0;
|
||||
QTest::newRow("type conversion function (built-in)") << 69 << 14 << 69 << 17
|
||||
<< QList<int>{C_PRIMITIVE_TYPE, C_OPERATOR, C_DECLARATION} << 0;
|
||||
<< QList<int>{C_PRIMITIVE_TYPE} << 0;
|
||||
QTest::newRow("type reference") << 74 << 5 << 74 << 8 << QList<int>{C_TYPE} << 0;
|
||||
QTest::newRow("local variable declaration") << 79 << 9 << 79 << 12
|
||||
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
||||
@@ -836,34 +836,16 @@ void ClangdTestHighlighting::test_data()
|
||||
<< QList<int>{C_LOCAL} << 0;
|
||||
QTest::newRow("operator new[] member declaration (keyword)") << 623 << 20 << 623 << 23
|
||||
<< QList<int>{C_KEYWORD, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator new[] member declaration (opening bracket)") << 623 << 23 << 623 << 24
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator new[] member declaration (closing bracket)") << 623 << 24 << 623 << 25
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator new[] member call (keyword") << 637 << 19 << 637 << 22
|
||||
<< QList<int>{C_KEYWORD, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator new[] member call (type argument)") << 637 << 23 << 637 << 28
|
||||
<< QList<int>{C_TYPE} << 0;
|
||||
QTest::newRow("operator new[] member call (opening bracket)") << 637 << 28 << 637 << 29
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator new[] member call (size argument)") << 637 << 29 << 637 << 31
|
||||
<< QList<int>{C_NUMBER} << 0;
|
||||
QTest::newRow("operator new[] member call (closing bracket)") << 637 << 31 << 637 << 32
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator delete[] member declaration (keyword)") << 624 << 19 << 624 << 25
|
||||
<< QList<int>{C_KEYWORD, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator delete[] member declaration (opening bracket)")
|
||||
<< 624 << 25 << 624 << 26
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator delete[] member declaration (closing bracket)")
|
||||
<< 624 << 26 << 624 << 27
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR, C_DECLARATION} << 0;
|
||||
QTest::newRow("operator delete[] member call (keyword") << 638 << 5 << 638 << 11
|
||||
<< QList<int>{C_KEYWORD, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator delete[] member call (opening bracket)") << 638 << 12 << 638 << 13
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator delete[] member call (closing bracket)") << 638 << 13 << 638 << 14
|
||||
<< QList<int>{C_PUNCTUATION, C_OPERATOR, C_OVERLOADED_OPERATOR} << 0;
|
||||
QTest::newRow("operator new built-in call") << 634 << 14 << 634 << 17
|
||||
<< QList<int>{C_KEYWORD, C_OPERATOR} << 0;
|
||||
QTest::newRow("operator() member declaration (opening paren") << 654 << 20 << 654 << 21
|
||||
|
Reference in New Issue
Block a user