Skip to content

Commit 7df8b70

Browse files
authored
Merge pull request swiftlang#34207 from slavapestov/astscope-char-source-ranges
Migrate ASTScope to CharSourceRanges
2 parents 164bd08 + e59069f commit 7df8b70

File tree

10 files changed

+101
-505
lines changed

10 files changed

+101
-505
lines changed

include/swift/AST/ASTScope.h

Lines changed: 8 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -141,21 +141,14 @@ class ASTScopeImpl {
141141
ASTScopeImpl *parent = nullptr; // null at the root
142142

143143
/// Child scopes, sorted by source range.
144-
/// Must clear source range change whenever this changes
145144
Children storedChildren;
146145

147146
bool wasExpanded = false;
148147

149148
/// Can clear storedChildren, so must remember this
150149
bool haveAddedCleanup = false;
151150

152-
// Must be updated after last child is added and after last child's source
153-
// position is known
154-
mutable Optional<SourceRange> cachedSourceRange;
155-
156-
// When ignoring ASTNodes in a scope, they still must count towards a scope's
157-
// source range. So include their ranges here
158-
SourceRange sourceRangeOfIgnoredASTNodes;
151+
mutable Optional<CharSourceRange> cachedCharSourceRange;
159152

160153
#pragma mark - constructor / destructor
161154
public:
@@ -192,9 +185,6 @@ class ASTScopeImpl {
192185
public:
193186
void addChild(ASTScopeImpl *child, ASTContext &);
194187

195-
private:
196-
NullablePtr<ASTScopeImpl> getPriorSibling() const;
197-
198188
public:
199189
void preOrderDo(function_ref<void(ASTScopeImpl *)>);
200190
/// Like preorderDo but without myself.
@@ -203,78 +193,26 @@ class ASTScopeImpl {
203193

204194
#pragma mark - source ranges
205195

206-
#pragma mark - source range queries
207-
208196
public:
209197
/// Return signum of ranges. Centralize the invariant that ASTScopes use ends.
210198
static int compare(SourceRange, SourceRange, const SourceManager &,
211199
bool ensureDisjoint);
212200

213-
SourceRange getSourceRangeOfScope(bool omitAssertions = false) const;
214-
215-
/// InterpolatedStringLiteralExprs and EditorPlaceHolders respond to
216-
/// getSourceRange with the starting point. But we might be asked to lookup an
217-
/// identifer within one of them. So, find the real source range of them here.
218-
SourceRange getEffectiveSourceRange(ASTNode) const;
219-
220-
void computeAndCacheSourceRangeOfScope(bool omitAssertions = false) const;
221-
bool isSourceRangeCached(bool omitAssertions = false) const;
222-
223-
bool checkSourceRangeOfThisASTNode() const;
224-
225-
/// For debugging
226-
bool doesRangeMatch(unsigned start, unsigned end, StringRef file = "",
227-
StringRef className = "");
228-
229-
unsigned countDescendants() const;
230-
231-
/// Make sure that when the argument is executed, there are as many
232-
/// descendants after as before.
233-
void assertThatTreeDoesNotShrink(function_ref<void()>);
234-
235-
private:
236-
SourceRange computeSourceRangeOfScope(bool omitAssertions = false) const;
237-
SourceRange
238-
computeSourceRangeOfScopeWithChildASTNodes(bool omitAssertions = false) const;
239-
bool ensureNoAncestorsSourceRangeIsCached() const;
240-
241-
#pragma mark - source range adjustments
242-
private:
243-
SourceRange widenSourceRangeForIgnoredASTNodes(SourceRange range) const;
244-
245-
/// If the scope refers to a Decl whose source range tells the whole story,
246-
/// for example a NominalTypeScope, it is not necessary to widen the source
247-
/// range by examining the children. In that case we could just return
248-
/// the childlessRange here.
249-
/// But, we have not marked such scopes yet. Doing so would be an
250-
/// optimization.
251-
SourceRange widenSourceRangeForChildren(SourceRange range,
252-
bool omitAssertions) const;
253-
254-
/// Even ASTNodes that do not form scopes must be included in a Scope's source
255-
/// range. Widen the source range of the receiver to include the (ignored)
256-
/// node.
257-
void widenSourceRangeForIgnoredASTNode(ASTNode);
258-
259-
private:
260-
void clearCachedSourceRangesOfMeAndAncestors();
201+
CharSourceRange getCharSourceRangeOfScope(SourceManager &SM,
202+
bool omitAssertions = false) const;
203+
bool isCharSourceRangeCached() const;
261204

262-
public: // public for debugging
263205
/// Returns source range of this node alone, without factoring in any
264206
/// children.
265207
virtual SourceRange
266208
getSourceRangeOfThisASTNode(bool omitAssertions = false) const = 0;
267209

268210
protected:
269211
SourceManager &getSourceManager() const;
270-
bool hasValidSourceRange() const;
271-
bool hasValidSourceRangeOfIgnoredASTNodes() const;
272-
bool precedesInSource(const ASTScopeImpl *) const;
273-
bool verifyThatChildrenAreContainedWithin(SourceRange) const;
274-
bool verifyThatThisNodeComeAfterItsPriorSibling() const;
275212

276213
private:
277-
bool checkSourceRangeAfterExpansion(const ASTContext &) const;
214+
void checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
215+
const ASTContext &ctx) const;
278216

279217
#pragma mark common queries
280218
public:
@@ -329,19 +267,11 @@ class ASTScopeImpl {
329267
void setWasExpanded() { wasExpanded = true; }
330268
virtual ASTScopeImpl *expandSpecifically(ScopeCreator &) = 0;
331269

332-
private:
333-
/// Compare the pre-expasion range with the post-expansion range and return
334-
/// false if lazyiness couild miss lookups.
335-
bool checkLazySourceRange(const ASTContext &) const;
336-
337270
public:
338271
/// Some scopes can be expanded lazily.
339-
/// Such scopes must: not change their source ranges after expansion, and
340-
/// their expansion must return an insertion point outside themselves.
341-
/// After a node is expanded, its source range (getSourceRangeofThisASTNode
342-
/// union children's ranges) must be same as this.
272+
/// Such scopes must return an insertion point outside themselves when
273+
/// expanded.
343274
virtual NullablePtr<ASTScopeImpl> insertionPointForDeferredExpansion();
344-
virtual SourceRange sourceRangeForDeferredExpansion() const;
345275

346276
private:
347277
virtual ScopeCreator &getScopeCreator();
@@ -545,8 +475,6 @@ class Portion {
545475

546476
virtual NullablePtr<ASTScopeImpl>
547477
insertionPointForDeferredExpansion(IterableTypeScope *) const = 0;
548-
virtual SourceRange
549-
sourceRangeForDeferredExpansion(const IterableTypeScope *) const = 0;
550478
};
551479

552480
// For the whole Decl scope of a GenericType or an Extension
@@ -570,8 +498,6 @@ class Portion {
570498

571499
NullablePtr<ASTScopeImpl>
572500
insertionPointForDeferredExpansion(IterableTypeScope *) const override;
573-
SourceRange
574-
sourceRangeForDeferredExpansion(const IterableTypeScope *) const override;
575501
};
576502

577503
/// GenericTypeOrExtension = GenericType or Extension
@@ -603,8 +529,6 @@ class GenericTypeOrExtensionWherePortion final
603529

604530
NullablePtr<ASTScopeImpl>
605531
insertionPointForDeferredExpansion(IterableTypeScope *) const override;
606-
SourceRange
607-
sourceRangeForDeferredExpansion(const IterableTypeScope *) const override;
608532
};
609533

610534
/// Behavior specific to representing the Body of a NominalTypeDecl or
@@ -622,8 +546,6 @@ class IterableTypeBodyPortion final
622546

623547
NullablePtr<ASTScopeImpl>
624548
insertionPointForDeferredExpansion(IterableTypeScope *) const override;
625-
SourceRange
626-
sourceRangeForDeferredExpansion(const IterableTypeScope *) const override;
627549
};
628550

629551
/// GenericType or Extension scope
@@ -720,7 +642,6 @@ class IterableTypeScope : public GenericTypeScope {
720642

721643
public:
722644
NullablePtr<ASTScopeImpl> insertionPointForDeferredExpansion() override;
723-
SourceRange sourceRangeForDeferredExpansion() const override;
724645

725646
void countBodies(ScopeCreator &) const;
726647
};
@@ -929,7 +850,6 @@ class FunctionBodyScope : public ASTScopeImpl {
929850
public:
930851
std::string getClassName() const override;
931852
NullablePtr<ASTScopeImpl> insertionPointForDeferredExpansion() override;
932-
SourceRange sourceRangeForDeferredExpansion() const override;
933853
};
934854

935855
class DefaultArgumentInitializerScope final : public ASTScopeImpl {

lib/AST/ASTScope.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -197,23 +197,4 @@ void ASTScopeImpl::postOrderDo(function_ref<void(ASTScopeImpl *)> fn) {
197197
for (auto *child : getChildren())
198198
child->postOrderDo(fn);
199199
fn(this);
200-
}
201-
202-
unsigned ASTScopeImpl::countDescendants() const {
203-
unsigned count = 0;
204-
const_cast<ASTScopeImpl *>(this)->preOrderDo(
205-
[&](ASTScopeImpl *) { ++count; });
206-
return count - 1;
207-
}
208-
209-
// Can fail if a subscope is lazy and not reexpanded
210-
void ASTScopeImpl::assertThatTreeDoesNotShrink(function_ref<void()> fn) {
211-
#ifndef NDEBUG
212-
unsigned beforeCount = countDescendants();
213-
#endif
214-
fn();
215-
#ifndef NDEBUG
216-
unsigned afterCount = countDescendants();
217-
ASTScopeAssert(beforeCount <= afterCount, "shrank?!");
218-
#endif
219-
}
200+
}

lib/AST/ASTScopeCreation.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,6 @@ class ScopeCreator final {
334334

335335
ASTScopeImpl *insertionPoint =
336336
child->expandAndBeCurrentDetectingRecursion(*this);
337-
ASTScopeAssert(child->verifyThatThisNodeComeAfterItsPriorSibling(),
338-
"Ensure search will work");
339337
return insertionPoint;
340338
}
341339

@@ -574,7 +572,6 @@ class NodeAdder
574572
#define VISIT_AND_IGNORE(What) \
575573
NullablePtr<ASTScopeImpl> visit##What(What *w, ASTScopeImpl *p, \
576574
ScopeCreator &) { \
577-
p->widenSourceRangeForIgnoredASTNode(w); \
578575
return p; \
579576
}
580577

