Clang: introduce more data in TokenInfo

Data added:
- return type spelling for functions
- parent spelling
- access specifier for class fields and methods
- storage class

New highlighting types are added, therefore
types are now categorized by class, struct, etc.

Change-Id: I1739b94a6f777045fde655060d8b9a12b6e0889b
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2018-01-12 09:44:05 +01:00
parent 730a8186af
commit bdd5066665
17 changed files with 449 additions and 72 deletions

View File

@@ -88,7 +88,33 @@ enum class HighlightingType : quint8
Label, Label,
Declaration, Declaration,
FunctionDefinition, FunctionDefinition,
OutputArgument OutputArgument,
Namespace,
Class,
Struct,
Enum,
Union,
TypeAlias,
Typedef
};
enum class StorageClass : quint8
{
Invalid,
None,
Extern,
Static,
PrivateExtern,
Auto,
Register
};
enum class AccessSpecifier : quint8
{
Invalid,
Public,
Protected,
Private
}; };
enum class CompletionCorrection : quint32 enum class CompletionCorrection : quint32

View File

@@ -52,6 +52,13 @@ static const char *highlightingTypeToCStringLiteral(HighlightingType type)
RETURN_TEXT_FOR_CASE(OutputArgument); RETURN_TEXT_FOR_CASE(OutputArgument);
RETURN_TEXT_FOR_CASE(PreprocessorDefinition); RETURN_TEXT_FOR_CASE(PreprocessorDefinition);
RETURN_TEXT_FOR_CASE(PreprocessorExpansion); RETURN_TEXT_FOR_CASE(PreprocessorExpansion);
RETURN_TEXT_FOR_CASE(Namespace);
RETURN_TEXT_FOR_CASE(Class);
RETURN_TEXT_FOR_CASE(Struct);
RETURN_TEXT_FOR_CASE(Enum);
RETURN_TEXT_FOR_CASE(Union);
RETURN_TEXT_FOR_CASE(TypeAlias);
RETURN_TEXT_FOR_CASE(Typedef);
default: return "UnhandledHighlightingType"; default: return "UnhandledHighlightingType";
} }
} }
@@ -66,6 +73,10 @@ QDebug operator<<(QDebug debug, const TokenInfoContainer &container)
<< highlightingTypeToCStringLiteral(container.types().mainHighlightingType) << ", " << highlightingTypeToCStringLiteral(container.types().mainHighlightingType) << ", "
<< container.token() << ", " << container.token() << ", "
<< container.typeSpelling() << ", " << container.typeSpelling() << ", "
<< container.returnTypeSpelling() << ", "
<< container.semanticParentTypeSpelling() << ", "
<< static_cast<uint>(container.accessSpecifier()) << ", "
<< static_cast<uint>(container.storageClass()) << ", "
<< container.isIdentifier() << ", " << container.isIdentifier() << ", "
<< container.isIncludeDirectivePath() << ", " << container.isIncludeDirectivePath() << ", "
<< container.isDeclaration() << ", " << container.isDeclaration() << ", "

View File

