From 14f968a5edc60f90cde49d919bfea677791013b4 Mon Sep 17 00:00:00 2001 From: Xi Ge Date: Tue, 20 Dec 2016 14:29:12 -0800 Subject: [PATCH] SourceEntityWalker: Add a parameter to visitDeclReference() describing the kind of the reference under visit. NFC --- include/swift/AST/ASTWalker.h | 18 ++++++++--- include/swift/AST/SourceEntityWalker.h | 4 ++- include/swift/IDE/Utils.h | 8 +++-- lib/AST/SourceEntityWalker.cpp | 30 ++++++++++++------- lib/IDE/SwiftSourceDocInfo.cpp | 8 +++-- lib/Index/Index.cpp | 3 +- .../lib/SwiftLang/SwiftDocSupport.cpp | 10 ++++--- tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp | 6 ++-- .../lib/SwiftLang/SwiftSourceDocInfo.cpp | 3 +- tools/swift-ide-test/swift-ide-test.cpp | 9 ++++-- 10 files changed, 66 insertions(+), 33 deletions(-) diff --git a/include/swift/AST/ASTWalker.h b/include/swift/AST/ASTWalker.h index 932d0ea41cf69..ad2507671f14f 100644 --- a/include/swift/AST/ASTWalker.h +++ b/include/swift/AST/ASTWalker.h @@ -27,6 +27,16 @@ class TypeRepr; struct TypeLoc; class ParameterList; +enum class SemaReferenceKind : uint8_t { + ModuleRef = 0, + DeclRef, + DeclMemberRef, + DeclConstructorRef, + TypeRef, + EnumElementRef, + SubscriptRef, +}; + /// \brief An abstract class used to traverse an AST. class ASTWalker { public: @@ -188,18 +198,18 @@ class ASTWalker { /// the subtree is skipped. /// virtual bool walkToParameterListPre(ParameterList *PL) { return true; } - + /// walkToParameterListPost - This method is called after visiting the /// children of a parameter list. If it returns false, the remaining /// traversal is terminated and returns failure. virtual bool walkToParameterListPost(ParameterList *PL) { return true; } - - + + protected: ASTWalker() = default; ASTWalker(const ASTWalker &) = default; virtual ~ASTWalker() = default; - + virtual void anchor(); }; diff --git a/include/swift/AST/SourceEntityWalker.h b/include/swift/AST/SourceEntityWalker.h index e936d116f1894..773ee2b44a766 100644 --- a/include/swift/AST/SourceEntityWalker.h +++ b/include/swift/AST/SourceEntityWalker.h @@ -13,6 +13,7 @@ #ifndef SWIFT_AST_SOURCE_ENTITY_WALKER_H #define SWIFT_AST_SOURCE_ENTITY_WALKER_H +#include "swift/AST/ASTWalker.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/PointerUnion.h" @@ -86,7 +87,8 @@ class SourceEntityWalker { /// \c ConstructorDecl, to point to the type declaration that the source /// refers to. virtual bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T); + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind); /// This method is called when a ValueDecl for a subscript is referenced in /// source. If it returns false, the remaining traversal is terminated diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h index 543150307514a..64dae981915aa 100644 --- a/include/swift/IDE/Utils.h +++ b/include/swift/IDE/Utils.h @@ -59,7 +59,7 @@ struct SourceCompleteResult { // prefix will contain the leading space characters of the line that // contained the '{', '(' or '[' character that was unbalanced. std::string IndentPrefix; - // Returns the indent level as an indentation count (number of indentations + // Returns the indent level as an indentation count (number of indentations // to apply). Clients can translate this into the standard indentation that // is being used by the IDE (3 spaces? 1 tab?) and should use the indent // prefix string followed by the correct indentation. @@ -181,7 +181,8 @@ class SemaLocResolver : public SourceEntityWalker { bool walkToStmtPre(Stmt *S) override; bool walkToStmtPost(Stmt *S) override; bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override; + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override; bool visitCallArgName(Identifier Name, CharSourceRange Range, ValueDecl *D) override; bool visitModuleReference(ModuleEntity Mod, CharSourceRange Range) override; @@ -239,7 +240,8 @@ class RangeResolver : public SourceEntityWalker { bool walkToDeclPre(Decl *D, CharSourceRange Range) override; bool walkToDeclPost(Decl *D) override; bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override; + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override; public: RangeResolver(SourceFile &File, SourceLoc Start, SourceLoc End); RangeResolver(SourceFile &File, unsigned Offset, unsigned Length); diff --git a/lib/AST/SourceEntityWalker.cpp b/lib/AST/SourceEntityWalker.cpp index 8fedcb1ab3b13..bda3aa7e5a066 100644 --- a/lib/AST/SourceEntityWalker.cpp +++ b/lib/AST/SourceEntityWalker.cpp @@ -60,7 +60,7 @@ class SemaAnnotator : public ASTWalker { bool passModulePathElements(ArrayRef Path, const clang::Module *ClangMod); - bool passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc); + bool passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc, SemaReferenceKind Kind); bool passReference(ModuleEntity Mod, std::pair IdLoc); bool passSubscriptReference(ValueDecl *D, SourceLoc Loc, bool IsOpenBracket); @@ -211,7 +211,8 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { std::make_pair(module->getName(), E->getLoc()))) return { false, nullptr }; } else if (!passReference(DRE->getDecl(), DRE->getType(), - DRE->getNameLoc())) { + DRE->getNameLoc(), + SemaReferenceKind::DeclRef)) { return { false, nullptr }; } } else if (MemberRefExpr *MRE = dyn_cast(E)) { @@ -219,7 +220,7 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { if (!MRE->getBase()->walk(*this)) return { false, nullptr }; if (!passReference(MRE->getMember().getDecl(), MRE->getType(), - MRE->getNameLoc())) + MRE->getNameLoc(), SemaReferenceKind::DeclMemberRef)) return { false, nullptr }; // We already visited the children. @@ -229,7 +230,8 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { } else if (auto OtherCtorE = dyn_cast(E)) { if (!passReference(OtherCtorE->getDecl(), OtherCtorE->getType(), - OtherCtorE->getConstructorLoc())) + OtherCtorE->getConstructorLoc(), + SemaReferenceKind::DeclConstructorRef)) return { false, nullptr }; } else if (SubscriptExpr *SE = dyn_cast(E)) { @@ -293,7 +295,8 @@ bool SemaAnnotator::walkToTypeReprPre(TypeRepr *T) { return passReference(ModD, std::make_pair(IdT->getIdentifier(), IdT->getIdLoc())); - return passReference(VD, Type(), DeclNameLoc(IdT->getIdLoc())); + return passReference(VD, Type(), DeclNameLoc(IdT->getIdLoc()), + SemaReferenceKind::TypeRef); } } return true; @@ -323,7 +326,8 @@ std::pair SemaAnnotator::walkToPatternPre(Pattern *P) { if (!Element) return { true, P }; Type T = EP->hasType() ? EP->getType() : Type(); - return { passReference(Element, T, DeclNameLoc(EP->getLoc())), P }; + return { passReference(Element, T, DeclNameLoc(EP->getLoc()), + SemaReferenceKind::EnumElementRef), P }; } auto *TP = dyn_cast(P); @@ -353,7 +357,8 @@ bool SemaAnnotator::handleImports(ImportDecl *Import) { auto Decls = Import->getDecls(); if (Decls.size() == 1) { // FIXME: ImportDecl should store a DeclNameLoc. - if (!passReference(Decls.front(), Type(), DeclNameLoc(Import->getEndLoc()))) + if (!passReference(Decls.front(), Type(), DeclNameLoc(Import->getEndLoc()), + SemaReferenceKind::DeclRef)) return false; } @@ -385,7 +390,8 @@ bool SemaAnnotator::passSubscriptReference(ValueDecl *D, SourceLoc Loc, return Continue; } -bool SemaAnnotator::passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc) { +bool SemaAnnotator:: +passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc, SemaReferenceKind Kind) { TypeDecl *CtorTyRef = nullptr; if (TypeDecl *TD = dyn_cast(D)) { @@ -401,7 +407,7 @@ bool SemaAnnotator::passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc) { CharSourceRange Range = Lexer::getCharSourceRangeFromSourceRange(D->getASTContext().SourceMgr, Loc.getSourceRange()); - bool Continue = SEWalker.visitDeclReference(D, Range, CtorTyRef, Ty); + bool Continue = SEWalker.visitDeclReference(D, Range, CtorTyRef, Ty, Kind); if (!Continue) Cancelled = true; return Continue; @@ -475,7 +481,8 @@ bool SourceEntityWalker::walk(DeclContext *DC) { } bool SourceEntityWalker::visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) { return true; } @@ -485,7 +492,8 @@ bool SourceEntityWalker::visitSubscriptReference(ValueDecl *D, // Most of the clients treat subscript reference the same way as a // regular reference when called on the open bracket and // ignore the closing one. - return IsOpenBracket ? visitDeclReference(D, Range, nullptr, Type()) : true; + return IsOpenBracket ? visitDeclReference(D, Range, nullptr, Type(), + SemaReferenceKind::SubscriptRef) : true; } bool SourceEntityWalker::visitCallArgName(Identifier Name, diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp index e7274626fceab..0989c771a3178 100644 --- a/lib/IDE/SwiftSourceDocInfo.cpp +++ b/lib/IDE/SwiftSourceDocInfo.cpp @@ -93,7 +93,8 @@ bool SemaLocResolver::tryResolve(ModuleEntity Mod, SourceLoc Loc) { bool SemaLocResolver::visitSubscriptReference(ValueDecl *D, CharSourceRange Range, bool IsOpenBracket) { // We should treat both open and close brackets equally - return visitDeclReference(D, Range, nullptr, Type()); + return visitDeclReference(D, Range, nullptr, Type(), + SemaReferenceKind::SubscriptRef); } SemaToken SemaLocResolver::resolve(SourceLoc Loc) { @@ -146,7 +147,8 @@ bool SemaLocResolver::walkToStmtPost(Stmt *S) { } bool SemaLocResolver::visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) { if (isDone()) return false; return !tryResolve(D, CtorTyRef, Range.getStart(), /*IsRef=*/true, T); @@ -506,7 +508,7 @@ bool RangeResolver::walkToDeclPost(Decl *D) { bool RangeResolver:: visitDeclReference(ValueDecl *D, CharSourceRange Range, TypeDecl *CtorTyRef, - Type T) { + Type T, SemaReferenceKind Kind) { Impl->analyzeDeclRef(D, Range, T); return true; } diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp index 0292e7dafe12a..1c2c88a14e46f 100644 --- a/lib/Index/Index.cpp +++ b/lib/Index/Index.cpp @@ -247,7 +247,8 @@ class IndexSwiftASTWalker : public SourceEntityWalker { } bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override { SourceLoc Loc = Range.getStart(); if (CtorTyRef) if (!reportRef(CtorTyRef, Loc)) diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp index f3bebbaf18b83..42cea1ed50d58 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp @@ -759,7 +759,7 @@ static void addParameters(ArrayRef &ArgNames, TypeRange = InOutTyR->getBase()->getSourceRange(); if (TypeRange.isInvalid()) continue; - + unsigned StartOffs = SM.getLocOffsetInBuffer(TypeRange.Start, BufferID); unsigned EndOffs = SM.getLocOffsetInBuffer(Lexer::getLocForEndOfToken(SM, TypeRange.End), @@ -927,7 +927,7 @@ static bool reportModuleDocInfo(CompilerInvocation Invocation, if (makeParserAST(ParseCI, IFaceInfo.Text)) return true; addParameterEntities(ParseCI, IFaceInfo); - + Consumer.handleSourceText(IFaceInfo.Text); reportDocEntities(Ctx, IFaceInfo.TopEntities, Consumer); reportSourceAnnotations(IFaceInfo, ParseCI, Consumer); @@ -977,7 +977,8 @@ class SourceDocASTWalker : public SourceEntityWalker { } bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type Ty) override { + TypeDecl *CtorTyRef, Type Ty, + SemaReferenceKind Kind) override { unsigned StartOffset = getOffset(Range.getStart()); References.emplace_back(D, StartOffset, Range.getByteLength(), Ty); return true; @@ -986,7 +987,8 @@ class SourceDocASTWalker : public SourceEntityWalker { bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range, bool IsOpenBracket) override { // Treat both open and close brackets equally - return visitDeclReference(D, Range, nullptr, Type()); + return visitDeclReference(D, Range, nullptr, Type(), + SemaReferenceKind::SubscriptRef); } bool isLocal(Decl *D) const { diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp index 714d4cd014243..ae44fa1fe5def 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp @@ -771,7 +771,8 @@ class SemanticAnnotator : public SourceEntityWalker { : SM(SM), BufferID(BufferID) {} bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override { if (isa(D) && D->hasName() && D->getName().str() == "self") return true; @@ -788,7 +789,8 @@ class SemanticAnnotator : public SourceEntityWalker { bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range, bool IsOpenBracket) override { // We should treat both open and close brackets equally - return visitDeclReference(D, Range, nullptr, Type()); + return visitDeclReference(D, Range, nullptr, Type(), + SemaReferenceKind::SubscriptRef); } void annotate(const Decl *D, bool IsRef, CharSourceRange Range) { diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp index 30b29178e63af..11fdc9907b8d9 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp @@ -1367,7 +1367,8 @@ class RelatedIdScanner : public SourceEntityWalker { return true; } bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override { if (Cancelled) return false; if (CtorTyRef) diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index e935fb3b7f6af..81663f93d635c 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -1147,14 +1147,16 @@ class AnnotationPrinter : public SourceEntityWalker { } bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type Ty) override { + TypeDecl *CtorTyRef, Type Ty, + SemaReferenceKind Kind) override { annotateSourceEntity({ Range, D, CtorTyRef, /*IsRef=*/true }); return true; } bool visitSubscriptReference(ValueDecl *D, CharSourceRange Range, bool IsOpenBracket) override { - return visitDeclReference(D, Range, nullptr, Type()); + return visitDeclReference(D, Range, nullptr, Type(), + SemaReferenceKind::SubscriptRef); } bool visitCallArgName(Identifier Name, CharSourceRange Range, @@ -2545,7 +2547,8 @@ class TypeReconstructWalker : public SourceEntityWalker { } bool visitDeclReference(ValueDecl *D, CharSourceRange Range, - TypeDecl *CtorTyRef, Type T) override { + TypeDecl *CtorTyRef, Type T, + SemaReferenceKind Kind) override { if (SeenDecls.insert(D).second) tryDemangleDecl(D, Range, /*isRef=*/true);