mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Lots of cleanups, renamings, etc.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "swift/AST/Stmt.h"
|
||||
#include "swift/AST/TypeRepr.h"
|
||||
#include "swift/Basic/STLExtras.h"
|
||||
#include "swift/Parse/Lexer.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <algorithm>
|
||||
|
||||
@@ -34,6 +35,8 @@ using namespace swift;
|
||||
using namespace ast_scope;
|
||||
|
||||
static SourceLoc getStartOfFirstParam(ClosureExpr *closure);
|
||||
static SourceLoc getLocEncompassingPotentialLookups(const SourceManager &,
|
||||
SourceLoc endLoc);
|
||||
|
||||
SourceRange ASTScopeImpl::widenSourceRangeForIgnoredASTNodes(
|
||||
const SourceRange range) const {
|
||||
@@ -53,9 +56,9 @@ ASTScopeImpl::widenSourceRangeForChildren(const SourceRange range,
|
||||
return range;
|
||||
}
|
||||
const auto childStart =
|
||||
getChildren().front()->getSourceRange(omitAssertions).Start;
|
||||
getChildren().front()->getSourceRangeOfScope(omitAssertions).Start;
|
||||
const auto childEnd =
|
||||
getChildren().back()->getSourceRange(omitAssertions).End;
|
||||
getChildren().back()->getSourceRangeOfScope(omitAssertions).End;
|
||||
auto childRange = SourceRange(childStart, childEnd);
|
||||
assert(omitAssertions || childRange.isValid());
|
||||
|
||||
@@ -66,10 +69,21 @@ ASTScopeImpl::widenSourceRangeForChildren(const SourceRange range,
|
||||
return r;
|
||||
}
|
||||
|
||||
bool ASTScopeImpl::checkSourceRangeAfterExpansion() const {
|
||||
assert((getSourceRangeOfThisASTNode().isValid() || !getChildren().empty()) &&
|
||||
"need to be able to find source range");
|
||||
assert(verifyThatChildrenAreContainedWithin(getSourceRangeOfScope()) &&
|
||||
"Search will fail");
|
||||
assert(checkLazySourceRange() &&
|
||||
"Lazy scopes must have compatible ranges before and after expansion");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma mark validation
|
||||
|
||||
bool ASTScopeImpl::hasValidSourceRange() const {
|
||||
const auto sourceRange = getSourceRange();
|
||||
const auto sourceRange = getSourceRangeOfScope();
|
||||
return sourceRange.Start.isValid() && sourceRange.End.isValid() &&
|
||||
!getSourceManager().isBeforeInBuffer(sourceRange.End,
|
||||
sourceRange.Start);
|
||||
@@ -82,8 +96,8 @@ bool ASTScopeImpl::hasValidSourceRangeOfIgnoredASTNodes() const {
|
||||
bool ASTScopeImpl::precedesInSource(const ASTScopeImpl *next) const {
|
||||
if (!hasValidSourceRange() || !next->hasValidSourceRange())
|
||||
return false;
|
||||
return !getSourceManager().isBeforeInBuffer(next->getSourceRange().Start,
|
||||
getSourceRange().End);
|
||||
return !getSourceManager().isBeforeInBuffer(
|
||||
next->getSourceRangeOfScope().Start, getSourceRangeOfScope().End);
|
||||
}
|
||||
|
||||
bool ASTScopeImpl::verifyThatChildrenAreContainedWithin(
|
||||
@@ -92,8 +106,8 @@ bool ASTScopeImpl::verifyThatChildrenAreContainedWithin(
|
||||
if (getChildren().empty())
|
||||
return true;
|
||||
const SourceRange rangeOfChildren =
|
||||
SourceRange(getChildren().front()->getSourceRange().Start,
|
||||
getChildren().back()->getSourceRange().End);
|
||||
SourceRange(getChildren().front()->getSourceRangeOfScope().Start,
|
||||
getChildren().back()->getSourceRangeOfScope().End);
|
||||
if (getSourceManager().rangeContains(range, rangeOfChildren))
|
||||
return true;
|
||||
auto &out = verificationError() << "children not contained in its parent\n";
|
||||
@@ -152,51 +166,51 @@ NullablePtr<ASTScopeImpl> ASTScopeImpl::getPriorSibling() const {
|
||||
return siblingsAndMe[myIndex - 1];
|
||||
}
|
||||
|
||||
#pragma mark getChildlessSourceRange
|
||||
#pragma mark getSourceRangeOfThisASTNode
|
||||
|
||||
SourceRange SpecializeAttributeScope::getChildlessSourceRange(
|
||||
SourceRange SpecializeAttributeScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return specializeAttr->getRange();
|
||||
}
|
||||
|
||||
SourceRange AbstractFunctionBodyScope::getChildlessSourceRange(
|
||||
SourceRange AbstractFunctionBodyScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return decl->getBodySourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
TopLevelCodeScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange TopLevelCodeScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return decl->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange SubscriptDeclScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return decl->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
SubscriptDeclScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
return decl->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
EnumElementScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
return decl->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
WholeClosureScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange WholeClosureScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return closureExpr->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
AbstractStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange AbstractStmtScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return getStmt()->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange DefaultArgumentInitializerScope::getChildlessSourceRange(
|
||||
SourceRange DefaultArgumentInitializerScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
if (auto *dv = decl->getDefaultValue())
|
||||
return dv->getSourceRange();
|
||||
return SourceRange();
|
||||
}
|
||||
|
||||
SourceRange PatternEntryDeclScope::getChildlessSourceRange(
|
||||
SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// TODO: Once rdar://53627317 is accomplished, the following may be able to be
|
||||
// simplified.
|
||||
@@ -211,7 +225,7 @@ SourceRange PatternEntryDeclScope::getChildlessSourceRange(
|
||||
return getPatternEntry().getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange PatternEntryInitializerScope::getChildlessSourceRange(
|
||||
SourceRange PatternEntryInitializerScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// See rdar://53921703
|
||||
// Note: grep for "When the initializer is removed we don't actually clear the
|
||||
@@ -220,13 +234,13 @@ SourceRange PatternEntryInitializerScope::getChildlessSourceRange(
|
||||
}
|
||||
|
||||
SourceRange
|
||||
VarDeclScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
VarDeclScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
const auto br = decl->getBracesRange();
|
||||
return br.isValid() ? br : decl->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
GenericParamScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange GenericParamScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
auto nOrE = holder;
|
||||
// A protocol's generic parameter list is not written in source, and
|
||||
// is visible from the start of the body.
|
||||
@@ -238,8 +252,8 @@ GenericParamScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
return SourceRange(startLoc, holder->getEndLoc());
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ASTSourceFileScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange ASTSourceFileScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
if (auto bufferID = SF->getBufferID()) {
|
||||
auto charRange = getSourceManager().getRangeForBuffer(*bufferID);
|
||||
return SourceRange(charRange.getStart(), charRange.getEnd());
|
||||
@@ -253,7 +267,7 @@ ASTSourceFileScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SF->Decls.back()->getEndLoc());
|
||||
}
|
||||
|
||||
SourceRange GenericTypeOrExtensionScope::getChildlessSourceRange(
|
||||
SourceRange GenericTypeOrExtensionScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return portion->getChildlessSourceRangeOf(this, omitAssertions);
|
||||
}
|
||||
@@ -286,7 +300,7 @@ SourceRange IterableTypeBodyPortion::getChildlessSourceRangeOf(
|
||||
llvm_unreachable("No body!");
|
||||
}
|
||||
|
||||
SourceRange AbstractFunctionDeclScope::getChildlessSourceRange(
|
||||
SourceRange AbstractFunctionDeclScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// For a get/put accessor all of the parameters are implicit, so start
|
||||
// them at the start location of the accessor.
|
||||
@@ -298,13 +312,14 @@ SourceRange AbstractFunctionDeclScope::getChildlessSourceRange(
|
||||
return decl->getBodySourceRange();
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ParameterListScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
const auto rangeForGoodInput = getSourceRangeOfEnclosedParams(omitAssertions);
|
||||
SourceRange ParameterListScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
const auto rangeForGoodInput =
|
||||
getSourceRangeOfEnclosedParamsOfASTNode(omitAssertions);
|
||||
auto r = SourceRange(rangeForGoodInput.Start,
|
||||
fixupEndForBadInput(rangeForGoodInput));
|
||||
assert(getSourceManager().rangeContains(
|
||||
getParent().get()->getChildlessSourceRange(true), r) &&
|
||||
getParent().get()->getSourceRangeOfThisASTNode(true), r) &&
|
||||
"Parameters not within function?!");
|
||||
return r;
|
||||
}
|
||||
@@ -316,8 +331,8 @@ SourceLoc ParameterListScope::fixupEndForBadInput(
|
||||
return getSourceManager().isBeforeInBuffer(s, e) ? e : s;
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ForEachPatternScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
SourceRange ForEachPatternScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// The scope of the pattern extends from the 'where' expression (if present)
|
||||
// until the end of the body.
|
||||
if (stmt->getWhere())
|
||||
@@ -329,7 +344,7 @@ ForEachPatternScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
}
|
||||
|
||||
SourceRange
|
||||
CatchStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
CatchStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
// The scope of the pattern extends from the 'where' (if present)
|
||||
// to the end of the body.
|
||||
if (stmt->getGuardExpr())
|
||||
@@ -339,7 +354,7 @@ CatchStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
return stmt->getBody()->getSourceRange();
|
||||
}
|
||||
SourceRange
|
||||
CaseStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
CaseStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
// The scope of the case statement begins at the first guard expression,
|
||||
// if there is one, and extends to the end of the body.
|
||||
// FIXME: Figure out what to do about multiple pattern bindings. We might
|
||||
@@ -356,7 +371,7 @@ CaseStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
}
|
||||
|
||||
SourceRange
|
||||
BraceStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
BraceStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
// The brace statements that represent closures start their scope at the
|
||||
// 'in' keyword, when present.
|
||||
if (auto closure = parentClosureIfAny()) {
|
||||
@@ -366,7 +381,7 @@ BraceStmtScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
return stmt->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange ConditionalClauseScope::getChildlessSourceRange(
|
||||
SourceRange ConditionalClauseScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// From the start of this particular condition to the start of the
|
||||
// then/body part.
|
||||
@@ -376,7 +391,7 @@ SourceRange ConditionalClauseScope::getChildlessSourceRange(
|
||||
: SourceRange(endLoc);
|
||||
}
|
||||
|
||||
SourceRange ConditionalClausePatternUseScope::getChildlessSourceRange(
|
||||
SourceRange ConditionalClausePatternUseScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
// For a guard continuation, the scope extends from the end of the 'else'
|
||||
// to the end of the continuation.
|
||||
@@ -384,12 +399,12 @@ SourceRange ConditionalClausePatternUseScope::getChildlessSourceRange(
|
||||
}
|
||||
|
||||
SourceRange
|
||||
CaptureListScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
CaptureListScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
auto *const closure = expr->getClosureBody();
|
||||
return SourceRange(expr->getStartLoc(), getStartOfFirstParam(closure));
|
||||
}
|
||||
|
||||
SourceRange ClosureParametersScope::getChildlessSourceRange(
|
||||
SourceRange ClosureParametersScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
if (!omitAssertions)
|
||||
assert(closureExpr->getInLoc().isValid() &&
|
||||
@@ -399,28 +414,29 @@ SourceRange ClosureParametersScope::getChildlessSourceRange(
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ClosureBodyScope::getChildlessSourceRange(const bool omitAssertions) const {
|
||||
ClosureBodyScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
|
||||
if (closureExpr->getInLoc().isValid())
|
||||
return SourceRange(closureExpr->getInLoc(), closureExpr->getEndLoc());
|
||||
|
||||
return closureExpr->getSourceRange();
|
||||
}
|
||||
|
||||
SourceRange AttachedPropertyWrapperScope::getChildlessSourceRange(
|
||||
SourceRange AttachedPropertyWrapperScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return sourceRangeWhenCreated;
|
||||
}
|
||||
|
||||
SourceRange LookupParentDiversionScope::getChildlessSourceRange(
|
||||
SourceRange LookupParentDiversionScope::getSourceRangeOfThisASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return SourceRange(startLoc);
|
||||
}
|
||||
|
||||
#pragma mark source range caching
|
||||
|
||||
SourceRange ASTScopeImpl::getSourceRange(const bool omitAssertions) const {
|
||||
SourceRange
|
||||
ASTScopeImpl::getSourceRangeOfScope(const bool omitAssertions) const {
|
||||
if (!isSourceRangeCached(omitAssertions))
|
||||
cacheSourceRangeOfMeAndDescendants(omitAssertions);
|
||||
computeAndCacheSourceRangeOfScope(omitAssertions);
|
||||
return *cachedSourceRange;
|
||||
}
|
||||
|
||||
@@ -441,33 +457,57 @@ bool ASTScopeImpl::ensureNoAncestorsSourceRangeIsCached() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTScopeImpl::cacheSourceRangeOfMeAndDescendants(
|
||||
void ASTScopeImpl::computeAndCacheSourceRangeOfScope(
|
||||
const bool omitAssertions) const {
|
||||
// In order to satisfy the invariant that, if my range is uncached,
|
||||
// my parent's range is uncached, (which is needed to optimize invalidation
|
||||
// by obviating the need to uncache all the way to the root every time),
|
||||
// when caching a range, must ensure all children's ranges are cached.
|
||||
for (auto *c : getChildren())
|
||||
c->cacheSourceRangeOfMeAndDescendants(omitAssertions);
|
||||
c->computeAndCacheSourceRangeOfScope(omitAssertions);
|
||||
|
||||
cachedSourceRange = getUncachedSourceRange(omitAssertions);
|
||||
cachedSourceRange = computeSourceRangeOfScope(omitAssertions);
|
||||
}
|
||||
|
||||
bool ASTScopeImpl::checkLazySourceRange() const {
|
||||
if (!getASTContext().LangOpts.LazyASTScopes)
|
||||
return true;
|
||||
const auto unexpandedRange = sourceRangeForDeferredExpansion();
|
||||
const auto expandedRange = computeSourceRangeOfScopeWithChildASTNodes();
|
||||
if (unexpandedRange.isInvalid() || expandedRange.isInvalid())
|
||||
return true;
|
||||
if (unexpandedRange == expandedRange)
|
||||
return true;
|
||||
|
||||
auto b = getChildren().back()->computeSourceRangeOfScope();
|
||||
llvm::errs() << "*** Lazy range problem. Parent: ***\n";
|
||||
unexpandedRange.print(llvm::errs(), getSourceManager(), false);
|
||||
llvm::errs() << "\n*** vs last child: ***\n";
|
||||
b.print(llvm::errs(), getSourceManager(), false);
|
||||
llvm::errs() << "\n";
|
||||
print(llvm::errs(), 0, false);
|
||||
llvm::errs() << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceRange
|
||||
ASTScopeImpl::getUncachedSourceRange(const bool omitAssertions) const {
|
||||
const SourceRange rangeForLazyCheck = getASTContext().LangOpts.LazyASTScopes
|
||||
? sourceRangeForDeferredExpansion()
|
||||
: SourceRange();
|
||||
(void)rangeForLazyCheck;
|
||||
const auto childlessRange = getChildlessSourceRange(omitAssertions);
|
||||
ASTScopeImpl::computeSourceRangeOfScope(const bool omitAssertions) const {
|
||||
// If we don't need to consider children, it's cheaper
|
||||
const auto deferredRange = sourceRangeForDeferredExpansion();
|
||||
return deferredRange.isValid()
|
||||
? deferredRange
|
||||
: computeSourceRangeOfScopeWithChildASTNodes(omitAssertions);
|
||||
}
|
||||
|
||||
SourceRange ASTScopeImpl::computeSourceRangeOfScopeWithChildASTNodes(
|
||||
const bool omitAssertions) const {
|
||||
const auto rangeOfJustThisASTNode =
|
||||
getSourceRangeOfThisASTNode(omitAssertions);
|
||||
const auto rangeIncludingIgnoredNodes =
|
||||
widenSourceRangeForIgnoredASTNodes(childlessRange);
|
||||
assert(rangeForLazyCheck.isInvalid() ||
|
||||
rangeForLazyCheck == rangeIncludingIgnoredNodes);
|
||||
auto uncachedSourceRange =
|
||||
widenSourceRangeForIgnoredASTNodes(rangeOfJustThisASTNode);
|
||||
const auto uncachedSourceRange =
|
||||
widenSourceRangeForChildren(rangeIncludingIgnoredNodes, omitAssertions);
|
||||
assert(rangeForLazyCheck.isInvalid() ||
|
||||
rangeForLazyCheck == uncachedSourceRange);
|
||||
return uncachedSourceRange;
|
||||
}
|
||||
|
||||
@@ -480,58 +520,74 @@ void ASTScopeImpl::clearCachedSourceRangesOfMeAndAncestors() {
|
||||
p.get()->clearCachedSourceRangesOfMeAndAncestors();
|
||||
}
|
||||
|
||||
#pragma mark ignored nodes and compensating for InterpolatedStringLiteralExprs and EditorPlaceHolders
|
||||
#pragma mark compensating for InterpolatedStringLiteralExprs and EditorPlaceHolders
|
||||
|
||||
namespace {
|
||||
class EffectiveEndFinder : public ASTWalker {
|
||||
SourceLoc end;
|
||||
const SourceManager &SM;
|
||||
|
||||
public:
|
||||
EffectiveEndFinder(const SourceManager &SM) : SM(SM) {}
|
||||
|
||||
std::pair<bool, Expr *> walkToExprPre(Expr *E) {
|
||||
if (!E)
|
||||
return {true, E};
|
||||
if (auto *isl = dyn_cast<InterpolatedStringLiteralExpr>(E)) {
|
||||
if (end.isInvalid() ||
|
||||
SM.isBeforeInBuffer(end, isl->getTrailingQuoteLoc()))
|
||||
end = isl->getTrailingQuoteLoc();
|
||||
} else if (auto *epl = dyn_cast<EditorPlaceholderExpr>(E)) {
|
||||
if (end.isInvalid() ||
|
||||
SM.isBeforeInBuffer(end, epl->getTrailingAngleBracketLoc()))
|
||||
end = epl->getTrailingAngleBracketLoc();
|
||||
}
|
||||
return ASTWalker::walkToExprPre(E);
|
||||
// If right brace is missing, the source range of the body will end
|
||||
// at the last token, which may be a one of the special cases below.
|
||||
static SourceLoc getLocEncompassingPotentialLookups(const SourceManager &SM,
|
||||
const SourceLoc endLoc) {
|
||||
const auto tok = Lexer::getTokenAtLocation(SM, endLoc);
|
||||
switch (tok.getKind()) {
|
||||
default:
|
||||
return endLoc;
|
||||
case tok::string_literal:
|
||||
break;
|
||||
case tok::identifier:
|
||||
// subtract one to get a closed-range endpoint from a half-open
|
||||
if (!Identifier::isEditorPlaceholder(tok.getText()))
|
||||
return endLoc;
|
||||
break;
|
||||
}
|
||||
SourceLoc getTrailingQuoteLoc() const { return end; }
|
||||
};
|
||||
} // namespace
|
||||
return tok.getRange().getEnd().getAdvancedLoc(-1);
|
||||
}
|
||||
|
||||
SourceRange ASTScopeImpl::sourceRangeForDeferredExpansion() const {
|
||||
return SourceRange();
|
||||
}
|
||||
SourceRange IterableTypeScope::sourceRangeForDeferredExpansion() const {
|
||||
return portion->sourceRangeForDeferredExpansion(this);
|
||||
}
|
||||
SourceRange
|
||||
Portion::sourceRangeForDeferredExpansion(const IterableTypeScope *) const {
|
||||
return SourceRange();
|
||||
}
|
||||
|
||||
// FIXME: Alter how EditorPlaceHolder and InterpolgatedStringLiteralExpr are
|
||||
// parsed so getSourceRange is enough.
|
||||
SourceRange ASTScopeImpl::getEffectiveSourceRange(const ASTNode n) const {
|
||||
if (const auto *d = n.dyn_cast<Decl *>())
|
||||
return d->getSourceRange();
|
||||
if (const auto *s = n.dyn_cast<Stmt *>())
|
||||
return s->getSourceRange();
|
||||
auto *e = n.dyn_cast<Expr *>();
|
||||
assert(e);
|
||||
EffectiveEndFinder finder(getSourceManager());
|
||||
e->walk(finder);
|
||||
return SourceRange(e->getLoc(), finder.getTrailingQuoteLoc().isValid()
|
||||
? finder.getTrailingQuoteLoc()
|
||||
: e->getEndLoc());
|
||||
return getLocEncompassingPotentialLookups(getSourceManager(), e->getEndLoc());
|
||||
}
|
||||
|
||||
/// Some nodes (e.g. the error expression) cannot possibly contain anything to
|
||||
/// be looked up and if included in a parent scope's source range would expand
|
||||
/// it beyond an ancestor's source range. But if the ancestor is expanded
|
||||
/// lazily, we check that its source range does not change when expanding it,
|
||||
/// and this check would fail.
|
||||
static bool sourceRangeWouldInterfereWithLaziness(const ASTNode n) {
|
||||
return n.isExpr(ExprKind::Error);
|
||||
}
|
||||
|
||||
static bool
|
||||
shouldIgnoredASTNodeSourceRangeWidenEnclosingScope(const ASTNode n) {
|
||||
if (n.isDecl(DeclKind::Var)) {
|
||||
// The pattern scopes will include the source ranges for VarDecls.
|
||||
// Using its range here would cause a pattern initializer scope's range
|
||||
// to overlap the pattern use scope's range.
|
||||
return false;
|
||||
}
|
||||
if (sourceRangeWouldInterfereWithLaziness(n))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTScopeImpl::widenSourceRangeForIgnoredASTNode(const ASTNode n) {
|
||||
// The pattern scopes will include the source ranges for VarDecls.
|
||||
// Doing the default here would cause a pattern initializer scope's range
|
||||
// to overlap the pattern use scope's range.
|
||||
|
||||
if (n.isDecl(DeclKind::Var))
|
||||
if (!shouldIgnoredASTNodeSourceRangeWidenEnclosingScope(n))
|
||||
return;
|
||||
|
||||
// FIXME: why only do effectiveness bit for *ignored* nodes?
|
||||
SourceRange r = getEffectiveSourceRange(n);
|
||||
if (r.isInvalid())
|
||||
return;
|
||||
@@ -553,20 +609,21 @@ static SourceLoc getStartOfFirstParam(ClosureExpr *closure) {
|
||||
return closure->getStartLoc();
|
||||
}
|
||||
|
||||
#pragma mark getSourceRangeOfEnclosedParams
|
||||
#pragma mark getSourceRangeOfEnclosedParamsOfASTNode
|
||||
|
||||
SourceRange
|
||||
ASTScopeImpl::getSourceRangeOfEnclosedParams(const bool omitAssertions) const {
|
||||
return getParent().get()->getSourceRangeOfEnclosedParams(omitAssertions);
|
||||
SourceRange ASTScopeImpl::getSourceRangeOfEnclosedParamsOfASTNode(
|
||||
const bool omitAssertions) const {
|
||||
return getParent().get()->getSourceRangeOfEnclosedParamsOfASTNode(
|
||||
omitAssertions);
|
||||
}
|
||||
|
||||
SourceRange
|
||||
EnumElementScope::getSourceRangeOfEnclosedParams(bool omitAssertions) const {
|
||||
SourceRange EnumElementScope::getSourceRangeOfEnclosedParamsOfASTNode(
|
||||
bool omitAssertions) const {
|
||||
auto *pl = decl->getParameterList();
|
||||
return pl ? pl->getSourceRange() : SourceRange();
|
||||
}
|
||||
|
||||
SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParams(
|
||||
SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParamsOfASTNode(
|
||||
const bool omitAssertions) const {
|
||||
auto r = SourceRange(decl->getIndices()->getLParenLoc(), decl->getEndLoc());
|
||||
// Because of "subscript(x: MyStruct#^PARAM_1^#) -> Int { return 0 }"
|
||||
@@ -575,15 +632,15 @@ SourceRange SubscriptDeclScope::getSourceRangeOfEnclosedParams(
|
||||
return r;
|
||||
}
|
||||
|
||||
SourceRange AbstractFunctionDeclScope::getSourceRangeOfEnclosedParams(
|
||||
SourceRange AbstractFunctionDeclScope::getSourceRangeOfEnclosedParamsOfASTNode(
|
||||
const bool omitAssertions) const {
|
||||
const auto s = getParamsSourceLoc(decl);
|
||||
const auto e = getChildlessSourceRange(omitAssertions).End;
|
||||
const auto s = getParmsSourceLocOfAFD(decl);
|
||||
const auto e = getSourceRangeOfThisASTNode(omitAssertions).End;
|
||||
return s.isInvalid() || e.isInvalid() ? SourceRange() : SourceRange(s, e);
|
||||
}
|
||||
|
||||
SourceLoc
|
||||
AbstractFunctionDeclScope::getParamsSourceLoc(AbstractFunctionDecl *decl) {
|
||||
AbstractFunctionDeclScope::getParmsSourceLocOfAFD(AbstractFunctionDecl *decl) {
|
||||
if (auto *c = dyn_cast<ConstructorDecl>(decl))
|
||||
return c->getParameters()->getLParenLoc();
|
||||
|
||||
@@ -597,3 +654,13 @@ AbstractFunctionDeclScope::getParamsSourceLoc(AbstractFunctionDecl *decl) {
|
||||
: fd->getParameters()->getLParenLoc();
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
#pragma mark deferred scope source ranges
|
||||
|
||||
SourceRange IterableTypeBodyPortion::sourceRangeForDeferredExpansion(
|
||||
const IterableTypeScope *s) const {
|
||||
const auto bracesRange = getChildlessSourceRangeOf(s, false);
|
||||
const auto &SM = s->getSourceManager();
|
||||
return SourceRange(bracesRange.Start,
|
||||
getLocEncompassingPotentialLookups(SM, bracesRange.End));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user