Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions include/swift/AST/ASTWalker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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();
};

Expand Down
4 changes: 3 additions & 1 deletion include/swift/AST/SourceEntityWalker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions include/swift/IDE/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
30 changes: 19 additions & 11 deletions lib/AST/SourceEntityWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class SemaAnnotator : public ASTWalker {
bool passModulePathElements(ArrayRef<ImportDecl::AccessPathElement> 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<Identifier, SourceLoc> IdLoc);

bool passSubscriptReference(ValueDecl *D, SourceLoc Loc, bool IsOpenBracket);
Expand Down Expand Up @@ -211,15 +211,16 @@ std::pair<bool, Expr *> 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<MemberRefExpr>(E)) {
// Visit in source order.
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.
Expand All @@ -229,7 +230,8 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {

} else if (auto OtherCtorE = dyn_cast<OtherConstructorDeclRefExpr>(E)) {
if (!passReference(OtherCtorE->getDecl(), OtherCtorE->getType(),
OtherCtorE->getConstructorLoc()))
OtherCtorE->getConstructorLoc(),
SemaReferenceKind::DeclConstructorRef))
return { false, nullptr };

} else if (SubscriptExpr *SE = dyn_cast<SubscriptExpr>(E)) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -323,7 +326,8 @@ std::pair<bool, Pattern *> 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<TypedPattern>(P);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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<TypeDecl>(D)) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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,
Expand Down
8 changes: 5 additions & 3 deletions lib/IDE/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/Index/Index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
10 changes: 6 additions & 4 deletions tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ static void addParameters(ArrayRef<Identifier> &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),
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<VarDecl>(D) && D->hasName() && D->getName().str() == "self")
return true;

Expand All @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 6 additions & 3 deletions tools/swift-ide-test/swift-ide-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down