@@ -62,7 +62,10 @@ class TokenInfoContainer
public: public:
TokenInfoContainer() = default; TokenInfoContainer() = default;
TokenInfoContainer(uint line, uint column, uint length, HighlightingTypes types, TokenInfoContainer(uint line, uint column, uint length, HighlightingTypes types,
const Utf8String &token, const Utf8String &typeSpelling, const Utf8String &token,const Utf8String &typeSpelling,
const Utf8String &returnTypeSpelling,
const Utf8String &semanticParentTypeSpelling,
AccessSpecifier accessSpecifier, StorageClass storageClass,
bool isIdentifier = false, bool isIncludeDirectivePath = false, bool isIdentifier = false, bool isIncludeDirectivePath = false,
bool isDeclaration = false, bool isDefinition = false) bool isDeclaration = false, bool isDefinition = false)
: line_(line), : line_(line),
@@ -70,7 +73,11 @@ public:
length_(length), length_(length),
types_(types), types_(types),
token_(token), token_(token),
typeSpelling_(typeSpelling) typeSpelling_(typeSpelling),
returnTypeSpelling_(returnTypeSpelling),
semanticParentTypeSpelling_(semanticParentTypeSpelling),
accessSpecifier_(accessSpecifier),
storageClass_(storageClass)
{ {
bitFields_.set(BitField::Identifier, isIdentifier); bitFields_.set(BitField::Identifier, isIdentifier);
bitFields_.set(BitField::IncludeDirectivePath, isIncludeDirectivePath); bitFields_.set(BitField::IncludeDirectivePath, isIncludeDirectivePath);
@@ -141,6 +148,25 @@ public:
return typeSpelling_; return typeSpelling_;
} }
const Utf8String returnTypeSpelling() const
{
return returnTypeSpelling_;
}
const Utf8String semanticParentTypeSpelling() const
{
return semanticParentTypeSpelling_;
}
AccessSpecifier accessSpecifier() const
{
return accessSpecifier_;
}
StorageClass storageClass() const
{
return storageClass_;
}
friend QDataStream &operator<<(QDataStream &out, const TokenInfoContainer &container) friend QDataStream &operator<<(QDataStream &out, const TokenInfoContainer &container)
{ {
@@ -150,6 +176,10 @@ public:
out << container.types_; out << container.types_;
out << container.token_; out << container.token_;
out << container.typeSpelling_; out << container.typeSpelling_;
out << container.returnTypeSpelling_;
out << container.semanticParentTypeSpelling_;
out << static_cast<uint>(container.accessSpecifier_);
out << static_cast<uint>(container.storageClass_);
out << container.bitFields_; out << container.bitFields_;
return out; return out;
@@ -163,6 +193,16 @@ public:
in >> container.types_; in >> container.types_;
in >> container.token_ ; in >> container.token_ ;
in >> container.typeSpelling_; in >> container.typeSpelling_;
in >> container.returnTypeSpelling_;
in >> container.semanticParentTypeSpelling_;
uint accessSpecifier;
uint storageClass;
in >> accessSpecifier;
in >> storageClass;
container.accessSpecifier_ = static_cast<AccessSpecifier>(accessSpecifier);
container.storageClass_ = static_cast<StorageClass>(storageClass);
in >> container.bitFields_; in >> container.bitFields_;
return in; return in;
@@ -174,6 +214,12 @@ public:
&& first.column_ == second.column_ && first.column_ == second.column_
&& first.length_ == second.length_ && first.length_ == second.length_
&& first.types_ == second.types_ && first.types_ == second.types_
&& first.token_ == second.token_
&& first.typeSpelling_ == second.typeSpelling_
&& first.returnTypeSpelling_ == second.returnTypeSpelling_
&& first.semanticParentTypeSpelling_ == second.semanticParentTypeSpelling_
&& first.accessSpecifier_ == second.accessSpecifier_
&& first.storageClass_ == second.storageClass_
&& first.bitFields_ == second.bitFields_; && first.bitFields_ == second.bitFields_;
} }
@@ -184,6 +230,10 @@ private:
HighlightingTypes types_; HighlightingTypes types_;
Utf8String token_; Utf8String token_;
Utf8String typeSpelling_; Utf8String typeSpelling_;
Utf8String returnTypeSpelling_;
Utf8String semanticParentTypeSpelling_;
AccessSpecifier accessSpecifier_;
StorageClass storageClass_;
ByteSizeBitset bitFields_; ByteSizeBitset bitFields_;
}; };

View File

@@ -78,9 +78,30 @@ TextEditor::TextStyle toTextStyle(ClangBackEnd::HighlightingType type)
case HighlightingType::Invalid: case HighlightingType::Invalid:
QTC_CHECK(false); // never called QTC_CHECK(false); // never called
return TextEditor::C_TEXT; return TextEditor::C_TEXT;
default:
break;
}
Q_UNREACHABLE();
}
bool ignore(ClangBackEnd::HighlightingType type)
{
using ClangBackEnd::HighlightingType;
switch (type) {
default:
break;
case HighlightingType::Namespace:
case HighlightingType::Class:
case HighlightingType::Struct:
case HighlightingType::Enum:
case HighlightingType::Union:
case HighlightingType::TypeAlias:
case HighlightingType::Typedef:
return true;
} }
Q_UNREACHABLE(); return false;
} }
TextEditor::TextStyles toTextStyles(ClangBackEnd::HighlightingTypes types) TextEditor::TextStyles toTextStyles(ClangBackEnd::HighlightingTypes types)
@@ -90,8 +111,10 @@ TextEditor::TextStyles toTextStyles(ClangBackEnd::HighlightingTypes types)
textStyles.mainStyle = toTextStyle(types.mainHighlightingType); textStyles.mainStyle = toTextStyle(types.mainHighlightingType);
for (ClangBackEnd::HighlightingType type : types.mixinHighlightingTypes) for (ClangBackEnd::HighlightingType type : types.mixinHighlightingTypes) {
if (!ignore(type))
textStyles.mixinStyles.push_back(toTextStyle(type)); textStyles.mixinStyles.push_back(toTextStyle(type));
}
return textStyles; return textStyles;
} }

View File