@@ -768,10 +765,9 @@ class NodeAdder
768765

769766
NullablePtr<ASTScopeImpl> visitExpr(Expr *expr, ASTScopeImpl *p,
770767
ScopeCreator &scopeCreator) {
771-
if (expr) {
772-
p->widenSourceRangeForIgnoredASTNode(expr);
768+
if (expr)
773769
scopeCreator.addExprToScopeTree(expr, p);
774-
}
770+
775771
return p;
776772
}
777773
};
@@ -881,6 +877,13 @@ ScopeCreator::addPatternBindingToScopeTree(PatternBindingDecl *patternBinding,
881877
#pragma mark creation helpers
882878

883879
void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) {
880+
ASTScopeAssert(!child->getParent(), "child should not already have parent");
881+
child->parent = this;
882+
883+
#ifndef NDEBUG
884+
checkSourceRangeBeforeAddingChild(child, ctx);
885+
#endif
886+
884887
// If this is the first time we've added children, notify the ASTContext
885888
// that there's a SmallVector that needs to be cleaned up.
886889
// FIXME: If we had access to SmallVector::isSmall(), we could do better.
@@ -889,9 +892,6 @@ void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) {
889892
haveAddedCleanup = true;
890893
}
891894
storedChildren.push_back(child);
892-
ASTScopeAssert(!child->getParent(), "child should not already have parent");
893-
child->parent = this;
894-
clearCachedSourceRangesOfMeAndAncestors();
895895
}
896896

