This commit is contained in:
David Ungar
2019-06-09 14:51:39 -07:00
parent c4322de196
commit 22d37eccd8
3 changed files with 192 additions and 269 deletions

View File

@@ -204,6 +204,11 @@ private:
// identifer within one of them. So, find the real source range of them here. // identifer within one of them. So, find the real source range of them here.
SourceRange getEffectiveSourceRange(ASTNode) const; SourceRange getEffectiveSourceRange(ASTNode) const;
/// Since source ranges are cached but depend on child ranges,
/// when descendants are added, my and my ancestor ranges must be
/// recalculated.
void ensureSourceRangesAreCorrectWhenAddingDescendants(function_ref<void()>);
public: // public for debugging public: // public for debugging
virtual SourceRange getChildlessSourceRange() const = 0; virtual SourceRange getChildlessSourceRange() const = 0;
@@ -253,7 +258,7 @@ public:
// contribute to widenSourceRangeForIgnoredASTNode. // contribute to widenSourceRangeForIgnoredASTNode.
// Closures and captures are also created directly but are // Closures and captures are also created directly but are
// screened out because they are expressions. // screened out because they are expressions.
static bool isCreatedDirectly(const ASTNode n); static bool isHandledSpeciallyByPatterns(const ASTNode n);
virtual NullablePtr<AbstractStorageDecl> virtual NullablePtr<AbstractStorageDecl>
getEnclosingAbstractStorageDecl() const; getEnclosingAbstractStorageDecl() const;
@@ -261,8 +266,9 @@ public:
#pragma mark - - creation queries #pragma mark - - creation queries
protected: protected:
/// In other words, does this scope introduce a new definition /// In other words, does this scope introduce a new definition
bool areDeferredNodesInANewScope() const { bool doISplitAScope() const {
// After an abstract storage decl, what was declared is now accessible. // Before an abstract storage decl, the decl is inaccessible.
// After an abstract storage decl, it is now accessible.
return isThisAnAbstractStorageDecl(); return isThisAnAbstractStorageDecl();
} }
public: public:
@@ -403,6 +409,11 @@ public:
SourceFile *const SF; SourceFile *const SF;
ScopeCreator *const scopeCreator; ScopeCreator *const scopeCreator;
/// The number of \c Decls in the \c SourceFile that were already seen.
/// Since parsing can be interleaved with type-checking, on every
/// lookup, look at creating scopes for any \c Decls beyond this number.
int numberOfDeclsAlreadySeen = 0;
ASTSourceFileScope(SourceFile *SF, ScopeCreator *scopeCreator) ASTSourceFileScope(SourceFile *SF, ScopeCreator *scopeCreator)
: SF(SF), scopeCreator(scopeCreator) {} : SF(SF), scopeCreator(scopeCreator) {}
@@ -417,11 +428,13 @@ public:
return NullablePtr<DeclContext>(SF); return NullablePtr<DeclContext>(SF);
} }
void addNewDeclsToTree();
const SourceFile *getSourceFile() const override; const SourceFile *getSourceFile() const override;
NullablePtr<const void> addressForPrinting() const override { return SF; } NullablePtr<const void> addressForPrinting() const override { return SF; }
protected: protected:
NullablePtr<ASTScopeImpl> expandMe(ScopeCreator &) override; void expandNonSplittingMe(ScopeCreator &) override;
}; };
class Portion { class Portion {
@@ -602,7 +615,7 @@ public:
NullablePtr<const ASTScopeImpl> getLookupLimitForDecl() const override; NullablePtr<const ASTScopeImpl> getLookupLimitForDecl() const override;
void createBodyScope(ASTScopeImpl *leaf, ScopeCreator &) override; void createBodyScope(ASTScopeImpl *leaf, ScopeCreator &) override;
ASTScopeImpl *createTrailingWhereClauseScope(ASTScopeImpl *parent, void createTrailingWhereClauseScope(ASTScopeImpl *parent,
ScopeCreator &) override; ScopeCreator &) override;
}; };
@@ -620,7 +633,7 @@ public:
NullablePtr<NominalTypeDecl> getCorrespondingNominalTypeDecl() const override; NullablePtr<NominalTypeDecl> getCorrespondingNominalTypeDecl() const override;
std::string declKindName() const override { return "Extension"; } std::string declKindName() const override { return "Extension"; }
SourceRange getBraces() const override; SourceRange getBraces() const override;
ASTScopeImpl *createTrailingWhereClauseScope(ASTScopeImpl *parent, void createTrailingWhereClauseScope(ASTScopeImpl *parent,
ScopeCreator &) override; ScopeCreator &) override;
void createBodyScope(ASTScopeImpl *leaf, ScopeCreator &) override; void createBodyScope(ASTScopeImpl *leaf, ScopeCreator &) override;
NullablePtr<Decl> getDecl() const override { return decl; } NullablePtr<Decl> getDecl() const override { return decl; }
@@ -634,7 +647,7 @@ public:
virtual ~TypeAliasScope() {} virtual ~TypeAliasScope() {}
std::string declKindName() const override { return "TypeAlias"; } std::string declKindName() const override { return "TypeAlias"; }
ASTScopeImpl *createTrailingWhereClauseScope(ASTScopeImpl *parent, void createTrailingWhereClauseScope(ASTScopeImpl *parent,
ScopeCreator &) override; ScopeCreator &) override;
GenericContext *getGenericContext() const override { return decl; } GenericContext *getGenericContext() const override { return decl; }
NullablePtr<Decl> getDecl() const override { return decl; } NullablePtr<Decl> getDecl() const override { return decl; }
@@ -893,6 +906,8 @@ public:
NullablePtr<ASTScopeImpl> expandMe(ScopeCreator &) override; NullablePtr<ASTScopeImpl> expandMe(ScopeCreator &) override;
std::string getClassName() const override; std::string getClassName() const override;
SourceRange getChildlessSourceRange() const override; SourceRange getChildlessSourceRange() const override;
static bool isHandledSpecially(const ASTNode n);
}; };
class PatternEntryInitializerScope final : public AbstractPatternEntryScope { class PatternEntryInitializerScope final : public AbstractPatternEntryScope {
@@ -952,9 +967,6 @@ public:
/// The statement after the conditions: body or then. /// The statement after the conditions: body or then.
Stmt *const stmtAfterAllConditions; Stmt *const stmtAfterAllConditions;
/// The next deepest, if any
NullablePtr<ConditionalClauseScope> nextConditionalClause;
NullablePtr<StatementConditionElementPatternScope> NullablePtr<StatementConditionElementPatternScope>
statementConditionElementPatternScope; statementConditionElementPatternScope;
@@ -977,10 +989,6 @@ public:
void createSubtreeForCondition(ScopeCreator &); void createSubtreeForCondition(ScopeCreator &);
SourceLoc startLocAccordingToCondition() const; SourceLoc startLocAccordingToCondition() const;
ASTScopeImpl *findInnermostConditionScope();
ConditionalClauseScope *findDeepestConditionalClauseScope();
NullablePtr<StatementConditionElementPatternScope> NullablePtr<StatementConditionElementPatternScope>
getStatementConditionElementPatternScope() const; getStatementConditionElementPatternScope() const;
SourceRange getChildlessSourceRange() const override; SourceRange getChildlessSourceRange() const override;

View File

@@ -39,29 +39,14 @@ namespace ast_scope {
#pragma mark ScopeCreator #pragma mark ScopeCreator
class ScopeCreator final { class ScopeCreator final {
friend class ASTSourceFileScope;
/// For allocating scopes. /// For allocating scopes.
ASTContext &ctx; ASTContext &ctx;
/// \c SourceFiles and \c BraceStmts have \c Decls and \c ASTNodes in them
/// that must be scoped in distant descendants. As scopes are created, pass
/// down the \c ASTNodes in enclosing \c Decls that really need to be in
/// subscopes.
///
/// /// The nodes that must be passed down to deeper levels in the scope
/// tree.
/// In reverse order!
std::vector<ASTNode> deferredNodesInReverse;
/// The number of \c Decls in the \c SourceFile that were already seen.
/// Since parsing can be interleaved with type-checking, on every
/// lookup, look at creating scopes for any \c Decls beyond this number.
int numberOfDeclsAlreadySeen = 0;
public: public:
ASTSourceFileScope *const sourceFileScope; ASTSourceFileScope *const sourceFileScope;
private: private:
/// The last scope to "adopt" deferred nodes.
/// When adding \c Decls to a scope tree that have been created since the tree /// When adding \c Decls to a scope tree that have been created since the tree
/// was originally built, add them as children of this scope. /// was originally built, add them as children of this scope.
ASTScopeImpl *newNodeInjectionPoint; ASTScopeImpl *newNodeInjectionPoint;
@@ -79,65 +64,36 @@ public:
_astDuplicates(llvm::DenseSet<void *>()), _astDuplicates(llvm::DenseSet<void *>()),
astDuplicates(_astDuplicates.getValue()) {} astDuplicates(_astDuplicates.getValue()) {}
private:
explicit ScopeCreator(ScopeCreator &sc)
: ctx(sc.ctx), sourceFileScope(sc.sourceFileScope),
astDuplicates(sc.astDuplicates) {}
public: public:
~ScopeCreator() {
assert(!haveDeferredNodes() && "Should have consumed all deferred nodes");
}
ScopeCreator(const ScopeCreator &) = delete; // ensure no copies ScopeCreator(const ScopeCreator &) = delete; // ensure no copies
ScopeCreator(const ScopeCreator &&) = delete; // ensure no moves ScopeCreator(const ScopeCreator &&) = delete; // ensure no moves
/// Get a half-copy of me for passing down the tree with its own deferred
/// nodes
ScopeCreator &withoutDeferrals() { return *(new (ctx) ScopeCreator(*this)); }
public: public:
template <typename ClassToConstruct, typename... Args> template <typename ClassToConstruct, typename... Args>
ClassToConstruct *constructInContext(Args... args) { ClassToConstruct *constructInContext(Args... args) {
return new (ctx) ClassToConstruct(args...); return new (ctx) ClassToConstruct(args...);
} }
void addAnyNewScopesToTree() { /// Given an array of ASTNodes or Decl pointers, add them
pushSourceFileDecls(sourceFileScope->SF->Decls); template <typename ASTNode_or_DeclPtr>
if (!haveDeferredNodes()) void addScopesToTree(ArrayRef<ASTNode_or_DeclPtr> nodesOrDeclsToAdd) {
return; // an optimization // Save source range recalculation work if possible
newNodeInjectionPoint->clearCachedSourceRangesOfMeAndAncestors(); if (nodesOrDeclsToAdd.empty())
auto *const sourceRangeFixupPoint = newNodeInjectionPoint; return;
createScopesForDeferredNodes(newNodeInjectionPoint);
sourceRangeFixupPoint->cacheSourceRangesOfSlice(); newNodeInjectionPoint->ensureSourceRangesAreCorrectWhenAddingDescendants(
[&] {
for (auto nd : nodesOrDeclsToAdd) {
if (shouldThisNodeBeScopedWhenEncountered(nd))
newNodeInjectionPoint = createScopeFor(nd, newNodeInjectionPoint);
}
});
} }
public: public:
/// For each deferred node, create scopes as needed and add those scopes as /// Return new insertion point
/// children of the argument.
/// Since nodes added to the source file in the future need to go where
/// deferred ndoes go, remember me as an adopter, too.
void createScopesForDeferredNodes(ASTScopeImpl *parent) {
// If a scope is a home for the deferred nodes,
// it's also the place to add
setNewNodeInjectionPoint(parent);
// more Decls to the SourceFile
while (haveDeferredNodes()) {
Optional<ASTNode> node = popNextDeferredNodeForAdoptionBy(parent);
if (!node)
return;
if (auto declToScope = node->dyn_cast<Decl *>())
createScopeFor(declToScope, parent);
else if (auto stmtToScope = node->dyn_cast<Stmt *>())
createScopeFor(stmtToScope, parent);
else if (auto exprToScope = node->dyn_cast<Expr *>())
createScopeFor(exprToScope, parent);
else
llvm_unreachable("Impossible case");
}
}
template <typename StmtOrExprOrDecl> template <typename StmtOrExprOrDecl>
void createScopeFor(StmtOrExprOrDecl *, ASTScopeImpl *parent); ASTScopeImpl *createScopeFor(StmtOrExprOrDecl *, ASTScopeImpl *parent);
template <typename StmtOrExpr> template <typename StmtOrExpr>
bool shouldCreateScope(StmtOrExpr *n) const { bool shouldCreateScope(StmtOrExpr *n) const {
@@ -214,8 +170,7 @@ public:
// Use the ASTWalker to find buried captures and closures // Use the ASTWalker to find buried captures and closures
forEachUniqueClosureIn(expr, [&](NullablePtr<CaptureListExpr> captureList, forEachUniqueClosureIn(expr, [&](NullablePtr<CaptureListExpr> captureList,
ClosureExpr *closureExpr) { ClosureExpr *closureExpr) {
withoutDeferrals().createSubtree<WholeClosureScope>(parent, closureExpr, createSubtree<WholeClosureScope>(parent, closureExpr, captureList);
captureList);
}); });
} }
@@ -252,8 +207,7 @@ public:
patternBinding->getPattern(0)->forEachVariable([&](VarDecl *vd) { patternBinding->getPattern(0)->forEachVariable([&](VarDecl *vd) {
// assume all same as first // assume all same as first
if (hasCustomAttribute(vd)) if (hasCustomAttribute(vd))
withoutDeferrals().createSubtree<AttachedPropertyWrapperScope>(parent, createSubtree<AttachedPropertyWrapperScope>(parent, vd);
vd);
}); });
} }
@@ -270,8 +224,7 @@ public:
auto *s = parent; auto *s = parent;
for (unsigned i : indices(generics->getParams())) for (unsigned i : indices(generics->getParams()))
if (!isDuplicate(generics->getParams()[i])) { if (!isDuplicate(generics->getParams()[i])) {
s = withoutDeferrals().createSubtree<GenericParamScope>( s = createSubtree<GenericParamScope>(s, parameterizedDecl, generics, i);
s, parameterizedDecl, generics, i);
} }
return s; return s;
} }
@@ -299,23 +252,19 @@ public:
fn(specializeAttr); fn(specializeAttr);
} }
bool haveDeferredNodes() const { return !deferredNodesInReverse.empty(); } bool shouldThisNodeBeScopedWhenEncountered(ASTNode n) {
// Do not scope VarDecls or Accessors when encountered because
void pushIfNecessary(ASTNode n) { // they get created directly by the pattern code.
// Do not defer VarDecls or Accessors because // Doing otherwise distorts the source range
// they get created directly by the pattern code
// and deferring them pushes them to the wrong place.
// Then, even though they're ignored, they distort the source range
// of their parents. // of their parents.
// An optimization; will be ignored later anyway. if (PatternEntryDeclScope::isHandledSpecially(n))
if (ASTScopeImpl::isCreatedDirectly(n)) return false;
return;
if (!astDuplicates.insert(n.getOpaqueValue()).second) if (!astDuplicates.insert(n.getOpaqueValue()).second)
return; return false;
deferredNodesInReverse.push_back(n); return true;
} }
template <typename ASTNodelike> template <typename ASTNodelike>
@@ -324,11 +273,6 @@ public:
pushIfNecessary(nodesToPrepend[i]); pushIfNecessary(nodesToPrepend[i]);
} }
void pushSourceFileDecls(ArrayRef<Decl *> declsToPrepend) {
pushAllNecessaryNodes(declsToPrepend.slice(numberOfDeclsAlreadySeen));
numberOfDeclsAlreadySeen = declsToPrepend.size();
}
bool isDuplicate(void *p, bool registerDuplicate = true) { bool isDuplicate(void *p, bool registerDuplicate = true) {
if (registerDuplicate) if (registerDuplicate)
return !astDuplicates.insert(p).second; return !astDuplicates.insert(p).second;
@@ -336,12 +280,6 @@ public:
} }
private: private:
ASTNode popNextDeferredNodeForAdoptionBy(ASTScopeImpl *s) {
auto f = deferredNodesInReverse.back();
deferredNodesInReverse.pop_back();
return f;
}
// Maintain last adopter so that when we reenter scope tree building // Maintain last adopter so that when we reenter scope tree building
// after the parser has added more decls to the source file, // after the parser has added more decls to the source file,
// we can resume building the scope tree where we left off. // we can resume building the scope tree where we left off.
@@ -356,13 +294,10 @@ public:
void dump() const { print(llvm::errs()); } void dump() const { print(llvm::errs()); }
void print(raw_ostream &out) const { void print(raw_ostream &out) const {
int i = 0; out << "injection point ";
for (auto n : reverse(deferredNodesInReverse)) { newNodeInjectionPoint->print(out);
out << i++ << ": ";
n.dump(out);
out << "\n"; out << "\n";
} }
}
// Make vanilla new illegal for ASTScopes. // Make vanilla new illegal for ASTScopes.
void *operator new(size_t bytes) = delete; void *operator new(size_t bytes) = delete;
@@ -386,13 +321,27 @@ public:
ASTScope *ASTScope::createScopeTreeFor(SourceFile *SF) { ASTScope *ASTScope::createScopeTreeFor(SourceFile *SF) {
ScopeCreator *scopeCreator = new (SF->getASTContext()) ScopeCreator(SF); ScopeCreator *scopeCreator = new (SF->getASTContext()) ScopeCreator(SF);
auto *scope = new (SF->getASTContext()) ASTScope(scopeCreator->sourceFileScope); auto *scope = new (SF->getASTContext()) ASTScope(scopeCreator->sourceFileScope);
scopeCreator->addAnyNewScopesToTree(); scopeCreator->sourceFileScope->addNewDeclsToTree();
return scope; return scope;
} }
void ASTSourceFileScope::addNewDeclsToTree() {
ArrayRef<Decl *> decls = SF->Decls;
ArrayRef<Decl *> newDecls = decls.slice(numberOfDeclsAlreadySeen);
scopeCreator->addScopesToTree(newDecls);
numberOfDeclsAlreadySeen = SF->Decls.size();
}
void ASTScope::addAnyNewScopesToTree() { void ASTScope::addAnyNewScopesToTree() {
assert(impl->SF && impl->scopeCreator); assert(impl->SF && impl->scopeCreator);
impl->scopeCreator->addAnyNewScopesToTree(); impl->scopeCreator->sourceFileScope->addNewDeclsToTree();
}
void ASTScopeImpl::ensureSourceRangesAreCorrectWhenAddingDescendants(
function_ref<void()> modify) {
clearCachedSourceRangesOfMeAndAncestors();
modify();
cacheSourceRangesOfSlice();
} }
#pragma mark ASTVisitorForScopeCreation #pragma mark ASTVisitorForScopeCreation
@@ -401,8 +350,9 @@ namespace swift {
namespace ast_scope { namespace ast_scope {
class ASTVisitorForScopeCreation class ASTVisitorForScopeCreation
: public ASTVisitor<ASTVisitorForScopeCreation, void, void, void, void, : public ASTVisitor<ASTVisitorForScopeCreation, ASTScopeImpl *,
void, void, ASTScopeImpl *, ScopeCreator &> { ASTScopeImpl *, ASTScopeImpl *, void, void, void,
ASTScopeImpl *, ScopeCreator &> {
public: public:
#pragma mark ASTNodes that do not create scopes #pragma mark ASTNodes that do not create scopes
@@ -412,8 +362,9 @@ public:
// accesses such a definition must resolve as being IN the scope. // accesses such a definition must resolve as being IN the scope.
#define VISIT_AND_IGNORE(What) \ #define VISIT_AND_IGNORE(What) \
void visit##What(What *w, ASTScopeImpl *p, ScopeCreator &) { \ ASTScopeImpl *visit##What(What *w, ASTScopeImpl *p, ScopeCreator &) { \
p->widenSourceRangeForIgnoredASTNode(w); \ p->widenSourceRangeForIgnoredASTNode(w); \
return p; \
} }
VISIT_AND_IGNORE(ImportDecl) VISIT_AND_IGNORE(ImportDecl)
@@ -449,8 +400,9 @@ public:
#pragma mark simple creation ignoring deferred nodes #pragma mark simple creation ignoring deferred nodes
#define VISIT_AND_CREATE(What, ScopeClass) \ #define VISIT_AND_CREATE(What, ScopeClass) \
void visit##What(What *w, ASTScopeImpl *p, ScopeCreator &scopeCreator) { \ ASTScopeImpl *visit##What(What *w, ASTScopeImpl *p, \
scopeCreator.withoutDeferrals().createSubtree<ScopeClass>(p, w); \ ScopeCreator &scopeCreator) { \
return scopeCreator.createSubtree<ScopeClass>(p, w); \
} }
VISIT_AND_CREATE(SubscriptDecl, SubscriptDeclScope) VISIT_AND_CREATE(SubscriptDecl, SubscriptDeclScope)
@@ -462,15 +414,6 @@ public:
VISIT_AND_CREATE(ForEachStmt, ForEachStmtScope) VISIT_AND_CREATE(ForEachStmt, ForEachStmtScope)
VISIT_AND_CREATE(CatchStmt, CatchStmtScope) VISIT_AND_CREATE(CatchStmt, CatchStmtScope)
VISIT_AND_CREATE(CaseStmt, CaseStmtScope) VISIT_AND_CREATE(CaseStmt, CaseStmtScope)
// Why don't AbstractFunctionDeclScopes inherit deferred nodes and thereby
// create a subscope in which they are visible?
// Consider:
// func f() { func g() {h()}; func h() { g(); }
// In Swift local functions can be mutually recursive!
// So, instead of subscopes, we put the AbstractFunctionDeclScope's for
// g and h in the same BraceStmtScope and get the local binding mechanism find
// them.
VISIT_AND_CREATE(AbstractFunctionDecl, AbstractFunctionDeclScope) VISIT_AND_CREATE(AbstractFunctionDecl, AbstractFunctionDeclScope)
#undef VISIT_AND_CREATE #undef VISIT_AND_CREATE
@@ -478,8 +421,9 @@ public:
#pragma mark 2D simple creation (ignoring deferred nodes) #pragma mark 2D simple creation (ignoring deferred nodes)
#define VISIT_AND_CREATE_WHOLE_PORTION(What, WhatScope) \ #define VISIT_AND_CREATE_WHOLE_PORTION(What, WhatScope) \
void visit##What(What *w, ASTScopeImpl *p, ScopeCreator &scopeCreator) { \ ASTScopeImpl *visit##What(What *w, ASTScopeImpl *p, \
scopeCreator.withoutDeferrals() \ ScopeCreator &scopeCreator) { \
return scopeCreator \
.createSubtree2D<WhatScope, GenericTypeOrExtensionWholePortion>(p, w); \ .createSubtree2D<WhatScope, GenericTypeOrExtensionWholePortion>(p, w); \
} }
@@ -491,10 +435,10 @@ public:
VISIT_AND_CREATE_WHOLE_PORTION(OpaqueTypeDecl, OpaqueTypeScope) VISIT_AND_CREATE_WHOLE_PORTION(OpaqueTypeDecl, OpaqueTypeScope)
#undef VISIT_AND_CREATE_WHOLE_PORTION #undef VISIT_AND_CREATE_WHOLE_PORTION
void visitProtocolDecl(ProtocolDecl *e, ASTScopeImpl *p, ASTScopeImpl *visitProtocolDecl(ProtocolDecl *e, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
e->createGenericParamsIfMissing(); e->createGenericParamsIfMissing();
scopeCreator.withoutDeferrals() return scopeCreator
.createSubtree2D<NominalTypeScope, GenericTypeOrExtensionWholePortion>( .createSubtree2D<NominalTypeScope, GenericTypeOrExtensionWholePortion>(
p, e); p, e);
} }
@@ -504,44 +448,45 @@ public:
// Each of the following creates a new scope, so that nodes which were parsed // Each of the following creates a new scope, so that nodes which were parsed
// after them need to be placed in scopes BELOW them in the tree. So pass down // after them need to be placed in scopes BELOW them in the tree. So pass down
// the deferred nodes. // the deferred nodes.
void visitGuardStmt(GuardStmt *e, ASTScopeImpl *p, ASTScopeImpl *visitGuardStmt(GuardStmt *e, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
scopeCreator.createSubtree<GuardStmtScope>(p, e); return scopeCreator.createSubtree<GuardStmtScope>(p, e);
} }
void visitDoStmt(DoStmt *ds, ASTScopeImpl *p, ScopeCreator &scopeCreator) { ASTScopeImpl *visitDoStmt(DoStmt *ds, ASTScopeImpl *p,
scopeCreator.createScopeFor(ds->getBody(), p);
}
void visitTopLevelCodeDecl(TopLevelCodeDecl *d, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
scopeCreator.createSubtree<TopLevelCodeScope>(p, d); return scopeCreator.createScopeFor(ds->getBody(), p);
}
ASTScopeImpl *visitTopLevelCodeDecl(TopLevelCodeDecl *d, ASTScopeImpl *p,
ScopeCreator &scopeCreator) {
return scopeCreator.createSubtree<TopLevelCodeScope>(p, d);
} }
#pragma mark special-case creation #pragma mark special-case creation
void visitSourceFile(SourceFile *, ASTScopeImpl *, ScopeCreator &) { ASTScopeImpl *visitSourceFile(SourceFile *, ASTScopeImpl *, ScopeCreator &) {
llvm_unreachable("SourceFiles are orphans."); llvm_unreachable("SourceFiles are orphans.");
} }
void visitYieldStmt(YieldStmt *ys, ASTScopeImpl *p, ASTScopeImpl *visitYieldStmt(YieldStmt *ys, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
for (Expr *e : ys->getYields()) for (Expr *e : ys->getYields())
visitExpr(e, p, scopeCreator); visitExpr(e, p, scopeCreator);
return p;
} }
void visitDeferStmt(DeferStmt *ds, ASTScopeImpl *p, ASTScopeImpl *visitDeferStmt(DeferStmt *ds, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
visitFuncDecl(ds->getTempDecl(), p, scopeCreator); visitFuncDecl(ds->getTempDecl(), p, scopeCreator);
return p;
} }
void visitBraceStmt(BraceStmt *bs, ASTScopeImpl *p, ASTScopeImpl *visitBraceStmt(BraceStmt *bs, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
if (p->areDeferredNodesInANewScope()) auto *insertionPoint = scopeCreator.createSubtree<BraceStmtScope>(p, bs);
scopeCreator.createSubtree<BraceStmtScope>(p, bs); return p->doISplitAScope() ? insertionPoint : p;
else
scopeCreator.withoutDeferrals().createSubtree<BraceStmtScope>(p, bs);
} }
void visitPatternBindingDecl(PatternBindingDecl *patternBinding, ASTScopeImpl *visitPatternBindingDecl(PatternBindingDecl *patternBinding,
ASTScopeImpl *parentScope, ASTScopeImpl *parentScope,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
scopeCreator.createAttachedPropertyWrapperScope(patternBinding, scopeCreator.createAttachedPropertyWrapperScope(patternBinding,
@@ -552,22 +497,27 @@ public:
const DeclVisibilityKind vis = const DeclVisibilityKind vis =
isInTypeDecl ? DeclVisibilityKind::MemberOfCurrentNominal isInTypeDecl ? DeclVisibilityKind::MemberOfCurrentNominal
: DeclVisibilityKind::LocalVariable; : DeclVisibilityKind::LocalVariable;
scopeCreator.createSubtree<PatternEntryDeclScope>(parentScope, auto *useScope = scopeCreator.createSubtree<PatternEntryDeclScope>(
patternBinding, 0, vis); parentScope, patternBinding, 0, vis);
// decls after a pattern are accessible before the pattern in a type scope
return isInTypeDecl ? parentScope : useScope;
} }
void visitReturnStmt(ReturnStmt *rs, ASTScopeImpl *p, ASTScopeImpl *visitReturnStmt(ReturnStmt *rs, ASTScopeImpl *p,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
if (rs->hasResult()) if (rs->hasResult())
visitExpr(rs->getResult(), p, scopeCreator); visitExpr(rs->getResult(), p, scopeCreator);
return p;
} }
void visitExpr(Expr *expr, ASTScopeImpl *p, ScopeCreator &scopeCreator) { ASTScopeImpl *visitExpr(Expr *expr, ASTScopeImpl *p,
if (!expr) ScopeCreator &scopeCreator) {
return; if (expr) {
p->widenSourceRangeForIgnoredASTNode(expr); p->widenSourceRangeForIgnoredASTNode(expr);
scopeCreator.addChildrenForCapturesAndClosuresIn(expr, p); scopeCreator.addChildrenForCapturesAndClosuresIn(expr, p);
} }
return p;
}
}; };
} // namespace ast_scope } // namespace ast_scope
} // namespace swift } // namespace swift
@@ -575,9 +525,11 @@ public:
// These definitions are way down here so it can call into // These definitions are way down here so it can call into
// ASTVisitorForScopeCreation // ASTVisitorForScopeCreation
template <typename StmtOrExprOrDecl> template <typename StmtOrExprOrDecl>
void ScopeCreator::createScopeFor(StmtOrExprOrDecl *sed, ASTScopeImpl *parent) { ASTScopeImpl *ScopeCreator::createScopeFor(StmtOrExprOrDecl *sed,
ASTScopeImpl *parent) {
if (shouldCreateScope(sed)) if (shouldCreateScope(sed))
ASTVisitorForScopeCreation().visit(sed, parent, *this); return ASTVisitorForScopeCreation().visit(sed, parent, *this);
return parent;
} }
void ScopeCreator::addChildrenForAllExplicitAccessors(AbstractStorageDecl *asd, void ScopeCreator::addChildrenForAllExplicitAccessors(AbstractStorageDecl *asd,
@@ -607,7 +559,11 @@ void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) {
child->parent = this; child->parent = this;
} }
bool PatternEntryDeclScope::isHandledSpecially(const ASTNode n) {
if (auto *d = n.dyn_cast<Decl *>())
return isa<VarDecl>(d) || isa<AccessorDecl>(d);
return false;
}
#pragma mark specific implementations of expansion #pragma mark specific implementations of expansion
@@ -619,10 +575,8 @@ NullablePtr<ASTScopeImpl> ASTScopeImpl::expandMe(ScopeCreator &scopeCreator) {
void ASTScopeImpl::expandNonSplittingMe(ScopeCreator &) {} void ASTScopeImpl::expandNonSplittingMe(ScopeCreator &) {}
NullablePtr<ASTScopeImpl> void ASTSourceFileScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
ASTSourceFileScope::expandMe(ScopeCreator &scopeCreator) { llvm_unreachable("expanded by addNewDeclsToTree()");
#error here
// nsertionPoint = scopeCreator.createScopeFor(d, <#ASTScopeImpl *parent#>)
} }
// Create child scopes for every declaration in a body. // Create child scopes for every declaration in a body.
@@ -632,7 +586,7 @@ void AbstractFunctionDeclScope::expandNonSplittingMe(
// Create scopes for specialize attributes // Create scopes for specialize attributes
scopeCreator.forEachSpecializeAttrInSourceOrder( scopeCreator.forEachSpecializeAttrInSourceOrder(
decl, [&](SpecializeAttr *specializeAttr) { decl, [&](SpecializeAttr *specializeAttr) {
scopeCreator.withoutDeferrals().createSubtree<SpecializeAttributeScope>( scopeCreator.createSubtree<SpecializeAttributeScope>(
this, specializeAttr, decl); this, specializeAttr, decl);
}); });
// Create scopes for generic and ordinary parameters. // Create scopes for generic and ordinary parameters.
@@ -643,19 +597,16 @@ void AbstractFunctionDeclScope::expandNonSplittingMe(
leaf = scopeCreator.createGenericParamScopes(decl, decl->getGenericParams(), leaf = scopeCreator.createGenericParamScopes(decl, decl->getGenericParams(),
leaf); leaf);
if (!decl->isImplicit()) { if (!decl->isImplicit()) {
leaf = scopeCreator.withoutDeferrals() leaf = scopeCreator.createSubtree<AbstractFunctionParamsScope>(
.createSubtree<AbstractFunctionParamsScope>(
leaf, decl->getParameters(), nullptr); leaf, decl->getParameters(), nullptr);
} }
} }
// Create scope for the body. // Create scope for the body.
if (decl->getBody()) { if (decl->getBody()) {
if (decl->getDeclContext()->isTypeContext()) if (decl->getDeclContext()->isTypeContext())
scopeCreator.withoutDeferrals().createSubtree<MethodBodyScope>(leaf, scopeCreator.createSubtree<MethodBodyScope>(leaf, decl);
decl);
else else
scopeCreator.withoutDeferrals().createSubtree<PureFunctionBodyScope>( scopeCreator.createSubtree<PureFunctionBodyScope>(leaf, decl);
leaf, decl);
} }
} }
@@ -666,8 +617,7 @@ AbstractFunctionParamsScope::expandMe(ScopeCreator &scopeCreator) {
// previous parameter. // previous parameter.
for (ParamDecl *pd : params->getArray()) { for (ParamDecl *pd : params->getArray()) {
if (!scopeCreator.isDuplicate(pd) && pd->getDefaultValue()) if (!scopeCreator.isDuplicate(pd) && pd->getDefaultValue())
scopeCreator.withoutDeferrals() scopeCreator.createSubtree<DefaultArgumentInitializerScope>(this, pd);
.createSubtree<DefaultArgumentInitializerScope>(this, pd);
} }
return this; // body of func goes under me return this; // body of func goes under me
} }
@@ -688,8 +638,8 @@ PatternEntryDeclScope::expandMe(ScopeCreator &scopeCreator) {
SourceLoc initializerEnd; SourceLoc initializerEnd;
if (patternEntry.getInitAsWritten() && if (patternEntry.getInitAsWritten() &&
patternEntry.getInitAsWritten()->getSourceRange().isValid()) { patternEntry.getInitAsWritten()->getSourceRange().isValid()) {
auto *initializer = scopeCreator.withoutDeferrals() auto *initializer =
.createSubtree<PatternEntryInitializerScope>( scopeCreator.createSubtree<PatternEntryInitializerScope>(
this, decl, patternEntryIndex, vis); this, decl, patternEntryIndex, vis);
initializer->cacheSourceRange(); initializer->cacheSourceRange();
initializerEnd = initializer->getSourceRange().End; initializerEnd = initializer->getSourceRange().End;
@@ -706,7 +656,7 @@ NullablePtr<ASTScopeImpl>
PatternEntryInitializerScope::expandMe(ScopeCreator &scopeCreator) { PatternEntryInitializerScope::expandMe(ScopeCreator &scopeCreator) {
// Create a child for the initializer expression. // Create a child for the initializer expression.
ASTVisitorForScopeCreation().visitExpr(getPatternEntry().getInitAsWritten(), ASTVisitorForScopeCreation().visitExpr(getPatternEntry().getInitAsWritten(),
this, scopeCreator.withoutDeferrals()); this, scopeCreator);
return this; // next PatternEntryDeclScope goes under me return this; // next PatternEntryDeclScope goes under me
} }
@@ -714,7 +664,7 @@ NullablePtr<ASTScopeImpl>
PatternEntryUseScope::expandMe(ScopeCreator &scopeCreator) { PatternEntryUseScope::expandMe(ScopeCreator &scopeCreator) {
// Add accessors for the variables in this pattern. // Add accessors for the variables in this pattern.
forEachVarDeclWithExplicitAccessors(scopeCreator, false, [&](VarDecl *var) { forEachVarDeclWithExplicitAccessors(scopeCreator, false, [&](VarDecl *var) {
scopeCreator.withoutDeferrals().createSubtree<VarDeclScope>(this, var); scopeCreator.createSubtree<VarDeclScope>(this, var);
}); });
if (!isLastEntry()) { if (!isLastEntry()) {
return scopeCreator.createSubtree<PatternEntryDeclScope>( return scopeCreator.createSubtree<PatternEntryDeclScope>(
@@ -741,36 +691,33 @@ ASTScopeImpl *
LabeledConditionalStmtScope::createCondScopes(ScopeCreator &scopeCreator) { LabeledConditionalStmtScope::createCondScopes(ScopeCreator &scopeCreator) {
if (getLabeledConditionalStmt()->getCond().empty()) if (getLabeledConditionalStmt()->getCond().empty())
return this; return this;
return scopeCreator.withoutDeferrals().createSubtree<ConditionalClauseScope>( return scopeCreator.createSubtree<ConditionalClauseScope>(
this, getLabeledConditionalStmt(), 0, getStmtAfterTheConditions()); this, getLabeledConditionalStmt(), 0, getStmtAfterTheConditions());
} }
void IfStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void IfStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
auto &sc = scopeCreator.withoutDeferrals(); ASTScopeImpl *lookupParent = createCondScopes(scopeCreator);
ASTScopeImpl *lookupParent = createCondScopes(sc);
// The 'then' branch // The 'then' branch
sc.createScopeFor(stmt->getThenStmt(), lookupParent); scopeCreator.createScopeFor(stmt->getThenStmt(), lookupParent);
// Add the 'else' branch, if needed. // Add the 'else' branch, if needed.
sc.createScopeFor(stmt->getElseStmt(), this); scopeCreator.createScopeFor(stmt->getElseStmt(), this);
} }
void WhileStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void WhileStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
auto &sc = scopeCreator.withoutDeferrals(); ASTScopeImpl *lookupParent = createCondScopes(scopeCreator);
ASTScopeImpl *lookupParent = createCondScopes(sc); scopeCreator.createScopeFor(stmt->getBody(), lookupParent);
sc.createScopeFor(stmt->getBody(), lookupParent);
} }
NullablePtr<ASTScopeImpl> GuardStmtScope::expandMe(ScopeCreator &scopeCreator) { NullablePtr<ASTScopeImpl> GuardStmtScope::expandMe(ScopeCreator &scopeCreator) {
auto &sc = scopeCreator.withoutDeferrals(); ASTScopeImpl *lookupParent = createCondScopes(scopeCreator);
ASTScopeImpl *lookupParent = createCondScopes(sc);
// Add a child for the 'guard' body, which always exits. // Add a child for the 'guard' body, which always exits.
// Parent is whole guard stmt scope, NOT the cond scopes // Parent is whole guard stmt scope, NOT the cond scopes
scopeCreator.createScopeFor(stmt->getBody(), this); scopeCreator.createScopeFor(stmt->getBody(), this);
return sc.createSubtree<ConditionalClauseUseScope>(this, lookupParent, return scopeCreator.createSubtree<ConditionalClauseUseScope>(
stmt->getEndLoc()); this, lookupParent, stmt->getEndLoc());
} }
void RepeatWhileScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void RepeatWhileScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
@@ -795,8 +742,7 @@ void SwitchStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
for (auto caseStmt : stmt->getCases()) { for (auto caseStmt : stmt->getCases()) {
if (!scopeCreator.isDuplicate(caseStmt)) { if (!scopeCreator.isDuplicate(caseStmt)) {
scopeCreator.withoutDeferrals().createSubtree<CaseStmtScope>(this, scopeCreator.createSubtree<CaseStmtScope>(this, caseStmt);
caseStmt);
} }
} }
} }
@@ -806,8 +752,7 @@ void ForEachStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
scopeCreator); scopeCreator);
// Add a child describing the scope of the pattern. // Add a child describing the scope of the pattern.
scopeCreator.withoutDeferrals().createSubtree<ForEachPatternScope>(this, scopeCreator.createSubtree<ForEachPatternScope>(this, stmt);
stmt);
} }
void ForEachPatternScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void ForEachPatternScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
@@ -832,13 +777,11 @@ void CaseStmtScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
} }
NullablePtr<ASTScopeImpl> BraceStmtScope::expandMe(ScopeCreator &scopeCreator) { NullablePtr<ASTScopeImpl> BraceStmtScope::expandMe(ScopeCreator &scopeCreator) {
scopeCreator.pushAllNecessaryNodes(stmt->getElements()); scopeCreator.addScopesToTree(stmt->getElements());
return this; return this;
} }
void VarDeclScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void VarDeclScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
assert(!scopeCreator.haveDeferredNodes() &&
"Decls needing this var go into the PatternEntryUseScope, not here");
scopeCreator.addChildrenForAllExplicitAccessors(decl, this); scopeCreator.addChildrenForAllExplicitAccessors(decl, this);
} }
@@ -846,22 +789,20 @@ void SubscriptDeclScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
auto *sub = decl; auto *sub = decl;
auto *leaf = auto *leaf =
scopeCreator.createGenericParamScopes(sub, sub->getGenericParams(), this); scopeCreator.createGenericParamScopes(sub, sub->getGenericParams(), this);
auto *params = scopeCreator.withoutDeferrals() auto *params = scopeCreator.createSubtree<AbstractFunctionParamsScope>(
.createSubtree<AbstractFunctionParamsScope>(
leaf, sub->getIndices(), sub->getGetter()); leaf, sub->getIndices(), sub->getGetter());
scopeCreator.addChildrenForAllExplicitAccessors(sub, params); scopeCreator.addChildrenForAllExplicitAccessors(sub, params);
} }
void WholeClosureScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void WholeClosureScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
if (auto *cl = captureList.getPtrOrNull()) if (auto *cl = captureList.getPtrOrNull())
scopeCreator.withoutDeferrals().createSubtree<CaptureListScope>(this, cl); scopeCreator.createSubtree<CaptureListScope>(this, cl);
ASTScopeImpl *bodyParent = this; ASTScopeImpl *bodyParent = this;
if (closureExpr->getInLoc().isValid()) if (closureExpr->getInLoc().isValid())
bodyParent = bodyParent = scopeCreator.createSubtree<ClosureParametersScope>(
scopeCreator.withoutDeferrals().createSubtree<ClosureParametersScope>(
this, closureExpr, captureList); this, closureExpr, captureList);
scopeCreator.withoutDeferrals().createSubtree<ClosureBodyScope>( scopeCreator.createSubtree<ClosureBodyScope>(bodyParent, closureExpr,
bodyParent, closureExpr, captureList); captureList);
} }
void CaptureListScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void CaptureListScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
@@ -877,8 +818,7 @@ void CaptureListScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
} }
void ClosureBodyScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void ClosureBodyScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
scopeCreator.withoutDeferrals().createSubtree<BraceStmtScope>( scopeCreator.createSubtree<BraceStmtScope>(this, closureExpr->getBody());
this, closureExpr->getBody());
} }
void TopLevelCodeScope::expandNonSplittingMe(ScopeCreator &scopeCreator) { void TopLevelCodeScope::expandNonSplittingMe(ScopeCreator &scopeCreator) {
@@ -907,10 +847,10 @@ void GenericTypeOrExtensionWholePortion::expandScope(
auto *deepestScope = scopeCreator.createGenericParamScopes( auto *deepestScope = scopeCreator.createGenericParamScopes(
scope->getDecl().get(), scope->getGenericContext()->getGenericParams(), scope->getDecl().get(), scope->getGenericContext()->getGenericParams(),
scope); scope);
if (scope->getGenericContext()->getTrailingWhereClause()) if (scope->getGenericContext()->getTrailingWhereClause()) {
deepestScope =
scope->createTrailingWhereClauseScope(deepestScope, scopeCreator); scope->createTrailingWhereClauseScope(deepestScope, scopeCreator);
deepestScope = deepestScope->getChildren().back();
}
scope->createBodyScope(deepestScope, scopeCreator); scope->createBodyScope(deepestScope, scopeCreator);
} }
@@ -926,35 +866,32 @@ void IterableTypeBodyPortion::expandScope(GenericTypeOrExtensionScope *scope,
void ExtensionScope::createBodyScope(ASTScopeImpl *leaf, void ExtensionScope::createBodyScope(ASTScopeImpl *leaf,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
scopeCreator.withoutDeferrals() scopeCreator.createSubtree2D<ExtensionScope, IterableTypeBodyPortion>(leaf,
.createSubtree2D<ExtensionScope, IterableTypeBodyPortion>(leaf, decl); decl);
} }
void NominalTypeScope::createBodyScope(ASTScopeImpl *leaf, void NominalTypeScope::createBodyScope(ASTScopeImpl *leaf,
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
scopeCreator.withoutDeferrals() scopeCreator.createSubtree2D<NominalTypeScope, IterableTypeBodyPortion>(leaf,
.createSubtree2D<NominalTypeScope, IterableTypeBodyPortion>(leaf, decl); decl);
} }
#pragma mark createTrailingWhereClauseScope #pragma mark createTrailingWhereClauseScope
ASTScopeImpl * void ExtensionScope::createTrailingWhereClauseScope(
ExtensionScope::createTrailingWhereClauseScope(ASTScopeImpl *parent, ASTScopeImpl *parent, ScopeCreator &scopeCreator) {
ScopeCreator &scopeCreator) { scopeCreator
return scopeCreator.withoutDeferrals()
.createSubtree2D<ExtensionScope, GenericTypeOrExtensionWherePortion>( .createSubtree2D<ExtensionScope, GenericTypeOrExtensionWherePortion>(
parent, decl); parent, decl);
} }
ASTScopeImpl * void NominalTypeScope::createTrailingWhereClauseScope(
NominalTypeScope::createTrailingWhereClauseScope(ASTScopeImpl *parent, ASTScopeImpl *parent, ScopeCreator &scopeCreator) {
ScopeCreator &scopeCreator) { scopeCreator
return scopeCreator.withoutDeferrals()
.createSubtree2D<NominalTypeScope, GenericTypeOrExtensionWherePortion>( .createSubtree2D<NominalTypeScope, GenericTypeOrExtensionWherePortion>(
parent, decl); parent, decl);
} }
ASTScopeImpl * void TypeAliasScope::createTrailingWhereClauseScope(
TypeAliasScope::createTrailingWhereClauseScope(ASTScopeImpl *parent, ASTScopeImpl *parent, ScopeCreator &scopeCreator) {
ScopeCreator &scopeCreator) { scopeCreator
return scopeCreator.withoutDeferrals()
.createSubtree2D<TypeAliasScope, GenericTypeOrExtensionWherePortion>( .createSubtree2D<TypeAliasScope, GenericTypeOrExtensionWherePortion>(
parent, decl); parent, decl);
} }
@@ -982,12 +919,6 @@ void AbstractPatternEntryScope::forEachVarDeclWithExplicitAccessors(
}); });
} }
bool ASTScopeImpl::isCreatedDirectly(const ASTNode n) {
// See PatternEntryUseScope::expandMe and addChildrenForAllExplicitAccessors
if (auto *d = n.dyn_cast<Decl*>())
return isa<VarDecl>(d) || isa<AccessorDecl>(d);
return false;
}
void ConditionalClauseScope::createSubtreeForCondition( void ConditionalClauseScope::createSubtreeForCondition(
ScopeCreator &scopeCreator) { ScopeCreator &scopeCreator) {
@@ -997,15 +928,14 @@ void ConditionalClauseScope::createSubtreeForCondition(
return; return;
case StmtConditionElement::CK_Boolean: case StmtConditionElement::CK_Boolean:
ASTVisitorForScopeCreation().visitExpr(cond.getBoolean(), this, ASTVisitorForScopeCreation().visitExpr(cond.getBoolean(), this,
scopeCreator.withoutDeferrals()); scopeCreator);
return; return;
case StmtConditionElement::CK_PatternBinding: case StmtConditionElement::CK_PatternBinding:
statementConditionElementPatternScope = statementConditionElementPatternScope =
scopeCreator.withoutDeferrals() scopeCreator.createSubtree<StatementConditionElementPatternScope>(
.createSubtree<StatementConditionElementPatternScope>(
this, cond.getPattern()); this, cond.getPattern());
ASTVisitorForScopeCreation().visitExpr(cond.getInitializer(), this, ASTVisitorForScopeCreation().visitExpr(cond.getInitializer(), this,
scopeCreator.withoutDeferrals()); scopeCreator);
return; return;
} }
} }
@@ -1014,21 +944,6 @@ bool AbstractPatternEntryScope::isLastEntry() const {
return patternEntryIndex + 1 == decl->getPatternList().size(); return patternEntryIndex + 1 == decl->getPatternList().size();
} }
ASTScopeImpl *ConditionalClauseScope::findInnermostConditionScope() {
auto *const deepest = findDeepestConditionalClauseScope();
auto statementCond = deepest->getStatementConditionElementPatternScope();
if (ASTScopeImpl *s = statementCond.getPtrOrNull())
return s;
return deepest;
}
ConditionalClauseScope *
ConditionalClauseScope::findDeepestConditionalClauseScope() {
return nextConditionalClause
? nextConditionalClause.get()->findDeepestConditionalClauseScope()
: this;
}
NullablePtr<StatementConditionElementPatternScope> NullablePtr<StatementConditionElementPatternScope>
ConditionalClauseScope::getStatementConditionElementPatternScope() const { ConditionalClauseScope::getStatementConditionElementPatternScope() const {
return statementConditionElementPatternScope; return statementConditionElementPatternScope;

View File

@@ -471,7 +471,7 @@ void ASTScopeImpl::widenSourceRangeForIgnoredASTNode(const ASTNode n) {
// Doing the default here would cause a pattern initializer scope's range // Doing the default here would cause a pattern initializer scope's range
// to overlap the pattern use scope's range. // to overlap the pattern use scope's range.
if (AbstractPatternEntryScope::isCreatedDirectly(n)) if (PatternEntryDeclScope::isHandledSpecially(n))
return; return;
SourceRange r = getEffectiveSourceRange(n); SourceRange r = getEffectiveSourceRange(n);