@@ -206,6 +206,11 @@ Type Type::pointeeType() const
return clang_getPointeeType(cxType); return clang_getPointeeType(cxType);
} }
Type Type::resultType() const
{
return clang_getResultType(cxType);
}
Type Type::argument(int index) const Type Type::argument(int index) const
{ {
return clang_getArgType(cxType, index); return clang_getArgType(cxType, index);

View File

@@ -64,6 +64,7 @@ public:
Type canonical() const; Type canonical() const;
Type classType() const; Type classType() const;
Type pointeeType() const; Type pointeeType() const;
Type resultType() const;
Type argument(int index) const; Type argument(int index) const;
Cursor declaration() const; Cursor declaration() const;

View File

@@ -436,6 +436,51 @@ CXCursor Cursor::cx() const
return cxCursor; return cxCursor;
} }
StorageClass Cursor::storageClass() const
{
CXCursor cursor = cxCursor;
if (!isDeclaration())
cursor = referenced().cxCursor;
const CX_StorageClass cxStorageClass = clang_Cursor_getStorageClass(cursor);
switch (cxStorageClass) {
case CX_SC_Invalid:
case CX_SC_OpenCLWorkGroupLocal:
break;
case CX_SC_None:
return StorageClass::None;
case CX_SC_Extern:
return StorageClass::Extern;
case CX_SC_Static:
return StorageClass::Static;
case CX_SC_PrivateExtern:
return StorageClass::PrivateExtern;
case CX_SC_Auto:
return StorageClass::Auto;
case CX_SC_Register:
return StorageClass::Register;
}
return StorageClass::Invalid;
}
AccessSpecifier Cursor::accessSpecifier() const
{
CXCursor cursor = cxCursor;
if (!isDeclaration())
cursor = referenced().cxCursor;
const CX_CXXAccessSpecifier cxAccessSpecifier = clang_getCXXAccessSpecifier(cursor);
switch (cxAccessSpecifier) {
case CX_CXXInvalidAccessSpecifier:
break;
case CX_CXXPublic:
return AccessSpecifier::Public;
case CX_CXXProtected:
return AccessSpecifier::Protected;
case CX_CXXPrivate:
return AccessSpecifier::Private;
}
return AccessSpecifier::Invalid;
}
bool operator==(const Cursor &first, const Cursor &second) bool operator==(const Cursor &first, const Cursor &second)
{ {
return clang_equalCursors(first.cxCursor, second.cxCursor); return clang_equalCursors(first.cxCursor, second.cxCursor);

View File

@@ -27,6 +27,8 @@
#include "clangtype.h" #include "clangtype.h"
#include <clangsupport/clangsupport_global.h>
#include <clang-c/Index.h> #include <clang-c/Index.h>
#include <iosfwd> #include <iosfwd>
@@ -107,6 +109,8 @@ public:
unsigned overloadedDeclarationsCount() const; unsigned overloadedDeclarationsCount() const;
Cursor overloadedDeclaration(unsigned index) const; Cursor overloadedDeclaration(unsigned index) const;
Cursor specializedCursorTemplate() const; Cursor specializedCursorTemplate() const;
AccessSpecifier accessSpecifier() const;
StorageClass storageClass() const;
CXFile includedFile() const; CXFile includedFile() const;

View File

@@ -32,6 +32,8 @@
#include "sourcerange.h" #include "sourcerange.h"
#include "sourcerangecontainer.h" #include "sourcerangecontainer.h"
#include <utils/qtcfallthrough.h>
#include <QDebug> #include <QDebug>
namespace ClangBackEnd { namespace ClangBackEnd {
@@ -114,6 +116,8 @@ bool TokenInfo::hasFunctionArguments() const
TokenInfo::operator TokenInfoContainer() const TokenInfo::operator TokenInfoContainer() const
{ {
return TokenInfoContainer(m_line, m_column, m_length, m_types, m_token, m_typeSpelling, return TokenInfoContainer(m_line, m_column, m_length, m_types, m_token, m_typeSpelling,
m_resultTypeSpelling, m_semanticParentTypeSpelling,
m_accessSpecifier, m_storageClass,
m_isIdentifier, m_isInclusion, m_isIdentifier, m_isInclusion,
m_isDeclaration, m_isDefinition); m_isDeclaration, m_isDefinition);
} }
@@ -142,6 +146,8 @@ bool isFunctionInFinalClass(const Cursor &cursor)
void TokenInfo::memberReferenceKind(const Cursor &cursor) void TokenInfo::memberReferenceKind(const Cursor &cursor)
{ {
if (cursor.isDynamicCall()) { if (cursor.isDynamicCall()) {
m_storageClass = cursor.storageClass();
m_accessSpecifier = cursor.accessSpecifier();
if (isFinalFunction(cursor) || isFunctionInFinalClass(cursor)) if (isFinalFunction(cursor) || isFunctionInFinalClass(cursor))
m_types.mainHighlightingType = HighlightingType::Function; m_types.mainHighlightingType = HighlightingType::Function;
else else
@@ -151,22 +157,6 @@ void TokenInfo::memberReferenceKind(const Cursor &cursor)
} }
} }
void TokenInfo::referencedTypeKind(const Cursor &cursor)
{
const Cursor referencedCursor = cursor.referenced();
switch (referencedCursor.kind()) {
case CXCursor_ClassDecl:
case CXCursor_StructDecl:
case CXCursor_UnionDecl:
case CXCursor_TypedefDecl:
case CXCursor_TemplateTypeParameter:
case CXCursor_TypeAliasDecl:
case CXCursor_EnumDecl: m_types.mainHighlightingType = HighlightingType::Type; break;
default: m_types.mainHighlightingType = HighlightingType::Invalid; break;
}
}
void TokenInfo::overloadedDeclRefKind(const Cursor &cursor) void TokenInfo::overloadedDeclRefKind(const Cursor &cursor)
{ {
m_types.mainHighlightingType = HighlightingType::Function; m_types.mainHighlightingType = HighlightingType::Function;
@@ -183,6 +173,7 @@ void TokenInfo::overloadedDeclRefKind(const Cursor &cursor)
void TokenInfo::variableKind(const Cursor &cursor) void TokenInfo::variableKind(const Cursor &cursor)
{ {
m_storageClass = cursor.storageClass();
if (cursor.isLocalVariable()) if (cursor.isLocalVariable())
m_types.mainHighlightingType = HighlightingType::LocalVariable; m_types.mainHighlightingType = HighlightingType::LocalVariable;
else else
@@ -192,8 +183,10 @@ void TokenInfo::variableKind(const Cursor &cursor)
m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument);
} }
void TokenInfo::fieldKind(const Cursor &) void TokenInfo::fieldKind(const Cursor &cursor)
{ {
m_accessSpecifier = cursor.accessSpecifier();
m_storageClass = cursor.storageClass();
m_types.mainHighlightingType = HighlightingType::Field; m_types.mainHighlightingType = HighlightingType::Field;
if (isOutputArgument()) if (isOutputArgument())
@@ -290,6 +283,11 @@ void TokenInfo::filterOutPreviousOutputArguments()
void TokenInfo::functionKind(const Cursor &cursor, Recursion recursion) void TokenInfo::functionKind(const Cursor &cursor, Recursion recursion)
{ {
updateTypeSpelling(cursor, true);
m_accessSpecifier = cursor.accessSpecifier();
m_storageClass = cursor.storageClass();
if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor)) if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor))
m_types.mainHighlightingType = HighlightingType::VirtualFunction; m_types.mainHighlightingType = HighlightingType::VirtualFunction;
else else
@@ -304,14 +302,106 @@ void TokenInfo::functionKind(const Cursor &cursor, Recursion recursion)
addExtraTypeIfFirstPass(HighlightingType::FunctionDefinition, recursion); addExtraTypeIfFirstPass(HighlightingType::FunctionDefinition, recursion);
} }
Utf8String fullyQualifiedType(const Cursor &cursor)
{
Utf8String typeSpelling = cursor.type().canonical().utf8Spelling();
if (typeSpelling.isEmpty()) {
// Only if it's the namespaces level.
typeSpelling = cursor.unifiedSymbolResolution();
typeSpelling.replace(Utf8StringLiteral("c:@N@"), Utf8StringLiteral(""));
typeSpelling.replace(Utf8StringLiteral("@N@"), Utf8StringLiteral("::"));
}
return typeSpelling;
}
void TokenInfo::updateTypeSpelling(const Cursor &cursor, bool functionLike)
{
m_typeSpelling = fullyQualifiedType(cursor);
m_semanticParentTypeSpelling = fullyQualifiedType(cursor.semanticParent());
if (!functionLike)
return;
Type type = cursor.type().canonical();
m_resultTypeSpelling = type.resultType().utf8Spelling();
const bool hasSpaceAfterReturnVal
= m_typeSpelling.constData()[m_resultTypeSpelling.byteSize()] == ' ';
m_typeSpelling = m_typeSpelling.mid(m_resultTypeSpelling.byteSize()
+ (hasSpaceAfterReturnVal ? 1 : 0));
}
void TokenInfo::referencedTypeKind(const Cursor &cursor)
{
const Cursor ref = cursor.referenced();
updateTypeSpelling(ref);
typeKind(ref);
}
void TokenInfo::typeKind(const Cursor &cursor)
{
m_types.mainHighlightingType = HighlightingType::Type;
const CXCursorKind kind = cursor.kind();
switch (kind) {
default:
m_types.mainHighlightingType = HighlightingType::Invalid;
return;
case CXCursor_TemplateRef:
case CXCursor_NamespaceRef:
case CXCursor_TypeRef:
referencedTypeKind(cursor);
return;
case CXCursor_ClassTemplate:
case CXCursor_ClassTemplatePartialSpecialization:
case CXCursor_ClassDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Class);
return;
case CXCursor_UnionDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Union);
return;
case CXCursor_StructDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Struct);
return;
case CXCursor_EnumDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Enum);
return;
case CXCursor_NamespaceAlias:
case CXCursor_Namespace:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Namespace);
return;
case CXCursor_TypeAliasDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::TypeAlias);
return;
case CXCursor_TypedefDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::Typedef);
return;
case CXCursor_TemplateTypeParameter:
case CXCursor_TemplateTemplateParameter:
case CXCursor_CXXStaticCastExpr:
case CXCursor_CXXReinterpretCastExpr:
case CXCursor_ObjCCategoryDecl:
case CXCursor_ObjCCategoryImplDecl:
case CXCursor_ObjCImplementationDecl:
case CXCursor_ObjCInterfaceDecl:
case CXCursor_ObjCProtocolDecl:
case CXCursor_ObjCProtocolRef:
case CXCursor_ObjCClassRef:
case CXCursor_ObjCSuperClassRef:
break;
}
}
void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion)
{ {
m_isIdentifier = (cursor.kind() != CXCursor_PreprocessingDirective); // For now save type spelling only for declarations.
if (m_isDeclaration)
updateTypeSpelling(cursor);
switch (cursor.kind()) { const CXCursorKind kind = cursor.kind();
m_isIdentifier = (kind != CXCursor_PreprocessingDirective);
switch (kind) {
case CXCursor_Destructor: case CXCursor_Destructor:
case CXCursor_Constructor: case CXCursor_Constructor:
case CXCursor_FunctionDecl: case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate:
case CXCursor_CallExpr: case CXCursor_CallExpr:
case CXCursor_CXXMethod: functionKind(cursor, recursion); break; case CXCursor_CXXMethod: functionKind(cursor, recursion); break;
case CXCursor_NonTypeTemplateParameter: m_types.mainHighlightingType = HighlightingType::LocalVariable; break; case CXCursor_NonTypeTemplateParameter: m_types.mainHighlightingType = HighlightingType::LocalVariable; break;
@@ -327,21 +417,22 @@ void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion)
case CXCursor_ObjCInstanceMethodDecl: case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_ObjCSynthesizeDecl: case CXCursor_ObjCSynthesizeDecl:
case CXCursor_ObjCDynamicDecl: m_types.mainHighlightingType = HighlightingType::Field; break; case CXCursor_ObjCDynamicDecl: m_types.mainHighlightingType = HighlightingType::Field; break;
case CXCursor_TemplateRef:
case CXCursor_NamespaceRef:
case CXCursor_TypeRef: referencedTypeKind(cursor); break; case CXCursor_TypeRef: referencedTypeKind(cursor); break;
case CXCursor_ClassDecl: case CXCursor_ClassDecl:
case CXCursor_ClassTemplate:
case CXCursor_ClassTemplatePartialSpecialization: case CXCursor_ClassTemplatePartialSpecialization:
case CXCursor_TemplateTypeParameter:
case CXCursor_TemplateTemplateParameter:
case CXCursor_UnionDecl: case CXCursor_UnionDecl:
case CXCursor_StructDecl: case CXCursor_StructDecl:
case CXCursor_TemplateRef: case CXCursor_EnumDecl:
case CXCursor_Namespace: case CXCursor_Namespace: m_types.mixinHighlightingTypes.push_back(HighlightingType::Declaration);
case CXCursor_NamespaceRef: Q_FALLTHROUGH();
case CXCursor_TemplateTypeParameter:
case CXCursor_TemplateTemplateParameter:
case CXCursor_NamespaceAlias: case CXCursor_NamespaceAlias:
case CXCursor_TypeAliasDecl: case CXCursor_TypeAliasDecl:
case CXCursor_TypedefDecl: case CXCursor_TypedefDecl:
case CXCursor_ClassTemplate:
case CXCursor_EnumDecl:
case CXCursor_CXXStaticCastExpr: case CXCursor_CXXStaticCastExpr:
case CXCursor_CXXReinterpretCastExpr: case CXCursor_CXXReinterpretCastExpr:
case CXCursor_ObjCCategoryDecl: case CXCursor_ObjCCategoryDecl:
@@ -351,9 +442,8 @@ void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion)
case CXCursor_ObjCProtocolDecl: case CXCursor_ObjCProtocolDecl:
case CXCursor_ObjCProtocolRef: case CXCursor_ObjCProtocolRef:
case CXCursor_ObjCClassRef: case CXCursor_ObjCClassRef:
case CXCursor_ObjCSuperClassRef: m_types.mainHighlightingType = HighlightingType::Type; break; case CXCursor_ObjCSuperClassRef: typeKind(cursor); break;
case CXCursor_OverloadedDeclRef: overloadedDeclRefKind(cursor); break; case CXCursor_OverloadedDeclRef: overloadedDeclRefKind(cursor); break;
case CXCursor_FunctionTemplate: m_types.mainHighlightingType = HighlightingType::Function; break;
case CXCursor_EnumConstantDecl: m_types.mainHighlightingType = HighlightingType::Enumeration; break; case CXCursor_EnumConstantDecl: m_types.mainHighlightingType = HighlightingType::Enumeration; break;
case CXCursor_PreprocessingDirective: m_types.mainHighlightingType = HighlightingType::Preprocessor; break; case CXCursor_PreprocessingDirective: m_types.mainHighlightingType = HighlightingType::Preprocessor; break;
case CXCursor_MacroExpansion: m_types.mainHighlightingType = HighlightingType::PreprocessorExpansion; break; case CXCursor_MacroExpansion: m_types.mainHighlightingType = HighlightingType::PreprocessorExpansion; break;
@@ -451,7 +541,6 @@ void TokenInfo::collectKinds(CXTranslationUnit cxTranslationUnit,
m_types = HighlightingTypes(); m_types = HighlightingTypes();
m_token = ClangString(clang_getTokenSpelling(cxTranslationUnit, *cxToken)); m_token = ClangString(clang_getTokenSpelling(cxTranslationUnit, *cxToken));
m_typeSpelling = cursor.type().utf8Spelling();
if (cxTokenKind == CXToken_Identifier) { if (cxTokenKind == CXToken_Identifier) {
m_isDeclaration = cursor.isDeclaration(); m_isDeclaration = cursor.isDeclaration();

View File

@@ -93,6 +93,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 typeKind(const Cursor &cursor);
void collectKinds(CXTranslationUnit cxTranslationUnit, 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);
@@ -100,6 +101,7 @@ private:
void collectOutputArguments(const Cursor &cursor); void collectOutputArguments(const Cursor &cursor);
void filterOutPreviousOutputArguments(); void filterOutPreviousOutputArguments();
bool isArgumentInCurrentOutputArgumentLocations() const; bool isArgumentInCurrentOutputArgumentLocations() const;
void updateTypeSpelling(const Cursor &cursor, bool functionLike = false);
private: private:
std::vector<CXSourceRange> *m_currentOutputArgumentRanges = nullptr; std::vector<CXSourceRange> *m_currentOutputArgumentRanges = nullptr;
@@ -111,6 +113,10 @@ private:
HighlightingTypes m_types; HighlightingTypes m_types;
Utf8String m_token; Utf8String m_token;
Utf8String m_typeSpelling; Utf8String m_typeSpelling;
Utf8String m_resultTypeSpelling;
Utf8String m_semanticParentTypeSpelling;
AccessSpecifier m_accessSpecifier = AccessSpecifier::Invalid;
StorageClass m_storageClass = StorageClass::Invalid;
bool m_isIdentifier = false; bool m_isIdentifier = false;
bool m_isInclusion = false; bool m_isInclusion = false;
bool m_isDeclaration = false; bool m_isDeclaration = false;

View File

@@ -670,7 +670,9 @@ void ClangCodeModelServer::expectDocumentAnnotationsChangedForFileBWithSpecificH
types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::Declaration); types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::Declaration);
types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::FunctionDefinition); types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::FunctionDefinition);
const TokenInfoContainer tokenInfo(1, 6, 8, types, Utf8String("function", 8), const TokenInfoContainer tokenInfo(1, 6, 8, types, Utf8String("function", 8),
Utf8String("void (int)", 10), true, false, true, true); Utf8String("(int)", 5), Utf8String("void", 4),
Utf8String(), AccessSpecifier::Invalid,
StorageClass::None, true, false, true, true);
EXPECT_CALL(mockClangCodeModelClient, EXPECT_CALL(mockClangCodeModelClient,
documentAnnotationsChanged( documentAnnotationsChanged(

View File

@@ -803,6 +803,96 @@ TEST_F(Cursor, ConstReferenceIsNotOutputArgument)
ASSERT_FALSE(argument.isOutputArgument()); ASSERT_FALSE(argument.isOutputArgument());
} }
TEST_F(Cursor, ResultType)
{
auto methodCursor = translationUnit.cursorAt(31, 18);
Utf8String resultType = methodCursor.type().resultType().spelling();
ASSERT_THAT(resultType, Utf8String("bool", 4));
}
TEST_F(Cursor, PrivateMethodAccessSpecifier)
{
auto methodCursor = translationUnit.cursorAt(16, 17);
auto accessSpecifier = methodCursor.accessSpecifier();
ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private);
}
TEST_F(Cursor, PublicMethodAccessSpecifier)
{
auto methodCursor = translationUnit.cursorAt(79, 25);
auto accessSpecifier = methodCursor.accessSpecifier();
ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Public);
}
TEST_F(Cursor, ProtectedMethodAccessSpecifier)
{
auto methodCursor = translationUnit.cursorAt(131, 22);
auto accessSpecifier = methodCursor.accessSpecifier();
ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Protected);
}
TEST_F(Cursor, PrivateFieldAccessSpecifier)
{
auto fieldCursor = translationUnit.cursorAt(21, 12);
auto accessSpecifier = fieldCursor.accessSpecifier();
ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private);
}
TEST_F(Cursor, InvalidAccessSpecifier)
{
auto localVarCursor = translationUnit.cursorAt(62, 9);
auto accessSpecifier = localVarCursor.accessSpecifier();
ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Invalid);
}
TEST_F(Cursor, NoStorageClass)
{
auto localVarCursor = translationUnit.cursorAt(62, 9);
auto storageClass = localVarCursor.storageClass();
ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::None);
}
TEST_F(Cursor, ExternVarStorageClass)
{
auto externalVarCursor = translationUnit.cursorAt(133, 12);
auto storageClass = externalVarCursor.storageClass();
ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Extern);
}
TEST_F(Cursor, StaticMethodStorageClass)
{
auto methodCursor = translationUnit.cursorAt(135, 13);
auto storageClass = methodCursor.storageClass();
ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Static);
}
TEST_F(Cursor, InvalidStorageClass)
{
auto functionTemplateCursor = translationUnit.cursorAt(137, 28);
auto storageClass = functionTemplateCursor.storageClass();
ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Invalid);
}
Data *Cursor::d; Data *Cursor::d;
void Cursor::SetUpTestCase() void Cursor::SetUpTestCase()

