Clang: Fix highlighting of primitive types

libClang categorizes these as keywords, so we need to check
if a keyword is actually a primitive type, and use that.

Task-number: QTCREATORBUG-17867
Change-Id: I354bb0422505ed7732a0799d9c86d3acfdeb0785
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Eike Ziller
2017-05-17 16:40:21 +02:00
parent f51fbd68e1
commit db11c01df8
5 changed files with 34 additions and 6 deletions

View File

@@ -74,6 +74,7 @@ enum class HighlightingType : quint8
Function, Function,
VirtualFunction, VirtualFunction,
Type, Type,
PrimitiveType,
LocalVariable, LocalVariable,
Field, Field,
GlobalVariable, GlobalVariable,

View File

@@ -44,6 +44,8 @@ TextEditor::TextStyle toTextStyle(ClangBackEnd::HighlightingType type)
return TextEditor::C_VIRTUAL_METHOD; return TextEditor::C_VIRTUAL_METHOD;
case HighlightingType::Type: case HighlightingType::Type:
return TextEditor::C_TYPE; return TextEditor::C_TYPE;
case HighlightingType::PrimitiveType:
return TextEditor::C_PRIMITIVE_TYPE;
case HighlightingType::LocalVariable: case HighlightingType::LocalVariable:
return TextEditor::C_LOCAL; return TextEditor::C_LOCAL;
case HighlightingType::Field: case HighlightingType::Field:

View File

@@ -54,7 +54,7 @@ HighlightingMark::HighlightingMark(const CXCursor &cxCursor,
column = start.column(); column = start.column();
offset = start.offset(); offset = start.offset();
length = end.offset() - start.offset(); length = end.offset() - start.offset();
collectKinds(cxToken, originalCursor); collectKinds(cxTranslationUnit, cxToken, originalCursor);
} }
HighlightingMark::HighlightingMark(uint line, uint column, uint length, HighlightingTypes types) HighlightingMark::HighlightingMark(uint line, uint column, uint length, HighlightingTypes types)
@@ -369,14 +369,39 @@ HighlightingType HighlightingMark::punctuationKind(const Cursor &cursor)
} }
} }
void HighlightingMark::collectKinds(CXToken *cxToken, const Cursor &cursor) static HighlightingType highlightingTypeForKeyword(CXTranslationUnit cxTranslationUnit,
CXToken *cxToken)
{
const ClangString spelling = clang_getTokenSpelling(cxTranslationUnit, *cxToken);
const char *c = spelling.cString();
if (std::strcmp(c, "bool") == 0
|| std::strcmp(c, "char") == 0
|| std::strcmp(c, "char16_t") == 0
|| std::strcmp(c, "char32_t") == 0
|| std::strcmp(c, "double") == 0
|| std::strcmp(c, "float") == 0
|| std::strcmp(c, "int") == 0
|| std::strcmp(c, "long") == 0
|| std::strcmp(c, "short") == 0
|| std::strcmp(c, "signed") == 0
|| std::strcmp(c, "unsigned") == 0
|| std::strcmp(c, "void") == 0
|| std::strcmp(c, "wchar_t") == 0) {
return HighlightingType::PrimitiveType;
}
return HighlightingType::Keyword;
}
void HighlightingMark::collectKinds(CXTranslationUnit cxTranslationUnit,
CXToken *cxToken, const Cursor &cursor)
{ {
auto cxTokenKind = clang_getTokenKind(*cxToken); auto cxTokenKind = clang_getTokenKind(*cxToken);
types = HighlightingTypes(); types = HighlightingTypes();
switch (cxTokenKind) { switch (cxTokenKind) {
case CXToken_Keyword: types.mainHighlightingType = HighlightingType::Keyword; break; case CXToken_Keyword: types.mainHighlightingType = highlightingTypeForKeyword(cxTranslationUnit, cxToken); break;
case CXToken_Punctuation: types.mainHighlightingType = punctuationKind(cursor); break; case CXToken_Punctuation: types.mainHighlightingType = punctuationKind(cursor); break;
case CXToken_Identifier: identifierKind(cursor, Recursion::FirstPass); break; case CXToken_Identifier: identifierKind(cursor, Recursion::FirstPass); break;
case CXToken_Comment: types.mainHighlightingType = HighlightingType::Comment; break; case CXToken_Comment: types.mainHighlightingType = HighlightingType::Comment; break;

View File

@@ -69,7 +69,7 @@ private:
void functionKind(const Cursor &cursor, Recursion recursion); void functionKind(const Cursor &cursor, Recursion recursion);
void memberReferenceKind(const Cursor &cursor); void memberReferenceKind(const Cursor &cursor);
HighlightingType punctuationKind(const Cursor &cursor); HighlightingType punctuationKind(const Cursor &cursor);
void collectKinds(CXToken *cxToken, const Cursor &cursor); void collectKinds(CXTranslationUnit cxTranslationUnit, CXToken *cxToken, const Cursor &cursor);
bool isRealDynamicCall(const Cursor &cursor) const; bool isRealDynamicCall(const Cursor &cursor) const;
void addExtraTypeIfFirstPass(HighlightingType type, Recursion recursion); void addExtraTypeIfFirstPass(HighlightingType type, Recursion recursion);
bool isOutputArgument() const; bool isOutputArgument() const;

View File

@@ -281,7 +281,7 @@ TEST_F(HighlightingMarks, InbuiltTypeConversionFunction)
{ {
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(69, 20)); const auto infos = translationUnit.highlightingMarksInRange(sourceRange(69, 20));
ASSERT_THAT(infos[1], IsHighlightingMark(69u, 14u, 3u, HighlightingType::Keyword)); ASSERT_THAT(infos[1], IsHighlightingMark(69u, 14u, 3u, HighlightingType::PrimitiveType));
} }
TEST_F(HighlightingMarks, TypeReference) TEST_F(HighlightingMarks, TypeReference)
@@ -757,7 +757,7 @@ TEST_F(HighlightingMarks, ArgumentInMacroExpansionIsKeyword)
{ {
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(302, 36)); const auto infos = translationUnit.highlightingMarksInRange(sourceRange(302, 36));
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Keyword)); ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PrimitiveType));
} }
TEST_F(HighlightingMarks, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable) TEST_F(HighlightingMarks, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable)