Skip to content

Commit ed173d2

Browse files
committed
[Scope map] Explicitly model pattern bindings and their initializers.
Consistently model all pattern bindings in the scope map, as well as having specific nodes for their initializers. This provides us with more consistency (the declarations are represented) as well as giving us a scope we can use to extract the DeclContext for a non-local initializer.
1 parent 84b0433 commit ed173d2

File tree

3 files changed

+152
-46
lines changed

3 files changed

+152
-46
lines changed

include/swift/AST/ASTScope.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ enum class ASTScopeKind : uint8_t {
6868
AbstractFunctionDecl,
6969
/// The parameters of a function/initializer/deinitializer.
7070
AbstractFunctionParams,
71+
/// A specific pattern binding.
72+
PatternBinding,
73+
/// The scope introduced for an initializer of a pattern binding.
74+
PatternInitializer,
7175
/// The scope introduced by a particular clause in a pattern binding
7276
/// declaration.
7377
AfterPatternBinding,
@@ -169,7 +173,9 @@ class ASTScope {
169173
unsigned paramIndex;
170174
} abstractFunctionParams;
171175

172-
/// For \c kind == ASTScopeKind::AfterPatternBinding.
176+
/// For \c kind == ASTScopeKind::PatternBinding,
177+
/// \c kind == ASTScopeKind::AfterPatternBinding, or
178+
/// \c kind == ASTScopeKind::PatternInitializer.
173179
struct {
174180
PatternBindingDecl *decl;
175181
unsigned entry;
@@ -287,8 +293,12 @@ class ASTScope {
287293
this->abstractFunctionParams.paramIndex = paramIndex;
288294
}
289295

290-
ASTScope(const ASTScope *parent, PatternBindingDecl *decl, unsigned entry)
291-
: ASTScope(ASTScopeKind::AfterPatternBinding, parent) {
296+
ASTScope(ASTScopeKind kind, const ASTScope *parent, PatternBindingDecl *decl,
297+
unsigned entry)
298+
: ASTScope(kind, parent) {
299+
assert(kind == ASTScopeKind::PatternBinding ||
300+
kind == ASTScopeKind::PatternInitializer ||
301+
kind == ASTScopeKind::AfterPatternBinding);
292302
this->patternBinding.decl = decl;
293303
this->patternBinding.entry = entry;
294304
}

lib/AST/ASTScope.cpp

Lines changed: 111 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ ASTScope::ASTScope(const ASTScope *parent, ArrayRef<ASTScope *> children)
3131
: ASTScope(ASTScopeKind::Preexpanded, parent) {
3232
assert(children.size() > 1 && "Don't use this without multiple nodes");
3333

34-
// Add child nodes.
35-
storedChildren.append(children.begin(), children.end());
34+
// Add child nodes, reparenting them to this node.
35+
storedChildren.reserve(children.size());
36+
for (auto child : children ) {
37+
child->parentAndExpanded.setPointer(this);
38+
storedChildren.push_back(child);
39+
}
3640

3741
// Note that this node has already been expanded.
3842
parentAndExpanded.setInt(true);
@@ -206,22 +210,40 @@ void ASTScope::expand() const {
206210
addChild(child);
207211
break;
208212

209-
case ASTScopeKind::AfterPatternBinding: {
213+
case ASTScopeKind::PatternBinding: {
210214
const auto &patternEntry =
211215
patternBinding.decl->getPatternList()[patternBinding.entry];
212216

213-
// Create a child for the initializer expression, if present.
214-
if (auto child = createIfNeeded(this, patternEntry.getInit()))
215-
addChild(child);
217+
// Create a child for the initializer, if present.
218+
if (patternEntry.getInit())
219+
addChild(new (ctx) ASTScope(ASTScopeKind::PatternInitializer, this,
220+
patternBinding.decl, patternBinding.entry));
216221

217-
// Create children for the variables in the pattern, if needed.
222+
// Create children for the accessors of any variables in the pattern that
223+
// have them.
218224
patternEntry.getPattern()->forEachVariable([&](VarDecl *var) {
219-
if (hasAccessors(var)) {
220-
if (auto varChild = createIfNeeded(this, var))
221-
addChild(varChild);
222-
}
225+
if (hasAccessors(var))
226+
addChild(new (ctx) ASTScope(this, var));
223227
});
224228

229+
// If the pattern binding is in a local context, we nest the remaining
230+
// pattern bindings.
231+
if (patternBinding.decl->getDeclContext()->isLocalContext()) {
232+
addChild(new (ctx) ASTScope(ASTScopeKind::AfterPatternBinding, this,
233+
patternBinding.decl, patternBinding.entry));
234+
}
235+
break;
236+
}
237+
238+
case ASTScopeKind::PatternInitializer:
239+
// Create a child for the initializer expression.
240+
if (auto child =
241+
createIfNeeded(this,
242+
patternBinding.decl->getInit(patternBinding.entry)))
243+
addChild(child);
244+
break;
245+
246+
case ASTScopeKind::AfterPatternBinding: {
225247
// Create a child for the next pattern binding.
226248
if (auto child = createIfNeeded(this, patternBinding.decl))
227249
addChild(child);
@@ -557,6 +579,8 @@ static bool parentDirectDescendedFromLocalDeclaration(const ASTScope *parent,
557579

558580
case ASTScopeKind::Preexpanded:
559581
case ASTScopeKind::SourceFile:
582+
case ASTScopeKind::PatternBinding:
583+
case ASTScopeKind::PatternInitializer:
560584
case ASTScopeKind::AfterPatternBinding:
561585
case ASTScopeKind::BraceStmt:
562586
case ASTScopeKind::ConditionalClause:
@@ -600,6 +624,8 @@ static bool parentDirectDescendedFromAbstractStorageDecl(
600624
case ASTScopeKind::SourceFile:
601625
case ASTScopeKind::TypeOrExtensionBody:
602626
case ASTScopeKind::LocalDeclaration:
627+
case ASTScopeKind::PatternBinding:
628+
case ASTScopeKind::PatternInitializer:
603629
case ASTScopeKind::AfterPatternBinding:
604630
case ASTScopeKind::BraceStmt:
605631
case ASTScopeKind::ConditionalClause:
@@ -642,6 +668,8 @@ static bool parentDirectDescendedFromAbstractFunctionDecl(
642668
case ASTScopeKind::SourceFile:
643669
case ASTScopeKind::TypeOrExtensionBody:
644670
case ASTScopeKind::LocalDeclaration:
671+
case ASTScopeKind::PatternBinding:
672+
case ASTScopeKind::PatternInitializer:
645673
case ASTScopeKind::AfterPatternBinding:
646674
case ASTScopeKind::Accessors:
647675
case ASTScopeKind::BraceStmt:
@@ -738,6 +766,10 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
738766
// These declarations do not introduce scopes.
739767
return nullptr;
740768

769+
case DeclKind::Var:
770+
// Always handled by a pattern-binding declaration.
771+
return nullptr;
772+
741773
case DeclKind::Extension:
742774
return new (ctx) ASTScope(parent, cast<ExtensionDecl>(decl));
743775

@@ -821,24 +853,40 @@ ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Decl *decl) {
821853
}
822854

823855
case DeclKind::PatternBinding: {
824-
// Only pattern bindings in local scope introduce scopes.
825-
if (!inLocalContext) return nullptr;
826-
827-
// If there are no bindings, we're done.
828856
auto patternBinding = cast<PatternBindingDecl>(decl);
829857

830-
// Find the next pattern binding.
831-
unsigned entry = (parent->getKind() == ASTScopeKind::AfterPatternBinding &&
832-
parent->patternBinding.decl == decl)
833-
? parent->patternBinding.entry + 1
834-
: 0;
835-
if (entry < patternBinding->getPatternList().size())
836-
return new (ctx) ASTScope(parent, patternBinding, entry);
858+
// Within a local context, bindings nest.
859+
if (inLocalContext) {
860+
// Find the next pattern binding.
861+
unsigned entry = (parent->getKind() == ASTScopeKind::AfterPatternBinding&&
862+
parent->patternBinding.decl == decl)
863+
? parent->patternBinding.entry + 1
864+
: 0;
865+
if (entry < patternBinding->getPatternList().size())
866+
return new (ctx) ASTScope(ASTScopeKind::PatternBinding, parent,
867+
patternBinding, entry);
837868

838-
return nullptr;
869+
return nullptr;
870+
}
871+
872+
// Elsewhere, explode out the bindings because they're independent.
873+
874+
// Handle a single binding directly.
875+
if (patternBinding->getNumPatternEntries() == 1)
876+
return new (ctx) ASTScope(ASTScopeKind::PatternBinding, parent,
877+
patternBinding, 0);
878+
879+
880+
// Pre-expand when there are multiple bindings.
881+
SmallVector<ASTScope *, 4> bindings;
882+
for (auto entry : range(patternBinding->getNumPatternEntries())) {
883+
bindings.push_back(new (ctx) ASTScope(ASTScopeKind::PatternBinding,
884+
parent, patternBinding, entry));
885+
}
886+
887+
return new (ctx) ASTScope(parent, bindings);
839888
}
840889

841-
case DeclKind::Var:
842890
case DeclKind::Subscript: {
843891
auto asd = cast<AbstractStorageDecl>(decl);
844892
if (hasAccessors(asd))
@@ -1000,6 +1048,8 @@ bool ASTScope::isContinuationScope() const {
10001048
case ASTScopeKind::GenericParams:
10011049
case ASTScopeKind::AbstractFunctionDecl:
10021050
case ASTScopeKind::AbstractFunctionParams:
1051+
case ASTScopeKind::PatternBinding:
1052+
case ASTScopeKind::PatternInitializer:
10031053
case ASTScopeKind::Accessors:
10041054
case ASTScopeKind::BraceStmt:
10051055
case ASTScopeKind::IfStmt:
@@ -1046,6 +1096,7 @@ void ASTScope::enumerateContinuationScopes(
10461096
switch (continuation->getKind()) {
10471097
case ASTScopeKind::Preexpanded:
10481098
case ASTScopeKind::SourceFile:
1099+
case ASTScopeKind::PatternInitializer:
10491100
case ASTScopeKind::IfStmt:
10501101
case ASTScopeKind::RepeatWhileStmt:
10511102
case ASTScopeKind::ForEachStmt:
@@ -1074,6 +1125,7 @@ void ASTScope::enumerateContinuationScopes(
10741125
case ASTScopeKind::AbstractFunctionDecl:
10751126
case ASTScopeKind::AbstractFunctionParams:
10761127
case ASTScopeKind::GenericParams:
1128+
case ASTScopeKind::PatternBinding:
10771129
case ASTScopeKind::AfterPatternBinding:
10781130
case ASTScopeKind::LocalDeclaration:
10791131
case ASTScopeKind::ConditionalClause:
@@ -1128,6 +1180,8 @@ ASTContext &ASTScope::getASTContext() const {
11281180
case ASTScopeKind::AbstractFunctionParams:
11291181
return abstractFunctionParams.decl->getASTContext();
11301182

1183+
case ASTScopeKind::PatternBinding:
1184+
case ASTScopeKind::PatternInitializer:
11311185
case ASTScopeKind::AfterPatternBinding:
11321186
return patternBinding.decl->getASTContext();
11331187

@@ -1230,23 +1284,35 @@ SourceRange ASTScope::getSourceRangeImpl() const {
12301284
auto param = abstractFunctionParams.decl->getParameterList(
12311285
abstractFunctionParams.listIndex)
12321286
->get(abstractFunctionParams.paramIndex);
1233-
// FIXME: getLocForEndOfToken... but I can't use it here.
12341287
return SourceRange(param->getEndLoc(), endLoc);
12351288
}
12361289

1290+
case ASTScopeKind::PatternBinding: {
1291+
const auto &patternEntry =
1292+
patternBinding.decl->getPatternList()[patternBinding.entry];
1293+
1294+
SourceRange range = patternEntry.getSourceRange();
1295+
1296+
// Local pattern bindings cover the entire binding + continuation.
1297+
if (patternBinding.decl->getDeclContext()->isLocalContext()) {
1298+
range.End = getParent()->getSourceRange().End;
1299+
}
1300+
1301+
return range;
1302+
}
1303+
1304+
case ASTScopeKind::PatternInitializer:
1305+
return patternBinding.decl->getInit(patternBinding.entry)->getSourceRange();
1306+
12371307
case ASTScopeKind::AfterPatternBinding: {
12381308
const auto &patternEntry =
12391309
patternBinding.decl->getPatternList()[patternBinding.entry];
1240-
// The scope of the binding begins after the initializer (if there is one);
1241-
// other, after the pattern itself.
1242-
SourceLoc startLoc = patternEntry.getOrigInitRange().End;
1243-
if (startLoc.isInvalid())
1244-
startLoc = patternEntry.getPattern()->getSourceRange().End;
1310+
// The scope of the binding begins at the end of the binding.
1311+
SourceLoc startLoc = patternEntry.getSourceRange().End;
12451312

12461313
// And extends to the end of the parent range.
12471314
return SourceRange(startLoc, getParent()->getSourceRange().End);
12481315
}
1249-
12501316
case ASTScopeKind::BraceStmt:
12511317
// The brace statements that represent closures start their scope at the
12521318
// 'in' keyword, when present.
@@ -1533,6 +1599,20 @@ void ASTScope::print(llvm::raw_ostream &out, unsigned level,
15331599
printRange();
15341600
break;
15351601

1602+
case ASTScopeKind::PatternBinding:
1603+
printScopeKind("PatternBinding");
1604+
printAddress(patternBinding.decl);
1605+
out << " entry " << patternBinding.entry;
1606+
printRange();
1607+
break;
1608+
1609+
case ASTScopeKind::PatternInitializer:
1610+
printScopeKind("PatternInitializer");
1611+
printAddress(patternBinding.decl);
1612+
out << " entry " << patternBinding.entry;
1613+
printRange();
1614+
break;
1615+
15361616
case ASTScopeKind::AfterPatternBinding:
15371617
printScopeKind("AfterPatternBinding");
15381618
printAddress(patternBinding.decl);

0 commit comments

Comments
 (0)