Skip to content

Commit 1980f72

Browse files
committed
[ASTScope] Re-enable checkSourceRangeBeforeAddingChild
Update the logic to correctly handle replacement ranges, and re-enable the assertion. For now, carve out an exception for attributes on extensions, I'll try and tackle those in a follow-up.
1 parent 801079b commit 1980f72

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

include/swift/AST/ASTScope.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
239239
NullablePtr<Stmt> getStmtIfAny() const;
240240
NullablePtr<Expr> getExprIfAny() const;
241241

242+
/// Whether this scope is for a decl attribute.
243+
bool isDeclAttribute() const;
244+
242245
#pragma mark - debugging and printing
243246

244247
public:

lib/AST/ASTScope.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,20 @@ NullablePtr<Expr> ASTScopeImpl::getExprIfAny() const {
297297
}
298298
}
299299

300+
bool ASTScopeImpl::isDeclAttribute() const {
301+
switch (getKind()) {
302+
#define DECL_ATTRIBUTE_SCOPE_NODE(Name) \
303+
case ScopeKind::Name: return true;
304+
#define SCOPE_NODE(Name)
305+
#include "swift/AST/ASTScopeNodes.def"
306+
307+
#define DECL_ATTRIBUTE_SCOPE_NODE(Name)
308+
#define SCOPE_NODE(Name) case ScopeKind::Name:
309+
#include "swift/AST/ASTScopeNodes.def"
310+
return false;
311+
}
312+
}
313+
300314
SourceManager &ASTScopeImpl::getSourceManager() const {
301315
return getASTContext().SourceMgr;
302316
}

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ void ASTScopeImpl::addChild(ASTScopeImpl *child, ASTContext &ctx) {
714714
child->parentAndWasExpanded.setPointer(this);
715715

716716
#ifndef NDEBUG
717-
// checkSourceRangeBeforeAddingChild(child, ctx);
717+
checkSourceRangeBeforeAddingChild(child, ctx);
718718
#endif
719719

720720
// If this is the first time we've added children, notify the ASTContext

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,15 @@ using namespace ast_scope;
3939

4040
static SourceLoc getLocAfterExtendedNominal(const ExtensionDecl *);
4141

42-
/// Retrieve the character-based source range for the given source range.
43-
static SourceRange getCharSourceRange(
44-
SourceManager &sourceMgr, SourceRange range
45-
){
46-
range.End = Lexer::getLocForEndOfToken(sourceMgr, range.End);
47-
return range;
48-
}
49-
5042
void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
5143
const ASTContext &ctx) const {
44+
// Ignore attributes on extensions, currently they exist outside of the
45+
// extension's source range due to the way we've setup the scope for
46+
// extension binding.
47+
// FIXME: We ought to fix the source range for extension scopes.
48+
if (isa<ExtensionScope>(this) && child->isDeclAttribute())
49+
return;
50+
5251
// Ignore debugger bindings - they're a special mix of user code and implicit
5352
// wrapper code that is too difficult to check for consistency.
5453
if (auto d = getDeclIfAny().getPtrOrNull())
@@ -60,14 +59,14 @@ void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
6059

6160
auto range = getCharSourceRangeOfScope(sourceMgr);
6261

63-
std::function<bool(SourceRange)> containedInParent;
64-
containedInParent = [&](SourceRange childCharRange) {
62+
auto containedInParent = [&](SourceRange childCharRange) {
6563
// HACK: For code completion. Handle replaced range.
64+
// Note that the replaced SourceRanges here are already disguised
65+
// CharSourceRanges, we don't need to adjust them. We use `rangeContains`
66+
// since we're only interested in comparing within a single buffer.
6667
for (const auto &pair : sourceMgr.getReplacedRanges()) {
67-
auto originalRange = getCharSourceRange(sourceMgr, pair.first);
68-
auto newRange = getCharSourceRange(sourceMgr, pair.second);
69-
if (sourceMgr.encloses(range, originalRange) &&
70-
sourceMgr.encloses(newRange, childCharRange))
68+
if (sourceMgr.rangeContains(range, pair.first) &&
69+
sourceMgr.rangeContains(pair.second, childCharRange))
7170
return true;
7271
}
7372

0 commit comments

Comments
 (0)