897897
#pragma mark implementations of expansion
@@ -926,8 +926,6 @@ ASTScopeImpl *ASTScopeImpl::expandAndBeCurrent(ScopeCreator &scopeCreator) {
926926

927927
setWasExpanded();
928928

929-
ASTScopeAssert(checkSourceRangeAfterExpansion(scopeCreator.getASTContext()),
930-
"Bad range.");
931929
return insertionPoint;
932930
}
933931

lib/AST/ASTScopeLookup.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,14 @@ ASTScopeImpl *ASTScopeImpl::findInnermostEnclosingScopeImpl(
7272
scopeCreator);
7373
}
7474

75-
bool ASTScopeImpl::checkSourceRangeOfThisASTNode() const {
76-
const auto r = getSourceRangeOfThisASTNode();
77-
(void)r;
78-
ASTScopeAssert(!getSourceManager().isBeforeInBuffer(r.End, r.Start),
79-
"Range is backwards.");
80-
return true;
81-
}
82-
8375
/// If the \p loc is in a new buffer but \p range is not, consider the location
8476
/// is at the start of replaced range. Otherwise, returns \p loc as is.
8577
static SourceLoc translateLocForReplacedRange(SourceManager &sourceMgr,
86-
SourceRange range,
78+
CharSourceRange range,
8779
SourceLoc loc) {
8880
if (const auto &replacedRange = sourceMgr.getReplacedRange()) {
8981
if (sourceMgr.rangeContainsTokenLoc(replacedRange.New, loc) &&
90-
!sourceMgr.rangeContains(replacedRange.New, range)) {
82+
!sourceMgr.rangeContainsTokenLoc(replacedRange.New, range.getStart())) {
9183
return replacedRange.Original.Start;
9284
}
9385
}
@@ -101,17 +93,19 @@ ASTScopeImpl::findChildContaining(SourceLoc loc,
10193
auto *const *child = llvm::lower_bound(
10294
getChildren(), loc,
10395
[&sourceMgr](const ASTScopeImpl *scope, SourceLoc loc) {
104-
ASTScopeAssert(scope->checkSourceRangeOfThisASTNode(), "Bad range.");
105-
auto rangeOfScope = scope->getSourceRangeOfScope();
96+
auto rangeOfScope = scope->getCharSourceRangeOfScope(sourceMgr);
97+
ASTScopeAssert(!sourceMgr.isBeforeInBuffer(rangeOfScope.getEnd(),
98+
rangeOfScope.getStart()),
99+
"Source range is backwards");
106100
loc = translateLocForReplacedRange(sourceMgr, rangeOfScope, loc);
107-
return -1 == ASTScopeImpl::compare(rangeOfScope, loc, sourceMgr,
108-
/*ensureDisjoint=*/false);
101+
return (rangeOfScope.getEnd() == loc ||
102+
sourceMgr.isBeforeInBuffer(rangeOfScope.getEnd(), loc));
109103
});
110104

111105
if (child != getChildren().end()) {
112-
auto rangeOfScope = (*child)->getSourceRangeOfScope();
106+
auto rangeOfScope = (*child)->getCharSourceRangeOfScope(sourceMgr);
113107
loc = translateLocForReplacedRange(sourceMgr, rangeOfScope, loc);
114-
if (sourceMgr.rangeContainsTokenLoc(rangeOfScope, loc))
108+
if (rangeOfScope.contains(loc))
115109
return *child;
116110
}
117111

lib/AST/ASTScopePrinting.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,7 @@ static void printSourceRange(llvm::raw_ostream &out, const SourceRange range,
123123
}
124124

125125
void ASTScopeImpl::printRange(llvm::raw_ostream &out) const {
126-
if (!isSourceRangeCached(true))
127-
out << "(uncached) ";
128-
SourceRange range = computeSourceRangeOfScope(/*omitAssertions=*/true);
126+
SourceRange range = getSourceRangeOfThisASTNode(/*omitAssertions=*/true);
129127
printSourceRange(out, range, getSourceManager());
130128
}
131129

0 commit comments

Comments
 (0)