mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
WIP
This commit is contained in:
@@ -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,8 +615,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtensionScope final : public IterableTypeScope {
|
class ExtensionScope final : public IterableTypeScope {
|
||||||
@@ -620,8 +633,8 @@ 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,8 +647,8 @@ 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;
|
||||||
|
|||||||
@@ -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,12 +294,9 @@ 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++ << ": ";
|
out << "\n";
|
||||||
n.dump(out);
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make vanilla new illegal for ASTScopes.
|
// Make vanilla new illegal for ASTScopes.
|
||||||
@@ -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,46 +448,47 @@ 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);
|
ScopeCreator &scopeCreator) {
|
||||||
|
return scopeCreator.createScopeFor(ds->getBody(), p);
|
||||||
}
|
}
|
||||||
void visitTopLevelCodeDecl(TopLevelCodeDecl *d, ASTScopeImpl *p,
|
ASTScopeImpl *visitTopLevelCodeDecl(TopLevelCodeDecl *d, ASTScopeImpl *p,
|
||||||
ScopeCreator &scopeCreator) {
|
ScopeCreator &scopeCreator) {
|
||||||
scopeCreator.createSubtree<TopLevelCodeScope>(p, d);
|
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) {
|
|
||||||
visitFuncDecl(ds->getTempDecl(), p, scopeCreator);
|
|
||||||
}
|
|
||||||
|
|
||||||
void visitBraceStmt(BraceStmt *bs, ASTScopeImpl *p,
|
|
||||||
ScopeCreator &scopeCreator) {
|
|
||||||
if (p->areDeferredNodesInANewScope())
|
|
||||||
scopeCreator.createSubtree<BraceStmtScope>(p, bs);
|
|
||||||
else
|
|
||||||
scopeCreator.withoutDeferrals().createSubtree<BraceStmtScope>(p, bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void visitPatternBindingDecl(PatternBindingDecl *patternBinding,
|
|
||||||
ASTScopeImpl *parentScope,
|
|
||||||
ScopeCreator &scopeCreator) {
|
ScopeCreator &scopeCreator) {
|
||||||
|
visitFuncDecl(ds->getTempDecl(), p, scopeCreator);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTScopeImpl *visitBraceStmt(BraceStmt *bs, ASTScopeImpl *p,
|
||||||
|
ScopeCreator &scopeCreator) {
|
||||||
|
auto *insertionPoint = scopeCreator.createSubtree<BraceStmtScope>(p, bs);
|
||||||
|
return p->doISplitAScope() ? insertionPoint : p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTScopeImpl *visitPatternBindingDecl(PatternBindingDecl *patternBinding,
|
||||||
|
ASTScopeImpl *parentScope,
|
||||||
|
ScopeCreator &scopeCreator) {
|
||||||
scopeCreator.createAttachedPropertyWrapperScope(patternBinding,
|
scopeCreator.createAttachedPropertyWrapperScope(patternBinding,
|
||||||
parentScope);
|
parentScope);
|
||||||
Decl *const pd = parentScope->getDecl().getPtrOrNull();
|
Decl *const pd = parentScope->getDecl().getPtrOrNull();
|
||||||
@@ -552,21 +497,26 @@ 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
|
||||||
@@ -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,9 +638,9 @@ 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.createSubtree<ClosureBodyScope>(bodyParent, closureExpr,
|
||||||
scopeCreator.withoutDeferrals().createSubtree<ClosureBodyScope>(
|
captureList);
|
||||||
bodyParent, closureExpr, 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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user