View File

@@ -127,3 +127,11 @@ void PointerToConst(const int *);
void Pointer(int *); void Pointer(int *);
void ConstantPointer(int *const); void ConstantPointer(int *const);
void ConstIntegerValue(const int); void ConstIntegerValue(const int);
void NonFinalStruct::ProtectedMethodAccessSpecifier() {}
extern int ExternVarStorageClass;
static void StaticMethodStorageClass() {}
template<class T> const T &InvalidStorageClass(const T &type) { return type; }

View File

@@ -39,4 +39,6 @@ struct NonFinalStruct
{ {
virtual void FinalVirtualMethod() final; virtual void FinalVirtualMethod() final;
void function(); void function();
protected:
void ProtectedMethodAccessSpecifier();
}; };

View File

@@ -331,7 +331,7 @@ void f14()
using IntegerAlias = int; using IntegerAlias = int;
using SecondIntegerAlias = IntegerAlias; using SecondIntegerAlias = IntegerAlias;
using IntegerTypedef = int; typedef int IntegerTypedef;
using Function = void (*)(); using Function = void (*)();
@@ -588,3 +588,5 @@ void BaseClass::VirtualFunction() {}
class WithVirtualFunctionDefined { class WithVirtualFunctionDefined {
virtual void VirtualFunctionDefinition() {}; virtual void VirtualFunctionDefinition() {};
}; };
namespace NFoo { namespace NBar { namespace NTest { class NamespaceTypeSpelling; } } }

