Skip to content

Commit 112e45d

Browse files
authored
Merge pull request #34205 from slavapestov/astscope-source-range-fixes
ASTScope: Pre-compute the right source ranges instead of relying on widening
2 parents 4175a01 + b8cccb1 commit 112e45d

8 files changed

+190
-182
lines changed

include/swift/AST/ASTScope.h

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -966,19 +966,8 @@ class AttachedPropertyWrapperScope final : public ASTScopeImpl {
966966
CustomAttr *attr;
967967
VarDecl *decl;
968968

969-
/// Because we have to avoid request cycles, we approximate the test for an
970-
/// AttachedPropertyWrapper with one based on source location. We might get
971-
/// false positives, that that doesn't hurt anything. However, the result of
972-
/// the conservative source range computation doesn't seem to be stable. So
973-
/// keep the original here, and use it for source range queries.
974-
const SourceRange sourceRangeWhenCreated;
975-
976969
AttachedPropertyWrapperScope(CustomAttr *attr, VarDecl *decl)
977-
: attr(attr), decl(decl),
978-
sourceRangeWhenCreated(attr->getTypeRepr()->getSourceRange()) {
979-
ASTScopeAssert(sourceRangeWhenCreated.isValid(),
980-
"VarDecls must have ranges to be looked-up");
981-
}
970+
: attr(attr), decl(decl) {}
982971
virtual ~AttachedPropertyWrapperScope() {}
983972

984973
protected:
@@ -1093,63 +1082,49 @@ class PatternEntryInitializerScope final : public AbstractPatternEntryScope {
10931082
bool lookupLocalsOrMembers(DeclConsumer) const override;
10941083
};
10951084

1096-
/// The scope introduced by a conditional clause in an if/guard/while
1097-
/// statement.
1098-
/// Since there may be more than one "let foo = ..." in (e.g.) an "if",
1099-
/// we allocate a matrushka of these.
1100-
class ConditionalClauseScope final : public ASTScopeImpl {
1085+
/// The scope introduced by a conditional clause initializer in an
1086+
/// if/while/guard statement.
1087+
class ConditionalClauseInitializerScope final : public ASTScopeImpl {
11011088
public:
1102-
LabeledConditionalStmt *const stmt;
1103-
const unsigned index;
1104-
const SourceLoc endLoc; // cannot get it from the stmt
1105-
1106-
ConditionalClauseScope(LabeledConditionalStmt *stmt, unsigned index,
1107-
SourceLoc endLoc)
1108-
: stmt(stmt), index(index), endLoc(endLoc) {}
1109-
1110-
virtual ~ConditionalClauseScope() {}
1089+
Expr *const initializer;
1090+
const SourceRange bodyRange;
11111091

1112-
protected:
1113-
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
1114-
1115-
private:
1116-
AnnotatedInsertionPoint
1117-
expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);
1118-
1119-
public:
1120-
std::string getClassName() const override;
1121-
1122-
protected:
1123-
void printSpecifics(llvm::raw_ostream &out) const override;
1092+
ConditionalClauseInitializerScope(Expr *initializer)
1093+
: initializer(initializer) {}
11241094

1125-
public:
1095+
virtual ~ConditionalClauseInitializerScope() {}
11261096
SourceRange
11271097
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1098+
std::string getClassName() const override;
11281099

11291100
private:
1130-
ArrayRef<StmtConditionElement> getCond() const;
1131-
const StmtConditionElement &getStmtConditionElement() const;
1101+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
11321102

11331103
protected:
1134-
bool isLabeledStmtLookupTerminator() const override;
1104+
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
1105+
NullablePtr<const ASTScopeImpl> getLookupParent() const override;
11351106
};
11361107

11371108
/// If, while, & guard statements all start with a conditional clause, then some
11381109
/// later part of the statement, (then, body, or after the guard) circumvents
11391110
/// the normal lookup rule to pass the lookup scope into the deepest conditional
11401111
/// clause.
11411112
class ConditionalClausePatternUseScope final : public ASTScopeImpl {
1142-
Pattern *const pattern;
1143-
const SourceLoc startLoc;
1113+
StmtConditionElement sec;
1114+
SourceLoc endLoc;
11441115

11451116
public:
1146-
ConditionalClausePatternUseScope(Pattern *pattern, SourceLoc startLoc)
1147-
: pattern(pattern), startLoc(startLoc) {}
1117+
ConditionalClausePatternUseScope(StmtConditionElement sec, SourceLoc endLoc)
1118+
: sec(sec), endLoc(endLoc) {}
11481119

11491120
SourceRange
11501121
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
11511122
std::string getClassName() const override;
11521123

1124+
private:
1125+
AnnotatedInsertionPoint
1126+
expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);
1127+
11531128
protected:
11541129
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;
11551130
bool lookupLocalsOrMembers(DeclConsumer) const override;
@@ -1214,8 +1189,10 @@ class ClosureParametersScope final : public ASTScopeImpl {
12141189
class TopLevelCodeScope final : public ASTScopeImpl {
12151190
public:
12161191
TopLevelCodeDecl *const decl;
1192+
SourceLoc endLoc;
12171193

1218-
TopLevelCodeScope(TopLevelCodeDecl *e) : decl(e) {}
1194+
TopLevelCodeScope(TopLevelCodeDecl *e, SourceLoc endLoc)
1195+
: decl(e), endLoc(endLoc) {}
12191196
virtual ~TopLevelCodeScope() {}
12201197

12211198
protected:
@@ -1361,7 +1338,7 @@ class LabeledConditionalStmtScope : public AbstractStmtScope {
13611338
protected:
13621339
/// Return the lookupParent required to search these.
13631340
ASTScopeImpl *createNestedConditionalClauseScopes(ScopeCreator &,
1364-
const Stmt *afterConds);
1341+
SourceLoc);
13651342
};
13661343

13671344
class IfStmtScope final : public LabeledConditionalStmtScope {
@@ -1419,28 +1396,24 @@ class GuardStmtScope final : public LabeledConditionalStmtScope {
14191396
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
14201397
};
14211398

1422-
/// A scope after a guard statement that follows lookups into the conditions
1423-
/// Also for:
1424-
/// The insertion point of the last statement of an active clause in an #if
1425-
/// must be the lookup parent
1426-
/// of any following scopes. But the active clause may not be the last clause.
1427-
/// In short, this is another case where the lookup parent cannot follow the same
1428-
/// nesting as the source order. IfConfigUseScope implements this twist. It
1429-
/// follows the IfConfig, wraps all subsequent scopes, and redirects the lookup.
1430-
class LookupParentDiversionScope final : public ASTScopeImpl {
1399+
/// A scope for the body of a guard statement. Lookups from the body must
1400+
/// skip the parent scopes for introducing pattern bindings, since they're
1401+
/// not visible in the guard body, only after the body ends.
1402+
class GuardStmtBodyScope final : public ASTScopeImpl {
14311403
public:
14321404
ASTScopeImpl *const lookupParent;
1433-
const SourceLoc startLoc;
1434-
const SourceLoc endLoc;
1405+
BraceStmt *const body;
14351406

1436-
LookupParentDiversionScope(ASTScopeImpl *lookupParent,
1437-
SourceLoc startLoc, SourceLoc endLoc)
1438-
: lookupParent(lookupParent), startLoc(startLoc), endLoc(endLoc) {}
1407+
GuardStmtBodyScope(ASTScopeImpl *lookupParent, BraceStmt *body)
1408+
: lookupParent(lookupParent), body(body) {}
14391409

14401410
SourceRange
14411411
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
14421412
std::string getClassName() const override;
14431413

1414+
private:
1415+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
1416+
14441417
protected:
14451418
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;
14461419
NullablePtr<const ASTScopeImpl> getLookupParent() const override {
@@ -1672,13 +1645,21 @@ class BraceStmtScope final : public AbstractStmtScope {
16721645
/// definition.
16731646
SmallVector<VarDecl *, 2> localVars;
16741647

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+
16751654
public:
16761655
BraceStmtScope(BraceStmt *e,
16771656
SmallVector<ValueDecl *, 2> localFuncsAndTypes,
1678-
SmallVector<VarDecl *, 2> localVars)
1657+
SmallVector<VarDecl *, 2> localVars,
1658+
SourceLoc endLoc)
16791659
: stmt(e),
16801660
localFuncsAndTypes(localFuncsAndTypes),
1681-
localVars(localVars) {}
1661+
localVars(localVars),
1662+
endLoc(endLoc) {}
16821663
virtual ~BraceStmtScope() {}
16831664

16841665
protected:

lib/AST/ASTScope.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ DEFINE_GET_CLASS_NAME(DefaultArgumentInitializerScope)
137137
DEFINE_GET_CLASS_NAME(AttachedPropertyWrapperScope)
138138
DEFINE_GET_CLASS_NAME(PatternEntryDeclScope)
139139
DEFINE_GET_CLASS_NAME(PatternEntryInitializerScope)
140-
DEFINE_GET_CLASS_NAME(ConditionalClauseScope)
141140
DEFINE_GET_CLASS_NAME(ConditionalClausePatternUseScope)
141+
DEFINE_GET_CLASS_NAME(ConditionalClauseInitializerScope)
142142
DEFINE_GET_CLASS_NAME(CaptureListScope)
143143
DEFINE_GET_CLASS_NAME(ClosureParametersScope)
144144
DEFINE_GET_CLASS_NAME(TopLevelCodeScope)
@@ -149,7 +149,7 @@ DEFINE_GET_CLASS_NAME(EnumElementScope)
149149
DEFINE_GET_CLASS_NAME(IfStmtScope)
150150
DEFINE_GET_CLASS_NAME(WhileStmtScope)
151151
DEFINE_GET_CLASS_NAME(GuardStmtScope)
152-
DEFINE_GET_CLASS_NAME(LookupParentDiversionScope)
152+
DEFINE_GET_CLASS_NAME(GuardStmtBodyScope)
153153
DEFINE_GET_CLASS_NAME(RepeatWhileScope)
154154
DEFINE_GET_CLASS_NAME(DoStmtScope)
155155
DEFINE_GET_CLASS_NAME(DoCatchStmtScope)
@@ -199,15 +199,6 @@ void ASTScopeImpl::postOrderDo(function_ref<void(ASTScopeImpl *)> fn) {
199199
fn(this);
200200
}
201201

202-
ArrayRef<StmtConditionElement> ConditionalClauseScope::getCond() const {
203-
return stmt->getCond();
204-
}
205-
206-
const StmtConditionElement &
207-
ConditionalClauseScope::getStmtConditionElement() const {
208-
return getCond()[index];
209-
}
210-
211202
unsigned ASTScopeImpl::countDescendants() const {
212203
unsigned count = 0;
213204
const_cast<ASTScopeImpl *>(this)->preOrderDo(

0 commit comments

Comments
 (0)