Skip to content

Commit dac68ca

Browse files
committed
ASTScope: Fix TopLevelCodeScope source range
Top-level code can contain guard statements which introduce bindings until the end of the parent scope, so plumb that through.
1 parent 2e67c13 commit dac68ca

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

include/swift/AST/ASTScope.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,8 +1189,10 @@ class ClosureParametersScope final : public ASTScopeImpl {
11891189
class TopLevelCodeScope final : public ASTScopeImpl {
11901190
public:
11911191
TopLevelCodeDecl *const decl;
1192+
SourceLoc endLoc;
11921193

1193-
TopLevelCodeScope(TopLevelCodeDecl *e) : decl(e) {}
1194+
TopLevelCodeScope(TopLevelCodeDecl *e, SourceLoc endLoc)
1195+
: decl(e), endLoc(endLoc) {}
11941196
virtual ~TopLevelCodeScope() {}
11951197

11961198
protected:
@@ -1643,13 +1645,21 @@ class BraceStmtScope final : public AbstractStmtScope {
16431645
/// definition.
16441646
SmallVector<VarDecl *, 2> localVars;
16451647

1648+
/// The end location for bindings introduced in this scope. This can
1649+
/// extend past the actual end of the BraceStmt in top-level code,
1650+
/// where every TopLevelCodeDecl introduces a new scope through the
1651+
/// end of the buffer.
1652+
SourceLoc endLoc;
1653+
16461654
public:
16471655
BraceStmtScope(BraceStmt *e,
16481656
SmallVector<ValueDecl *, 2> localFuncsAndTypes,
1649-
SmallVector<VarDecl *, 2> localVars)
1657+
SmallVector<VarDecl *, 2> localVars,
1658+
SourceLoc endLoc)
16501659
: stmt(e),
16511660
localFuncsAndTypes(localFuncsAndTypes),
1652-
localVars(localVars) {}
1661+
localVars(localVars),
1662+
endLoc(endLoc) {}
16531663
virtual ~BraceStmtScope() {}
16541664

16551665
protected:

lib/AST/ASTScopeCreation.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,9 @@ class NodeAdder
662662
NullablePtr<ASTScopeImpl> visitTopLevelCodeDecl(TopLevelCodeDecl *d,
663663
ASTScopeImpl *p,
664664
ScopeCreator &scopeCreator) {
665-
return scopeCreator.ifUniqueConstructExpandAndInsert<TopLevelCodeScope>(p,
666-
d);
665+
ASTScopeAssert(endLoc.hasValue(), "TopLevelCodeDecl in wrong place?");
666+
return scopeCreator.ifUniqueConstructExpandAndInsert<TopLevelCodeScope>(
667+
p, d, *endLoc);
667668
}
668669

669670
#pragma mark special-case creation
@@ -708,9 +709,14 @@ class NodeAdder
708709
}
709710
}
710711

712+
SourceLoc endLocForBraceStmt = bs->getEndLoc();
713+
if (endLoc.hasValue())
714+
endLocForBraceStmt = *endLoc;
715+
711716
auto maybeBraceScope =
712717
scopeCreator.ifUniqueConstructExpandAndInsert<BraceStmtScope>(
713-
p, bs, std::move(localFuncsAndTypes), std::move(localVars));
718+
p, bs, std::move(localFuncsAndTypes), std::move(localVars),
719+
endLocForBraceStmt);
714720
if (auto *s = scopeCreator.getASTContext().Stats)
715721
++s->getFrontendCounters().NumBraceStmtASTScopes;
716722

@@ -989,12 +995,17 @@ ASTSourceFileScope::expandAScopeThatCreatesANewInsertionPoint(
989995
ASTScopeAssert(SF, "Must already have a SourceFile.");
990996
ArrayRef<Decl *> decls = SF->getTopLevelDecls();
991997
// Assume that decls are only added at the end, in source order
998+
Optional<SourceLoc> endLoc = None;
999+
if (!decls.empty())
1000+
endLoc = decls.back()->getEndLoc();
1001+
9921002
std::vector<ASTNode> newNodes(decls.begin(), decls.end());
9931003
insertionPoint =
9941004
scopeCreator.addSiblingsToScopeTree(insertionPoint,
9951005
scopeCreator.sortBySourceRange(
9961006
scopeCreator.cull(newNodes)),
997-
None);
1007+
endLoc);
1008+
9981009
// Too slow to perform all the time:
9991010
// ASTScopeAssert(scopeCreator->containsAllDeclContextsFromAST(),
10001011
// "ASTScope tree missed some DeclContexts or made some up");
@@ -1123,7 +1134,7 @@ BraceStmtScope::expandAScopeThatCreatesANewInsertionPoint(
11231134
scopeCreator.sortBySourceRange(
11241135
scopeCreator.cull(
11251136
stmt->getElements())),
1126-
stmt->getEndLoc());
1137+
endLoc);
11271138
if (auto *s = scopeCreator.getASTContext().Stats)
11281139
++s->getFrontendCounters().NumBraceStmtASTScopeExpansions;
11291140
return {
@@ -1137,7 +1148,7 @@ TopLevelCodeScope::expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &
11371148

11381149
if (auto *body =
11391150
scopeCreator
1140-
.addToScopeTreeAndReturnInsertionPoint(decl->getBody(), this, None)
1151+
.addToScopeTreeAndReturnInsertionPoint(decl->getBody(), this, endLoc)
11411152
.getPtrOrNull())
11421153
return {body, "So next top level code scope and put its decls in its body "
11431154
"under a guard statement scope (etc) from the last top level "

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ SourceRange FunctionBodyScope::getSourceRangeOfThisASTNode(
221221

222222
SourceRange TopLevelCodeScope::getSourceRangeOfThisASTNode(
223223
const bool omitAssertions) const {
224-
return decl->getSourceRange();
224+
return SourceRange(decl->getStartLoc(), endLoc);
225225
}
226226

227227
SourceRange SubscriptDeclScope::getSourceRangeOfThisASTNode(
@@ -401,9 +401,9 @@ BraceStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
401401
// 'in' keyword, when present.
402402
if (auto closure = parentClosureIfAny()) {
403403
if (closure.get()->getInLoc().isValid())
404-
return SourceRange(closure.get()->getInLoc(), stmt->getEndLoc());
404+
return SourceRange(closure.get()->getInLoc(), endLoc);
405405
}
406-
return stmt->getSourceRange();
406+
return SourceRange(stmt->getStartLoc(), endLoc);
407407
}
408408

409409
SourceRange ConditionalClauseInitializerScope::getSourceRangeOfThisASTNode(

0 commit comments

Comments
 (0)