From 939394927c943ec3d69a7b59dbbf80799507b4e7 Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 9 Aug 2024 22:30:46 +0800 Subject: [PATCH] some update. --- docs/examples/ASTVisitor.cpp | 126 +++++---- docs/examples/Preprocessor.cpp | 3 +- src/Feature/SemanticToken.cpp | 468 ++++++++++++++------------------- src/Feature/SemanticToken2.cpp | 269 ------------------- test.cpp | 11 +- 5 files changed, 275 insertions(+), 602 deletions(-) delete mode 100644 src/Feature/SemanticToken2.cpp diff --git a/docs/examples/ASTVisitor.cpp b/docs/examples/ASTVisitor.cpp index f34337c4..fb316201 100644 --- a/docs/examples/ASTVisitor.cpp +++ b/docs/examples/ASTVisitor.cpp @@ -618,6 +618,7 @@ public: #define Traverse(NAME) bool Traverse##NAME(clang::NAME* node) #define WalkUpFrom(NAME) bool WalkUpFrom##NAME(clang::NAME* node) #define VISIT(NAME) bool Visit##NAME(clang::NAME* node) +#define VISIT_TYPE(NAME) bool Visit##NAME(clang::NAME node) class ASTVistor : public clang::RecursiveASTVisitor { private: @@ -667,23 +668,15 @@ public: // return true; //} // - - bool VisitCXXStaticCastExpr(clang::CXXStaticCastExpr* expr) { - expr->getAngleBrackets().getBegin().dump(sourceManager); - expr->getAngleBrackets().getEnd().dump(sourceManager); - return true; - } - - bool VisitTypeLoc(clang::TypeLoc loc) { - // loc.dump(); - return true; + void addAngle(clang::SourceLocation l, clang::SourceLocation r) { + l.dump(sourceManager); + r.dump(sourceManager); } VISIT(DeclaratorDecl) { for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { - if(auto* TPL = node->getTemplateParameterList(i)) { - TPL->getLAngleLoc().dump(sourceManager); - TPL->getRAngleLoc().dump(sourceManager); + if(auto params = node->getTemplateParameterList(i)) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } } return true; @@ -691,83 +684,84 @@ public: VISIT(TagDecl) { for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { - if(auto* TPL = node->getTemplateParameterList(i)) { - TPL->getLAngleLoc().dump(sourceManager); - TPL->getRAngleLoc().dump(sourceManager); + if(auto params = node->getTemplateParameterList(i)) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } } return true; } - VISIT(TemplateDecl) { - if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - auto langle = params->getLAngleLoc(); - auto rangle = params->getRAngleLoc(); - langle.dump(sourceManager); - rangle.dump(sourceManager); + VISIT(FunctionDecl) { + if(auto args = node->getTemplateSpecializationArgsAsWritten()) { + addAngle(args->getLAngleLoc(), args->getRAngleLoc()); } return true; } - VISIT(FunctionDecl) { - if(auto* args = node->getTemplateSpecializationArgsAsWritten()) { - auto langle = args->LAngleLoc; - auto rangle = args->RAngleLoc; - langle.dump(sourceManager); - rangle.dump(sourceManager); + VISIT(TemplateDecl) { + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } return true; } VISIT(ClassTemplateSpecializationDecl) { - if(const clang::ASTTemplateArgumentListInfo* args = node->getTemplateArgsAsWritten()) { - auto langle = args->getLAngleLoc(); - auto rangle = args->getRAngleLoc(); - langle.dump(sourceManager); - rangle.dump(sourceManager); + if(auto args = node->getTemplateArgsAsWritten()) { + addAngle(args->getLAngleLoc(), args->getRAngleLoc()); } return true; } VISIT(ClassTemplatePartialSpecializationDecl) { - if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - auto langle = params->getLAngleLoc(); - auto rangle = params->getRAngleLoc(); - langle.dump(sourceManager); - rangle.dump(sourceManager); + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } return true; } - // VISIT(FunctionTemplateSpecializationInfo) { - // if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - // auto langle = params->getLAngleLoc(); - // auto rangle = params->getRAngleLoc(); - // } - // return true; - // } + VISIT(VarTemplateSpecializationDecl) { + if(auto args = node->getTemplateArgsAsWritten()) { + addAngle(args->LAngleLoc, args->RAngleLoc); + } + return true; + } - // bool VisitTemplateSpecializationTypeLoc(clang::TemplateSpecializationTypeLoc loc) { - // // loc.dump(); - // auto l_angle = loc.getLAngleLoc(); - // l_angle.dump(sourceManager); - // auto r_angle = sourceManager.getFileLoc(loc.getRAngleLoc()); - // r_angle.dump(sourceManager); - // - // // llvm::outs() << sourceManager.getSpellingColumnNumber(r_angle) << "\n"; - // // llvm::outs() << sourceManager.getExpansionColumnNumber(r_angle) << "\n"; - // - // llvm::outs() << sourceManager.isInMainFile(r_angle) << "\n"; - // - // auto ID = sourceManager.getFileID(r_angle); - // llvm::outs() << sourceManager.getFilename(r_angle) << "\n"; - // - // auto tokens = buffer.spelledTokens(sourceManager.getFileID(l_angle)); - // for(auto& token: tokens) { - // token.location().dump(sourceManager); - // } - // return true; - //} + VISIT(VarTemplatePartialSpecializationDecl) { + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); + } + return true; + } + + VISIT(CXXNamedCastExpr) { + addAngle(node->getAngleBrackets().getBegin(), node->getAngleBrackets().getEnd()); + return true; + } + + VISIT(OverloadExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); + return true; + } + + VISIT(CXXDependentScopeMemberExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); + return true; + } + + VISIT(DependentScopeDeclRefExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); + return true; + } + + VISIT_TYPE(TemplateSpecializationTypeLoc) { + addAngle(node.getLAngleLoc(), node.getRAngleLoc()); + return true; + } + + VISIT_TYPE(DependentTemplateSpecializationTypeLoc) { + addAngle(node.getLAngleLoc(), node.getRAngleLoc()); + return true; + } }; int main(int argc, const char** argv) { diff --git a/docs/examples/Preprocessor.cpp b/docs/examples/Preprocessor.cpp index cc546d90..ab469ba9 100644 --- a/docs/examples/Preprocessor.cpp +++ b/docs/examples/Preprocessor.cpp @@ -122,6 +122,7 @@ int main(int argc, const char** argv) { // // // TODO: split annoated token // // } // }); + pp.addPPCallbacks(std::make_unique(pp)); clang::syntax::TokenCollector collector{pp}; @@ -138,7 +139,7 @@ int main(int argc, const char** argv) { llvm::outs() << "Token: " << token.text(sm) << " " << clang::tok::getTokenName(token.kind()) << "\n"; } - buffer.expansionStartingAt(tokens[0].location()); + // auto tokens2 = buffer.expandedTokens(); // for(auto& token: tokens2) { // token.dumpForTests(sm); diff --git a/src/Feature/SemanticToken.cpp b/src/Feature/SemanticToken.cpp index b36abc74..ffd68a42 100644 --- a/src/Feature/SemanticToken.cpp +++ b/src/Feature/SemanticToken.cpp @@ -1,332 +1,272 @@ #include #include -namespace clice { - -using protocol::SemanticTokenTypes; -using protocol::SemanticTokenModifiers; - -struct SemanticToken { - clang::SourceRange range; - SemanticTokenTypes type; - uint32_t modifiers = 0; - -#define ADD_MODIFIER(NAME) \ - SemanticToken& add##NAME(bool is##NAME) { \ - modifiers |= is##NAME ? SemanticTokenModifiers::NAME : 0; \ - return *this; \ - } - ADD_MODIFIER(Declaration) - ADD_MODIFIER(Definition) - ADD_MODIFIER(Const) - ADD_MODIFIER(Constexpr) - ADD_MODIFIER(Consteval) - ADD_MODIFIER(Virtual) - ADD_MODIFIER(PureVirtual) - ADD_MODIFIER(Inline) - ADD_MODIFIER(Static) - ADD_MODIFIER(Deprecated) - ADD_MODIFIER(Local) -#undef ADD_MODIFIER - - SemanticToken& addDefinitionElseDeclaration(bool isDefinition) { - modifiers |= - isDefinition ? SemanticTokenModifiers::Definition : SemanticTokenModifiers::Declaration; - return *this; - } - - SemanticToken& setType(SemanticTokenTypes type) { - this->type = type; - return *this; - } -}; - -class HighlighCollector { -private: - clang::ASTContext& context; - clang::syntax::TokenBuffer& buffer; - clang::SourceManager& SM; - clang::Preprocessor& PP; - // store all tokens in the main file - std::vector tokens; - llvm::DenseMap tokenMap; - // cache the last location and token index - // to have a better performance in traversing the same node - clang::SourceLocation lastLocation; - std::optional lastTokenIndex; - -public: - HighlighCollector(ParsedAST& ast, clang::Preprocessor& PP) : - context(ast.ASTContext()), buffer(ast. - ()), SM(ast.SourceManager()), PP(PP) { - // TODO: render diretives use the information from the preprocessor - // collect all source tokens(preprocessings haven't occurred) - for(auto& token: buffer.spelledTokens(SM.getMainFileID())) { - clang::tok::TokenKind kind = token.kind(); - SemanticTokenTypes type = SemanticTokenTypes::Unknown; - - switch(kind) { - case clang::tok::numeric_constant: { - type = SemanticTokenTypes::Number; - break; - } - case clang::tok::char_constant: { - type = SemanticTokenTypes::Char; - break; - } - case clang::tok::string_literal: { - type = SemanticTokenTypes::String; - break; - } - case clang::tok::comment: { - type = SemanticTokenTypes::Comment; - break; - } - - { - type = SemanticTokenTypes::Operator; - break; - } - - default: { - if(auto II = PP.getIdentifierInfo(token.text(SM))) { - if(II->isKeyword(PP.getLangOpts())) { - type = SemanticTokenTypes::Keyword; - } - } - } - } - - tokenMap[&token] = tokens.size(); - tokens.emplace_back(token.range(SM), type, 0); - clang::SourceLocation loc = token.location(); - auto length = token.length(); - } - } - - /// determine whether the location is in the main file or in the header file - bool isInMainFile(clang::Decl* decl) { return isInMainFile(decl->getLocation()); } - - bool isInMainFile(clang::SourceLocation location) { return SM.isWrittenInMainFile(location); } - - SemanticToken* lookup(clang::SourceLocation location) { - // check whether the location is same as the last location - if(lastLocation != location) { - // if not, update the last location and find the token - lastLocation = location; - auto token = buffer.spelledTokenContaining(location); - if(token) { - // if there is a corresponding token, update the token - auto iter = tokenMap.find(token); - assert(iter != tokenMap.end()); - auto index = iter->second; - lastTokenIndex = index; - return &tokens[index]; - } else { - // if there is no corresponding token, reset the last token index - lastTokenIndex.reset(); - return nullptr; - } - } else { - // if yes, use the last token index to find the token - if(lastTokenIndex) { - return &tokens[*lastTokenIndex]; - } - } - } - - void collect() {} -}; // namespace clice - -class HighlightVisitor : public clang::RecursiveASTVisitor { -private: - HighlighCollector& collector; - -public: - HighlightVisitor(HighlighCollector& collector) : collector(collector) {} +namespace clice::feature { #define Traverse(NAME) bool Traverse##NAME(clang::NAME* node) #define WalkUpFrom(NAME) bool WalkUpFrom##NAME(clang::NAME* node) #define VISIT(NAME) bool Visit##NAME(clang::NAME* node) +#define VISIT_TYPE(NAME) bool Visit##NAME(clang::NAME node) + +using protocol::SemanticTokenType; +using protocol::SemanticTokenModifier; + +class SemanticToken { +private: + clang::SourceRange range; + SemanticTokenType type; + uint32_t modifiers; + +private: + +public: + SemanticToken(SemanticTokenType type, clang::SourceLocation begin, clang::SourceLocation end) : + range(begin, end), type(type), modifiers(0) {} + + SemanticToken(SemanticTokenType type, const clang::syntax::Token& token) : + range(token.location(), token.endLocation()), type(type), modifiers(0) {} + + SemanticToken& addModifier(SemanticTokenModifier modifier) { + modifiers |= (static_cast>(modifier) << 1); + return *this; + } + + // SemanticToken& add() { int x = 1; } +}; + +class HighlightCollector : public clang::RecursiveASTVisitor { +private: + clang::ASTContext& context; + clang::Preprocessor& preprocessor; + clang::SourceManager& sourceManager; + clang::syntax::TokenBuffer& tokenBuffer; + std::vector tokens; + +public: + HighlightCollector(ParsedAST& AST) : + context(AST.ASTContext()), preprocessor(AST.Preprocessor()), + sourceManager(AST.SourceManager()), tokenBuffer(AST.TokenBuffer()) {} + + std::vector collect() && { + + // highlight tokens directly from token buffer. + // mainly about directives, macros, keywords, comments, operators, and literals. + // TraverseTokens(); + + // highlight tokens from AST. + // mainly about types, functions, variables and namespaces. + TraverseTranslationUnitDecl(context.getTranslationUnitDecl()); + + return std::move(tokens); + } + + void addAngle(clang::SourceLocation left, clang::SourceLocation right) {} + + void TraverseTokens() { + auto spelledTokens = tokenBuffer.spelledTokens(sourceManager.getMainFileID()); + bool in_directive = false; + bool in_include = false; + for(std::size_t index = 0; index < spelledTokens.size(); ++index) { + auto& current = spelledTokens[index]; + switch(current.kind()) { + case clang::tok::TokenKind::comment: { + tokens.emplace_back(SemanticTokenType::Comment, current); + break; + } + case clang::tok::TokenKind::numeric_constant: { + tokens.emplace_back(SemanticTokenType::Number, current); + break; + } + case clang::tok::TokenKind::char_constant: + case clang::tok::TokenKind::wide_char_constant: + case clang::tok::TokenKind::utf8_char_constant: + case clang::tok::TokenKind::utf16_char_constant: + case clang::tok::TokenKind::utf32_char_constant: { + tokens.emplace_back(SemanticTokenType::Char, current); + break; + } + case clang::tok::TokenKind::string_literal: + case clang::tok::TokenKind::wide_string_literal: + case clang::tok::TokenKind::utf8_string_literal: + case clang::tok::TokenKind::utf16_string_literal: + case clang::tok::TokenKind::utf32_string_literal: { + tokens.emplace_back(SemanticTokenType::String, current); + break; + } + case clang::tok::identifier: { + break; + } + case clang::tok::l_paren: { + tokens.emplace_back(SemanticTokenType::Paren, current) + .addModifier(SemanticTokenModifier::Left); + break; + } + case clang::tok::r_paren: { + tokens.emplace_back(SemanticTokenType::Paren, current) + .addModifier(SemanticTokenModifier::Right); + break; + } + case clang::tok::l_square: { + tokens.emplace_back(SemanticTokenType::Bracket, current) + .addModifier(SemanticTokenModifier::Left); + break; + } + case clang::tok::r_square: { + tokens.emplace_back(SemanticTokenType::Bracket, current) + .addModifier(SemanticTokenModifier::Right); + break; + } + case clang::tok::l_brace: { + tokens.emplace_back(SemanticTokenType::Brace, current) + .addModifier(SemanticTokenModifier::Left); + break; + } + case clang::tok::r_brace: { + tokens.emplace_back(SemanticTokenType::Brace, current) + .addModifier(SemanticTokenModifier::Right); + break; + } + case clang::tok::plus: // + + case clang::tok::plusplus: // ++ + case clang::tok::plusequal: // += + case clang::tok::minus: // - + case clang::tok::minusminus: // -- + case clang::tok::minusequal: // -= + case clang::tok::star: // * + case clang::tok::starequal: // *= + case clang::tok::slash: // / + case clang::tok::slashequal: // /= + case clang::tok::percent: // % + case clang::tok::percentequal: // %= + case clang::tok::amp: // & + case clang::tok::ampamp: // && + case clang::tok::ampequal: // &= + case clang::tok::pipe: // | + case clang::tok::pipepipe: // || + case clang::tok::pipeequal: // |= + case clang::tok::caret: // ^ + case clang::tok::caretequal: // ^= + case clang::tok::exclaim: // ! + case clang::tok::exclaimequal: // != + case clang::tok::equal: // = + case clang::tok::equalequal: // == + { + } + case clang::tok::eod: { + in_directive = false; + break; + } + default: break; + } + } + } Traverse(TranslationUnitDecl) { - // filter out the nodes that are not in the main file(in headers) for(auto decl: node->decls()) { - auto loc = decl->getLocation(); - if(collector.isInMainFile(loc)) { + // we only need to highlight the token in main file. + // so filter out the nodes which are in headers for better performance. + if(sourceManager.isInMainFile(decl->getLocation())) { TraverseDecl(decl); } } return true; } - WalkUpFrom(NamespaceDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Namespace); + WalkUpFrom(NamespaceDecl) {} + + VISIT(DeclaratorDecl) { + for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { + if(auto params = node->getTemplateParameterList(i)) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); + } } return true; } - WalkUpFrom(TypeDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Type); + VISIT(TagDecl) { + for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { + if(auto params = node->getTemplateParameterList(i)) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); + } } return true; } - WalkUpFrom(RecordDecl) { - // if(auto token = collector.lookup(node->getLocation())) { - // token->setType(SemanticTokenTypes::Struct); - // } - return true; - } - - WalkUpFrom(CXXRecordDecl) { - // collector.attach(node, SemanticTokenTypes::Class, 0); - return true; - } - - WalkUpFrom(FieldDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Field); - auto TSI = node->getTypeSourceInfo(); + VISIT(FunctionDecl) { + if(auto args = node->getTemplateSpecializationArgsAsWritten()) { + addAngle(args->getLAngleLoc(), args->getRAngleLoc()); } return true; } - WalkUpFrom(EnumDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Enum); + VISIT(TemplateDecl) { + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } return true; } - WalkUpFrom(EnumConstantDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::EnumMember); + VISIT(ClassTemplateSpecializationDecl) { + if(auto args = node->getTemplateArgsAsWritten()) { + addAngle(args->getLAngleLoc(), args->getRAngleLoc()); } return true; } - WalkUpFrom(VarDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Variable) - .addDefinitionElseDeclaration(node->isThisDeclarationADefinition()) - .addConstexpr(node->isConstexpr()) - .addInline(node->isInline()) - .addStatic(node->isStaticDataMember()) - .addLocal(node->isLocalVarDecl()); + VISIT(ClassTemplatePartialSpecializationDecl) { + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } return true; } - WalkUpFrom(FunctionDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Function) - .addDefinitionElseDeclaration(node->isThisDeclarationADefinition()) - .addConstexpr(node->isConstexpr()) - .addConsteval(node->isConsteval()) - .addVirtual(node->isVirtualAsWritten()) - .addPureVirtual(node->isPureVirtual()) - .addInline(node->isInlined()); - return true; - } - return false; - } - - WalkUpFrom(CXXMethodDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Method) - .addDefinitionElseDeclaration(node->isThisDeclarationADefinition()) - .addConstexpr(node->isConstexpr()) - .addConsteval(node->isConsteval()) - .addVirtual(node->isVirtualAsWritten()) - .addPureVirtual(node->isPureVirtual()) - .addInline(node->isInlined()); - return true; - } - return false; - } - - WalkUpFrom(ParmVarDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Parameter) - .addDefinitionElseDeclaration(node->isThisDeclarationADefinition()) - .addConst(node->isConstexpr()) - .addLocal(node->isLocalVarDecl()); + VISIT(VarTemplateSpecializationDecl) { + if(auto args = node->getTemplateArgsAsWritten()) { + addAngle(args->LAngleLoc, args->RAngleLoc); } return true; } - WalkUpFrom(TemplateTypeParmDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::TypeTemplateParameter); + VISIT(VarTemplatePartialSpecializationDecl) { + if(auto params = node->getTemplateParameters()) { + addAngle(params->getLAngleLoc(), params->getRAngleLoc()); } return true; } - WalkUpFrom(NonTypeTemplateParmDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::NonTypeTemplateParameter).addConstexpr(true); - } + VISIT(CXXNamedCastExpr) { + addAngle(node->getAngleBrackets().getBegin(), node->getAngleBrackets().getEnd()); return true; } - WalkUpFrom(TemplateTemplateParmDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::TemplateTemplateParameter); - } + VISIT(OverloadExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); return true; } - WalkUpFrom(ClassTemplateDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::ClassTemplate); - } + VISIT(CXXDependentScopeMemberExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); return true; } - WalkUpFrom(VarTemplateDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::VariableTemplate); - } + VISIT(DependentScopeDeclRefExpr) { + addAngle(node->getLAngleLoc(), node->getRAngleLoc()); return true; } - WalkUpFrom(FunctionTemplateDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::FunctionTemplate); - } + VISIT_TYPE(TemplateSpecializationTypeLoc) { + addAngle(node.getLAngleLoc(), node.getRAngleLoc()); return true; } - WalkUpFrom(ConceptDecl) { - if(auto token = collector.lookup(node->getLocation())) { - token->setType(SemanticTokenTypes::Concept); - } + VISIT_TYPE(DependentTemplateSpecializationTypeLoc) { + addAngle(node.getLAngleLoc(), node.getRAngleLoc()); return true; } - - WalkUpFrom(Stmt) { return collector.isInMainFile(node->getBeginLoc()); } - - WalkUpFrom(Expr) { return collector.isInMainFile(node->getBeginLoc()); } - - WalkUpFrom(DeclRefExpr) {} - - WalkUpFrom(MemberExpr) {} - - WalkUpFrom(Attr) { - // auto location = node->getLocation(); - // if(collector.isInMainFile(location)) { - // collector.attach(location, SemanticTokenTypes::Attribute, 0); - // return true; - // } - return false; - } - -#undef VISIT }; -protocol::SemanticTokens semanticTokens(const ParsedAST& ast) {} +#undef Traverse; +#undef WalkUpFrom; +#undef VISIT; -} // namespace clice +} // namespace clice::feature diff --git a/src/Feature/SemanticToken2.cpp b/src/Feature/SemanticToken2.cpp deleted file mode 100644 index 92d3ca7e..00000000 --- a/src/Feature/SemanticToken2.cpp +++ /dev/null @@ -1,269 +0,0 @@ -#include -#include - -namespace clice::feature { - -#define Traverse(NAME) bool Traverse##NAME(clang::NAME* node) -#define WalkUpFrom(NAME) bool WalkUpFrom##NAME(clang::NAME* node) -#define VISIT(NAME) bool Visit##NAME(clang::NAME* node) - -using protocol::SemanticTokenType; -using protocol::SemanticTokenModifier; - -class SemanticToken { -private: - clang::SourceRange range; - SemanticTokenType type; - uint32_t modifiers; - -private: - -public: - SemanticToken(SemanticTokenType type, clang::SourceLocation begin, clang::SourceLocation end) : - range(begin, end), type(type), modifiers(0) {} - - SemanticToken(SemanticTokenType type, const clang::syntax::Token& token) : - range(token.location(), token.endLocation()), type(type), modifiers(0) {} - - SemanticToken& addModifier(SemanticTokenModifier modifier) { - modifiers |= (static_cast>(modifier) << 1); - return *this; - } - - // SemanticToken& add() { int x = 1; } -}; - -class HighlightCollector : clang::RecursiveASTVisitor { -private: - clang::ASTContext& context; - clang::Preprocessor& preprocessor; - clang::SourceManager& sourceManager; - clang::syntax::TokenBuffer& tokenBuffer; - std::vector tokens; - -public: - HighlightCollector(ParsedAST& AST) : - context(AST.ASTContext()), preprocessor(AST.Preprocessor()), - sourceManager(AST.SourceManager()), tokenBuffer(AST.TokenBuffer()) {} - - std::vector collect() && { - - // highlight tokens directly from token buffer. - // mainly about directives, macros, keywords, comments, operators, and literals. - TraverseTokens(); - - // highlight tokens from AST. - // mainly about types, functions, variables and namespaces. - TraverseTranslationUnitDecl(context.getTranslationUnitDecl()); - - return std::move(tokens); - } - - void TraverseTokens() { - auto spelledTokens = tokenBuffer.spelledTokens(sourceManager.getMainFileID()); - bool in_directive = false; - bool in_include = false; - for(std::size_t index = 0; index < spelledTokens.size(); ++index) { - auto& current = spelledTokens[index]; - switch(current.kind()) { - case clang::tok::TokenKind::comment: { - tokens.emplace_back(SemanticTokenType::Comment, current); - break; - } - case clang::tok::TokenKind::numeric_constant: { - tokens.emplace_back(SemanticTokenType::Number, current); - break; - } - case clang::tok::TokenKind::char_constant: - case clang::tok::TokenKind::wide_char_constant: - case clang::tok::TokenKind::utf8_char_constant: - case clang::tok::TokenKind::utf16_char_constant: - case clang::tok::TokenKind::utf32_char_constant: { - tokens.emplace_back(SemanticTokenType::Char, current); - break; - } - case clang::tok::TokenKind::string_literal: - case clang::tok::TokenKind::wide_string_literal: - case clang::tok::TokenKind::utf8_string_literal: - case clang::tok::TokenKind::utf16_string_literal: - case clang::tok::TokenKind::utf32_string_literal: { - tokens.emplace_back(SemanticTokenType::String, current); - break; - } - case clang::tok::identifier: { - break; - } - case clang::tok::l_paren: { - tokens.emplace_back(SemanticTokenType::Paren, current) - .addModifier(SemanticTokenModifier::Left); - break; - } - case clang::tok::r_paren: { - tokens.emplace_back(SemanticTokenType::Paren, current) - .addModifier(SemanticTokenModifier::Right); - break; - } - case clang::tok::l_square: { - tokens.emplace_back(SemanticTokenType::Bracket, current) - .addModifier(SemanticTokenModifier::Left); - break; - } - case clang::tok::r_square: { - tokens.emplace_back(SemanticTokenType::Bracket, current) - .addModifier(SemanticTokenModifier::Right); - break; - } - case clang::tok::l_brace: { - tokens.emplace_back(SemanticTokenType::Brace, current) - .addModifier(SemanticTokenModifier::Left); - break; - } - case clang::tok::r_brace: { - tokens.emplace_back(SemanticTokenType::Brace, current) - .addModifier(SemanticTokenModifier::Right); - break; - } - case clang::tok::plus: // + - case clang::tok::plusplus: // ++ - case clang::tok::plusequal: // += - case clang::tok::minus: // - - case clang::tok::minusminus: // -- - case clang::tok::minusequal: // -= - case clang::tok::star: // * - case clang::tok::starequal: // *= - case clang::tok::slash: // / - case clang::tok::slashequal: // /= - case clang::tok::percent: // % - case clang::tok::percentequal: // %= - case clang::tok::amp: // & - case clang::tok::ampamp: // && - case clang::tok::ampequal: // &= - case clang::tok::pipe: // | - case clang::tok::pipepipe: // || - case clang::tok::pipeequal: // |= - case clang::tok::caret: // ^ - case clang::tok::caretequal: // ^= - case clang::tok::exclaim: // ! - case clang::tok::exclaimequal: // != - case clang::tok::equal: // = - case clang::tok::equalequal: // == - { - } - case clang::tok::eod: { - in_directive = false; - break; - } - default: break; - } - } - } - - Traverse(TranslationUnitDecl) { - for(auto decl: node->decls()) { - // we only need to highlight the token in main file. - // so filter out the nodes which are in headers for better performance. - if(sourceManager.isInMainFile(decl->getLocation())) { - TraverseDecl(decl); - } - } - return true; - } - - WalkUpFrom(NamespaceDecl) {} - - // angle - VISIT(DeclaratorDecl) { - for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { - if(auto* TPL = node->getTemplateParameterList(i)) { - TPL->getLAngleLoc().dump(sourceManager); - TPL->getRAngleLoc().dump(sourceManager); - } - } - return true; - } - - VISIT(TagDecl) { - for(unsigned i = 0; i < node->getNumTemplateParameterLists(); ++i) { - if(auto* TPL = node->getTemplateParameterList(i)) { - TPL->getLAngleLoc().dump(sourceManager); - TPL->getRAngleLoc().dump(sourceManager); - } - } - return true; - } - - VISIT(FunctionDecl) { - if(auto* args = node->getTemplateSpecializationArgsAsWritten()) { - auto langle = args->LAngleLoc; - auto rangle = args->RAngleLoc; - } - } - - VISIT(TemplateDecl) { - if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - auto langle = params->getLAngleLoc(); - auto rangle = params->getRAngleLoc(); - } - } - - VISIT(ClassTemplateSpecializationDecl) { - if(const clang::ASTTemplateArgumentListInfo* args = node->getTemplateArgsAsWritten()) { - auto langle = args->getLAngleLoc(); - auto rangle = args->getRAngleLoc(); - } - } - - VISIT(ClassTemplatePartialSpecializationDecl) { - if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - auto langle = params->getLAngleLoc(); - auto rangle = params->getRAngleLoc(); - } - } - - VISIT(VarTemplateSpecializationDecl) { - if(const clang::ASTTemplateArgumentListInfo* args = node->getTemplateArgsAsWritten()) { - auto langle = args->getLAngleLoc(); - auto rangle = args->getRAngleLoc(); - } - } - - VISIT(VarTemplatePartialSpecializationDecl) { - if(clang::TemplateParameterList* params = node->getTemplateParameters()) { - auto langle = params->getLAngleLoc(); - auto rangle = params->getRAngleLoc(); - } - } - - VISIT(TemplateSpecializationTypeLoc) { - auto langle = node->getLAngleLoc(); - auto rangle = node->getRAngleLoc(); - } - - VISIT(DependentTemplateSpecializationTypeLoc) { - auto langle = node->getLAngleLoc(); - auto rangle = node->getRAngleLoc(); - } - - VISIT(CXXNamedCastExpr) { auto langle = node->getAngleBrackets(); } - - VISIT(OverloadExpr) { - auto l = node->getLAngleLoc(); - auto r = node->getRAngleLoc(); - } - - VISIT(CXXDependentScopeMemberExpr) { - auto langle = node->getLAngleLoc(); - auto rangle = node->getRAngleLoc(); - } - - VISIT(DependentScopeDeclRefExpr) { - auto langle = node->getLAngleLoc(); - auto rangle = node->getRAngleLoc(); - } -}; - -#undef Traverse; -#undef WalkUpFrom; -#undef VISIT; - -} // namespace clice::feature diff --git a/test.cpp b/test.cpp index 9198daa5..76babb12 100644 --- a/test.cpp +++ b/test.cpp @@ -1,4 +1,11 @@ -template typename T> +template struct X{ - + void foo(){}; }; + +template<> +void X::foo(){ + +} + +