|
38 | 38 | using namespace swift;
|
39 | 39 | using namespace ast_scope;
|
40 | 40 |
|
41 |
| -/// If true, nest scopes so a variable is out of scope before its declaration |
42 |
| -/// Does not handle capture rules for local functions properly. |
43 |
| -/// If false don't push uses down into subscopes after decls. |
44 |
| -static const bool handleUseBeforeDef = false; |
45 |
| - |
46 | 41 | #pragma mark source range utilities
|
47 | 42 | static bool rangeableIsIgnored(const Decl *d) { return d->isImplicit(); }
|
48 | 43 | static bool rangeableIsIgnored(const Expr *d) {
|
@@ -215,6 +210,10 @@ class ScopeCreator final {
|
215 | 210 | ScopeCreator(const ScopeCreator &) = delete; // ensure no copies
|
216 | 211 | ScopeCreator(const ScopeCreator &&) = delete; // ensure no moves
|
217 | 212 |
|
| 213 | + SourceManager &getSourceManager() const { |
| 214 | + return ctx.SourceMgr; |
| 215 | + } |
| 216 | + |
218 | 217 | /// Given an array of ASTNodes or Decl pointers, add them
|
219 | 218 | /// Return the resultant insertionPoint
|
220 | 219 | ASTScopeImpl *
|
@@ -283,7 +282,7 @@ class ScopeCreator final {
|
283 | 282 | /// \endcode
|
284 | 283 | /// I'm seeing a dumped AST include:
|
285 | 284 | /// (pattern_binding_decl range=[test.swift:13:8 - line:12:29]
|
286 |
| - const auto &SM = d->getASTContext().SourceMgr; |
| 285 | + const auto &SM = getSourceManager(); |
287 | 286 |
|
288 | 287 | // Once we allow invalid PatternBindingDecls (see
|
289 | 288 | // isWorthTryingToCreateScopeFor), then
|
@@ -746,22 +745,62 @@ class NodeAdder
|
746 | 745 | if (auto *var = patternBinding->getSingleVar())
|
747 | 746 | scopeCreator.addChildrenForKnownAttributes(var, parentScope);
|
748 | 747 |
|
749 |
| - const bool isInTypeDecl = parentScope->isATypeDeclScope(); |
| 748 | + const bool isLocalBinding = patternBinding->getDeclContext()->isLocalContext(); |
750 | 749 |
|
751 |
| - const DeclVisibilityKind vis = |
752 |
| - isInTypeDecl ? DeclVisibilityKind::MemberOfCurrentNominal |
753 |
| - : DeclVisibilityKind::LocalVariable; |
754 | 750 | auto *insertionPoint = parentScope;
|
755 | 751 | for (auto i : range(patternBinding->getNumPatternEntries())) {
|
756 |
| - insertionPoint = |
| 752 | + // Create a child for the initializer, if present. |
| 753 | + // Cannot trust the source range given in the ASTScopeImpl for the end of the |
| 754 | + // initializer (because of InterpolatedLiteralStrings and EditorPlaceHolders), |
| 755 | + // so compute it ourselves. |
| 756 | + // Even if this predicate fails, there may be an initContext but |
| 757 | + // we cannot make a scope for it, since no source range. |
| 758 | + if (auto *expr = patternBinding->getOriginalInit(i)) { |
| 759 | + if (isLocalizable(expr)) { |
| 760 | + ASTScopeAssert( |
| 761 | + !scopeCreator.getSourceManager().isBeforeInBuffer( |
| 762 | + expr->getStartLoc(), patternBinding->getStartLoc()), |
| 763 | + "Original inits are always after the '='"); |
757 | 764 | scopeCreator
|
758 |
| - .ifUniqueConstructExpandAndInsert<PatternEntryDeclScope>( |
759 |
| - insertionPoint, patternBinding, i, vis) |
760 |
| - .getPtrOr(insertionPoint); |
| 765 | + .constructExpandAndInsertUncheckable<PatternEntryInitializerScope>( |
| 766 | + insertionPoint, patternBinding, i); |
| 767 | + } |
| 768 | + } |
| 769 | + |
| 770 | + // Add accessors for the variables in this pattern. |
| 771 | + patternBinding->getPattern(i)->forEachVariable([&](VarDecl *var) { |
| 772 | + scopeCreator.addChildrenForAllLocalizableAccessorsInSourceOrder( |
| 773 | + var, insertionPoint); |
| 774 | + }); |
| 775 | + |
| 776 | + // For local bindings, introduce the scope where the names become |
| 777 | + // visible. |
| 778 | + if(isLocalBinding) { |
| 779 | + // Don't create the scope if the start is past the end of the buffer. |
| 780 | + // |
| 781 | + // This can happen with invalid code missing an end delimiter, eg |
| 782 | + // |
| 783 | + // func foo() { var x = 123<EOF> |
| 784 | + // |
| 785 | + // The PatternEntryDeclScope for 'x' should begin immediately after |
| 786 | + // the 123, but that is not a valid location, so we drop the scope |
| 787 | + // since we're not going to be able to see it anyway. |
| 788 | + auto loc = PatternEntryDeclScope::getStartLocForBinding( |
| 789 | + scopeCreator.getSourceManager(), |
| 790 | + insertionPoint, patternBinding, i); |
| 791 | + if (loc.isValid()) { |
| 792 | + insertionPoint = |
| 793 | + scopeCreator |
| 794 | + .ifUniqueConstructExpandAndInsert<PatternEntryDeclScope>( |
| 795 | + insertionPoint, patternBinding, i, loc) |
| 796 | + .getPtrOr(insertionPoint); |
| 797 | + } |
| 798 | + } |
761 | 799 | }
|
| 800 | + |
762 | 801 | // If in a type decl, the type search will find these,
|
763 | 802 | // but if in a brace stmt, must continue under the last binding.
|
764 |
| - return isInTypeDecl ? parentScope : insertionPoint; |
| 803 | + return isLocalBinding ? insertionPoint : parentScope; |
765 | 804 | }
|
766 | 805 |
|
767 | 806 | NullablePtr<ASTScopeImpl> visitEnumElementDecl(EnumElementDecl *eed,
|
@@ -947,7 +986,6 @@ ASTScopeImpl *ASTScopeImpl::expandAndBeCurrent(ScopeCreator &scopeCreator) {
|
947 | 986 | CREATES_NEW_INSERTION_POINT(ASTSourceFileScope)
|
948 | 987 | CREATES_NEW_INSERTION_POINT(ConditionalClauseScope)
|
949 | 988 | CREATES_NEW_INSERTION_POINT(GuardStmtScope)
|
950 |
| -CREATES_NEW_INSERTION_POINT(PatternEntryDeclScope) |
951 | 989 | CREATES_NEW_INSERTION_POINT(GenericTypeOrExtensionScope)
|
952 | 990 | CREATES_NEW_INSERTION_POINT(BraceStmtScope)
|
953 | 991 | CREATES_NEW_INSERTION_POINT(TopLevelCodeScope)
|
@@ -976,6 +1014,7 @@ NO_NEW_INSERTION_POINT(SwitchStmtScope)
|
976 | 1014 | NO_NEW_INSERTION_POINT(WhileStmtScope)
|
977 | 1015 |
|
978 | 1016 | NO_EXPANSION(GenericParamScope)
|
| 1017 | +NO_EXPANSION(PatternEntryDeclScope) |
979 | 1018 | NO_EXPANSION(SpecializeAttributeScope)
|
980 | 1019 | NO_EXPANSION(DifferentiableAttributeScope)
|
981 | 1020 | NO_EXPANSION(ConditionalClausePatternUseScope)
|
@@ -1013,41 +1052,6 @@ ParameterListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
|
1013 | 1052 | }
|
1014 | 1053 | }
|
1015 | 1054 |
|
1016 |
| -AnnotatedInsertionPoint |
1017 |
| -PatternEntryDeclScope::expandAScopeThatCreatesANewInsertionPoint( |
1018 |
| - ScopeCreator &scopeCreator) { |
1019 |
| - // Initializers come before VarDecls, e.g. PCMacro/didSet.swift 19 |
1020 |
| - auto patternEntry = getPatternEntry(); |
1021 |
| - |
1022 |
| - // Create a child for the initializer, if present. |
1023 |
| - // Cannot trust the source range given in the ASTScopeImpl for the end of the |
1024 |
| - // initializer (because of InterpolatedLiteralStrings and EditorPlaceHolders), |
1025 |
| - // so compute it ourselves. |
1026 |
| - // Even if this predicate fails, there may be an initContext but |
1027 |
| - // we cannot make a scope for it, since no source range. |
1028 |
| - if (patternEntry.getOriginalInit() && |
1029 |
| - isLocalizable(patternEntry.getOriginalInit())) { |
1030 |
| - ASTScopeAssert( |
1031 |
| - !getSourceManager().isBeforeInBuffer( |
1032 |
| - patternEntry.getOriginalInit()->getStartLoc(), decl->getStartLoc()), |
1033 |
| - "Original inits are always after the '='"); |
1034 |
| - scopeCreator |
1035 |
| - .constructExpandAndInsertUncheckable<PatternEntryInitializerScope>( |
1036 |
| - this, decl, patternEntryIndex, vis); |
1037 |
| - } |
1038 |
| - |
1039 |
| - // Add accessors for the variables in this pattern. |
1040 |
| - patternEntry.getPattern()->forEachVariable([&](VarDecl *var) { |
1041 |
| - scopeCreator.addChildrenForAllLocalizableAccessorsInSourceOrder(var, this); |
1042 |
| - }); |
1043 |
| - |
1044 |
| - ASTScopeAssert(!handleUseBeforeDef, |
1045 |
| - "next line is wrong otherwise; would need a use scope"); |
1046 |
| - |
1047 |
| - return {getParent().get(), "When not handling use-before-def, succeeding " |
1048 |
| - "code just goes in the same scope as this one"}; |
1049 |
| -} |
1050 |
| - |
1051 | 1055 | void
|
1052 | 1056 | PatternEntryInitializerScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
|
1053 | 1057 | ScopeCreator &scopeCreator) {
|
@@ -1417,18 +1421,12 @@ ASTScopeImpl *LabeledConditionalStmtScope::createNestedConditionalClauseScopes(
|
1417 | 1421 | }
|
1418 | 1422 |
|
1419 | 1423 | AbstractPatternEntryScope::AbstractPatternEntryScope(
|
1420 |
| - PatternBindingDecl *declBeingScoped, unsigned entryIndex, |
1421 |
| - DeclVisibilityKind vis) |
1422 |
| - : decl(declBeingScoped), patternEntryIndex(entryIndex), vis(vis) { |
| 1424 | + PatternBindingDecl *declBeingScoped, unsigned entryIndex) |
| 1425 | + : decl(declBeingScoped), patternEntryIndex(entryIndex) { |
1423 | 1426 | ASTScopeAssert(entryIndex < declBeingScoped->getPatternList().size(),
|
1424 | 1427 | "out of bounds");
|
1425 | 1428 | }
|
1426 | 1429 |
|
1427 |
| -bool ASTScopeImpl::isATypeDeclScope() const { |
1428 |
| - Decl *const pd = getDeclIfAny().getPtrOrNull(); |
1429 |
| - return pd && (isa<NominalTypeDecl>(pd) || isa<ExtensionDecl>(pd)); |
1430 |
| -} |
1431 |
| - |
1432 | 1430 | #pragma mark new operators
|
1433 | 1431 | void *ASTScopeImpl::operator new(size_t bytes, const ASTContext &ctx,
|
1434 | 1432 | unsigned alignment) {
|
@@ -1481,8 +1479,6 @@ ScopeCreator &ASTSourceFileScope::getScopeCreator() { return *scopeCreator; }
|
1481 | 1479 | }
|
1482 | 1480 |
|
1483 | 1481 | GET_REFERRENT(AbstractFunctionDeclScope, getDecl())
|
1484 |
| -// If the PatternBindingDecl is a dup, detect it for the first |
1485 |
| -// PatternEntryDeclScope; the others are subscopes. |
1486 | 1482 | GET_REFERRENT(PatternEntryDeclScope, getPattern())
|
1487 | 1483 | GET_REFERRENT(TopLevelCodeScope, getDecl())
|
1488 | 1484 | GET_REFERRENT(SubscriptDeclScope, getDecl())
|
|
0 commit comments