View File

@@ -490,6 +490,13 @@ static const char *highlightingTypeToCStringLiteral(HighlightingType type)
RETURN_TEXT_FOR_CASE(PreprocessorExpansion); RETURN_TEXT_FOR_CASE(PreprocessorExpansion);
RETURN_TEXT_FOR_CASE(PrimitiveType); RETURN_TEXT_FOR_CASE(PrimitiveType);
RETURN_TEXT_FOR_CASE(Declaration); RETURN_TEXT_FOR_CASE(Declaration);
RETURN_TEXT_FOR_CASE(Namespace);
RETURN_TEXT_FOR_CASE(Class);
RETURN_TEXT_FOR_CASE(Struct);
RETURN_TEXT_FOR_CASE(Enum);
RETURN_TEXT_FOR_CASE(Union);
RETURN_TEXT_FOR_CASE(TypeAlias);
RETURN_TEXT_FOR_CASE(Typedef);
} }
return ""; return "";

View File

@@ -75,9 +75,8 @@ MATCHER_P4(IsHighlightingMark, line, column, length, type,
+ PrintToString(TokenInfo(line, column, length, type)) + PrintToString(TokenInfo(line, column, length, type))
) )
{ {
const TokenInfo expected(line, column, length, type); return arg.line() == line && arg.column() == column && arg.length() == length
&& arg.types().mainHighlightingType == type;
return arg == expected;
} }
MATCHER_P(HasOnlyType, type, MATCHER_P(HasOnlyType, type,
@@ -396,7 +395,7 @@ TEST_F(TokenInfos, Enumeration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(118, 17)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(118, 17));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum));
} }
TEST_F(TokenInfos, Enumerator) TEST_F(TokenInfos, Enumerator)
@@ -410,7 +409,7 @@ TEST_F(TokenInfos, EnumerationReferenceDeclarationType)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Enum));
} }
TEST_F(TokenInfos, EnumerationReferenceDeclarationVariable) TEST_F(TokenInfos, EnumerationReferenceDeclarationVariable)
@@ -438,7 +437,7 @@ TEST_F(TokenInfos, ClassForwardDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(130, 12)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(130, 12));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class));
} }
TEST_F(TokenInfos, ConstructorDeclaration) TEST_F(TokenInfos, ConstructorDeclaration)
@@ -459,14 +458,14 @@ TEST_F(TokenInfos, ClassForwardDeclarationReference)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(138, 23)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(138, 23));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, ClassTypeReference) TEST_F(TokenInfos, ClassTypeReference)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, ConstructorReferenceVariable) TEST_F(TokenInfos, ConstructorReferenceVariable)
@@ -480,14 +479,14 @@ TEST_F(TokenInfos, UnionDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(145, 12)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(145, 12));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Union));
} }
TEST_F(TokenInfos, UnionDeclarationReference) TEST_F(TokenInfos, UnionDeclarationReference)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Union));
} }
TEST_F(TokenInfos, GlobalVariable) TEST_F(TokenInfos, GlobalVariable)
@@ -501,21 +500,21 @@ TEST_F(TokenInfos, StructDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(50, 11)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(50, 11));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Struct));
} }
TEST_F(TokenInfos, NameSpace) TEST_F(TokenInfos, NameSpace)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(160, 22)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(160, 22));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Namespace));
} }
TEST_F(TokenInfos, NameSpaceAlias) TEST_F(TokenInfos, NameSpaceAlias)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(164, 38)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(164, 38));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace));
} }
TEST_F(TokenInfos, UsingStructInNameSpace) TEST_F(TokenInfos, UsingStructInNameSpace)
@@ -529,14 +528,14 @@ TEST_F(TokenInfos, NameSpaceReference)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace));
} }
TEST_F(TokenInfos, StructInNameSpaceReference) TEST_F(TokenInfos, StructInNameSpaceReference)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35));
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct));
} }
TEST_F(TokenInfos, VirtualFunctionDeclaration) TEST_F(TokenInfos, VirtualFunctionDeclaration)
@@ -676,7 +675,7 @@ TEST_F(TokenInfos, TemplateDefaultParameter)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135));
ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[5], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct));
} }
TEST_F(TokenInfos, NonTypeTemplateParameter) TEST_F(TokenInfos, NonTypeTemplateParameter)
@@ -704,14 +703,14 @@ TEST_F(TokenInfos, TemplateTemplateParameterDefaultArgument)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135));
ASSERT_THAT(infos[19], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[19], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, TemplateFunctionDeclaration) TEST_F(TokenInfos, TemplateFunctionDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(266, 63)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(266, 63));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Function)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition));
} }
TEST_F(TokenInfos, TemplateTypeParameterReference) TEST_F(TokenInfos, TemplateTypeParameterReference)
@@ -824,7 +823,7 @@ TEST_F(TokenInfos, EnumerationType)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(316, 30)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(316, 30));
ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum));
} }
TEST_F(TokenInfos, TypeInStaticCast) TEST_F(TokenInfos, TypeInStaticCast)
@@ -861,49 +860,49 @@ TEST_F(TokenInfos, IntegerAliasDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(333, 41)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(333, 41));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias));
} }
TEST_F(TokenInfos, IntegerAlias) TEST_F(TokenInfos, IntegerAlias)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(341, 31)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(341, 31));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias));
} }
TEST_F(TokenInfos, SecondIntegerAlias) TEST_F(TokenInfos, SecondIntegerAlias)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(342, 43)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(342, 43));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias));
} }
TEST_F(TokenInfos, IntegerTypedef) TEST_F(TokenInfos, IntegerTypedef)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(343, 35)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(343, 35));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef));
} }
TEST_F(TokenInfos, FunctionAlias) TEST_F(TokenInfos, FunctionAlias)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(344, 16)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(344, 16));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias));
} }
TEST_F(TokenInfos, FriendTypeDeclaration) TEST_F(TokenInfos, FriendTypeDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(350, 28)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(350, 28));
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, FriendArgumentTypeDeclaration) TEST_F(TokenInfos, FriendArgumentTypeDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65));
ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[6], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, FriendArgumentDeclaration) TEST_F(TokenInfos, FriendArgumentDeclaration)
@@ -931,14 +930,14 @@ TEST_F(TokenInfos, TemplatedType)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(377, 21)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(377, 21));
ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class));
} }
TEST_F(TokenInfos, TemplatedTypeDeclaration) TEST_F(TokenInfos, TemplatedTypeDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(384, 49)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(384, 49));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, NoOperator) TEST_F(TokenInfos, NoOperator)
@@ -959,21 +958,21 @@ TEST_F(TokenInfos, TemplateClassNamespace)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace));
} }
TEST_F(TokenInfos, TemplateClass) TEST_F(TokenInfos, TemplateClass)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78));
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, TemplateClassParameter) TEST_F(TokenInfos, TemplateClassParameter)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78));
ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Type, HighlightingType::Class));
} }
TEST_F(TokenInfos, TemplateClassDeclaration) TEST_F(TokenInfos, TemplateClassDeclaration)
@@ -987,14 +986,14 @@ TEST_F(TokenInfos, TypeDefDeclaration)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(418, 36)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(418, 36));
ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef));
} }
TEST_F(TokenInfos, TypeDefDeclarationUsage) TEST_F(TokenInfos, TypeDefDeclarationUsage)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(419, 48)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(419, 48));
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef));
} }
TEST_F(TokenInfos, NonConstReferenceArgument) TEST_F(TokenInfos, NonConstReferenceArgument)
@@ -1156,7 +1155,7 @@ TEST_F(TokenInfos, EnumerationTypeDef)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(424, 41)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(424, 41));
ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum));
} }
// QTCREATORBUG-15473 // QTCREATORBUG-15473
@@ -1171,7 +1170,7 @@ TEST_F(TokenInfos, ClassTemplateParticalSpecialization)
{ {
const auto infos = translationUnit.tokenInfosInRange(sourceRange(553, 33)); const auto infos = translationUnit.tokenInfosInRange(sourceRange(553, 33));
ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Type)); ASSERT_THAT(infos[6], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class));
} }
TEST_F(TokenInfos, UsingFunction) TEST_F(TokenInfos, UsingFunction)
@@ -1246,6 +1245,13 @@ TEST_F(TokenInfos, DefineIsNotIdentifier)
ASSERT_THAT(container.isIncludeDirectivePath(), false); ASSERT_THAT(container.isIncludeDirectivePath(), false);
} }
TEST_F(TokenInfos, NamespaceTypeSpelling)
{
const auto infos = translationUnit.tokenInfosInRange(sourceRange(592, 59));
ClangBackEnd::TokenInfoContainer container(infos[10]);
ASSERT_THAT(container.semanticParentTypeSpelling(), Utf8StringLiteral("NFoo::NBar::NTest"));
}
Data *TokenInfos::d; Data *TokenInfos::d;
void TokenInfos::SetUpTestCase() void TokenInfos::SetUpTestCase()