Skip to content

Commit 007c814

Browse files
authored
Merge pull request #34021 from slavapestov/astscope-invalid-pbds
ASTScope: Clean up handling of PatternBindingDecls and AccessorDecls
2 parents ed96cf4 + c662c10 commit 007c814

File tree

12 files changed

+43
-151
lines changed

12 files changed

+43
-151
lines changed

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ class Parser {
11161116
ParsedAccessors &accessors,
11171117
AbstractStorageDecl *storage,
11181118
SourceLoc StaticLoc);
1119-
ParserResult<VarDecl> parseDeclVarGetSet(Pattern *pattern,
1119+
ParserResult<VarDecl> parseDeclVarGetSet(PatternBindingEntry &entry,
11201120
ParseDeclOptions Flags,
11211121
SourceLoc StaticLoc,
11221122
StaticSpellingKind StaticSpelling,

lib/AST/ASTScopeCreation.cpp

Lines changed: 19 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,6 @@ class ScopeCreator final {
273273
// Implicit nodes may not have source information for name lookup.
274274
if (!isLocalizable(d))
275275
return false;
276-
/// In \c Parser::parseDeclVarGetSet fake PBDs are created. Ignore them.
277-
/// Example:
278-
/// \code
279-
/// class SR10903 { static var _: Int { 0 } }
280-
/// \endcode
281276

282277
// Commented out for
283278
// validation-test/compiler_crashers_fixed/27962-swift-rebindselfinconstructorexpr-getcalledconstructor.swift
@@ -502,9 +497,6 @@ class ScopeCreator final {
502497
std::vector<ASTNode> expandIfConfigClausesThenCullAndSortElementsOrMembers(
503498
ArrayRef<ASTNode> input) const {
504499
auto cleanedupNodes = sortBySourceRange(cull(expandIfConfigClauses(input)));
505-
// TODO: uncomment when working on not creating two pattern binding decls at
506-
// same location.
507-
// findCollidingPatterns(cleanedupNodes);
508500
return cleanedupNodes;
509501
}
510502

@@ -562,73 +554,6 @@ class ScopeCreator final {
562554
return culled;
563555
}
564556

565-
/// TODO: The parser yields two decls at the same source loc with the same
566-
/// kind. TODO: me when fixing parser's proclivity to create two
567-
/// PatternBindingDecls at the same source location, then move this to
568-
/// ASTVerifier.
569-
///
570-
/// In all cases the first pattern seems to carry the initializer, and the
571-
/// second, the accessor
572-
void findCollidingPatterns(ArrayRef<ASTNode> input) const {
573-
auto dumpPBD = [&](PatternBindingDecl *pbd, const char *which) {
574-
llvm::errs() << "*** " << which
575-
<< " pbd isImplicit: " << pbd->isImplicit()
576-
<< ", #entries: " << pbd->getNumPatternEntries() << " :";
577-
pbd->getSourceRange().print(llvm::errs(), pbd->getASTContext().SourceMgr,
578-
false);
579-
llvm::errs() << "\n";
580-
llvm::errs() << "init: " << pbd->getInit(0) << "\n";
581-
if (pbd->getInit(0)) {
582-
llvm::errs() << "SR (init): ";
583-
pbd->getInit(0)->getSourceRange().print(
584-
llvm::errs(), pbd->getASTContext().SourceMgr, false);
585-
llvm::errs() << "\n";
586-
pbd->getInit(0)->dump(llvm::errs(), 0);
587-
}
588-
llvm::errs() << "vars:\n";
589-
pbd->getPattern(0)->forEachVariable([&](VarDecl *vd) {
590-
llvm::errs() << " " << vd->getName()
591-
<< " implicit: " << vd->isImplicit()
592-
<< " #accs: " << vd->getAllAccessors().size()
593-
<< "\nSR (var):";
594-
vd->getSourceRange().print(llvm::errs(), pbd->getASTContext().SourceMgr,
595-
false);
596-
llvm::errs() << "\nSR (braces)";
597-
vd->getBracesRange().print(llvm::errs(), pbd->getASTContext().SourceMgr,
598-
false);
599-
llvm::errs() << "\n";
600-
for (auto *a : vd->getAllAccessors()) {
601-
llvm::errs() << "SR (acc): ";
602-
a->getSourceRange().print(llvm::errs(),
603-
pbd->getASTContext().SourceMgr, false);
604-
llvm::errs() << "\n";
605-
a->dump(llvm::errs(), 0);
606-
}
607-
});
608-
};
609-
610-
Decl *lastD = nullptr;
611-
for (auto n : input) {
612-
auto *d = n.dyn_cast<Decl *>();
613-
if (!d || !lastD || lastD->getStartLoc() != d->getStartLoc() ||
614-
lastD->getKind() != d->getKind()) {
615-
lastD = d;
616-
continue;
617-
}
618-
if (auto *pbd = dyn_cast<PatternBindingDecl>(lastD))
619-
dumpPBD(pbd, "prev");
620-
if (auto *pbd = dyn_cast<PatternBindingDecl>(d)) {
621-
dumpPBD(pbd, "curr");
622-
ASTScope_unreachable("found colliding pattern binding decls");
623-
}
624-
llvm::errs() << "Two same kind decls at same loc: \n";
625-
lastD->dump(llvm::errs());
626-
llvm::errs() << "and\n";
627-
d->dump(llvm::errs());
628-
ASTScope_unreachable("Two same kind decls; unexpected kinds");
629-
}
630-
}
631-
632557
/// Templated to work on either ASTNodes, Decl*'s, or whatnot.
633558
template <typename Rangeable>
634559
std::vector<Rangeable>
@@ -962,24 +887,6 @@ class NodeAdder
962887
: DeclVisibilityKind::LocalVariable;
963888
auto *insertionPoint = parentScope;
964889
for (auto i : range(patternBinding->getNumPatternEntries())) {
965-
// TODO: Won't need to do so much work to avoid creating one without
966-
// a SourceRange once parser is fixed to not create two
967-
// PatternBindingDecls with same locaiton and getSourceRangeOfThisASTNode
968-
// for PatternEntryDeclScope is simplified to use the PatternEntry's
969-
// source range.
970-
if (!patternBinding->getOriginalInit(i)) {
971-
bool found = false;
972-
patternBinding->getPattern(i)->forEachVariable([&](VarDecl *vd) {
973-
if (!vd->isImplicit())
974-
found = true;
975-
else
976-
found |= llvm::any_of(vd->getAllAccessors(), [&](AccessorDecl *a) {
977-
return isLocalizable(a);
978-
});
979-
});
980-
if (!found)
981-
continue;
982-
}
983890
insertionPoint =
984891
scopeCreator
985892
.ifUniqueConstructExpandAndInsert<PatternEntryDeclScope>(
@@ -1058,15 +965,6 @@ void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder(
1058965
// Accessors are always nested within their abstract storage
1059966
// declaration. The nesting may not be immediate, because subscripts may
1060967
// have intervening scopes for generics.
1061-
AbstractStorageDecl *const enclosingAbstractStorageDecl =
1062-
parent->getEnclosingAbstractStorageDecl().get();
1063-
1064-
std::vector<AccessorDecl *> accessorsToScope;
1065-
// Assume we don't have to deal with inactive clauses of IfConfigs here
1066-
llvm::copy_if(asd->getAllAccessors(), std::back_inserter(accessorsToScope),
1067-
[&](AccessorDecl *ad) {
1068-
return enclosingAbstractStorageDecl == ad->getStorage();
1069-
});
1070968

1071969
// Create scopes for `@differentiable` attributes.
1072970
forEachDifferentiableAttrInSourceOrder(
@@ -1075,9 +973,15 @@ void ScopeCreator::addChildrenForAllLocalizableAccessorsInSourceOrder(
1075973
parent, diffAttr, asd);
1076974
});
1077975

1078-
// Sort in order to include synthesized ones, which are out of order.
1079-
for (auto *accessor : sortBySourceRange(accessorsToScope))
1080-
addToScopeTree(accessor, parent);
976+
AbstractStorageDecl *enclosingAbstractStorageDecl =
977+
parent->getEnclosingAbstractStorageDecl().get();
978+
979+
asd->visitParsedAccessors([&](AccessorDecl *ad) {
980+
assert(enclosingAbstractStorageDecl == ad->getStorage());
981+
(void) enclosingAbstractStorageDecl;
982+
983+
this->addToScopeTree(ad, parent);
984+
});
1081985
}
1082986

1083987
#pragma mark creation helpers
@@ -1693,8 +1597,12 @@ AbstractPatternEntryScope::AbstractPatternEntryScope(
16931597
void AbstractPatternEntryScope::forEachVarDeclWithLocalizableAccessors(
16941598
ScopeCreator &scopeCreator, function_ref<void(VarDecl *)> foundOne) const {
16951599
getPatternEntry().getPattern()->forEachVariable([&](VarDecl *var) {
1696-
if (llvm::any_of(var->getAllAccessors(),
1697-
[&](AccessorDecl *a) { return isLocalizable(a); }))
1600+
bool hasParsedAccessors = false;
1601+
var->visitParsedAccessors([&](AccessorDecl *) {
1602+
hasParsedAccessors = true;
1603+
});
1604+
1605+
if (hasParsedAccessors)
16981606
foundOne(var);
16991607
});
17001608
}
@@ -2023,9 +1931,11 @@ class LocalizableDeclContextCollector : public ASTWalker {
20231931
record(pd->getDefaultArgumentInitContext());
20241932
else if (auto *pbd = dyn_cast<PatternBindingDecl>(D))
20251933
recordInitializers(pbd);
2026-
else if (auto *vd = dyn_cast<VarDecl>(D))
2027-
for (auto *ad : vd->getAllAccessors())
1934+
else if (auto *vd = dyn_cast<VarDecl>(D)) {
1935+
vd->visitParsedAccessors([&](AccessorDecl *ad) {
20281936
ad->walk(*this);
1937+
});
1938+
}
20291939
return ASTWalker::walkToDeclPre(D);
20301940
}
20311941

lib/AST/ASTScopeLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ bool DifferentiableAttributeScope::lookupLocalsOrMembers(
371371
if (auto *afd = dyn_cast<AbstractFunctionDecl>(attributedDeclaration)) {
372372
return visitAbstractFunctionDecl(afd);
373373
} else if (auto *asd = dyn_cast<AbstractStorageDecl>(attributedDeclaration)) {
374-
for (auto *accessor : asd->getAllAccessors())
374+
if (auto *accessor = asd->getParsedAccessor(AccessorKind::Get))
375375
if (visitAbstractFunctionDecl(accessor))
376376
return true;
377377
}

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,6 @@ SourceRange DefaultArgumentInitializerScope::getSourceRangeOfThisASTNode(
247247

248248
SourceRange PatternEntryDeclScope::getSourceRangeOfThisASTNode(
249249
const bool omitAssertions) const {
250-
// TODO: Once the creation of two PatternBindingDecls at same location is
251-
// eliminated, the following may be able to be simplified.
252-
if (!getChildren().empty()) { // why needed???
253-
bool hasOne = false;
254-
getPattern()->forEachVariable([&](VarDecl *) { hasOne = true; });
255-
if (!hasOne)
256-
return SourceRange(); // just the init
257-
if (!getPatternEntry().getInit())
258-
return SourceRange(); // just the var decls
259-
}
260250
return getPatternEntry().getSourceRange();
261251
}
262252

lib/IDE/SyntaxModel.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,9 @@ bool ModelASTWalker::walkToDeclPre(Decl *D) {
990990
if (bracesRange.isValid())
991991
SN.BodyRange = innerCharSourceRangeFromSourceRange(SM, bracesRange);
992992
SourceLoc NRStart = VD->getNameLoc();
993-
SourceLoc NREnd = NRStart.getAdvancedLoc(VD->getName().getLength());
993+
SourceLoc NREnd = (!VD->getName().empty()
994+
? NRStart.getAdvancedLoc(VD->getName().getLength())
995+
: NRStart);
994996
SN.NameRange = CharSourceRange(SM, NRStart, NREnd);
995997
SN.TypeRange = charSourceRangeFromSourceRange(SM,
996998
VD->getTypeSourceRangeForDiagnostics());

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5680,14 +5680,16 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags,
56805680

56815681
/// Parse the brace-enclosed getter and setter for a variable.
56825682
ParserResult<VarDecl>
5683-
Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags,
5683+
Parser::parseDeclVarGetSet(PatternBindingEntry &entry, ParseDeclOptions Flags,
56845684
SourceLoc StaticLoc,
56855685
StaticSpellingKind StaticSpelling,
56865686
SourceLoc VarLoc, bool hasInitializer,
56875687
const DeclAttributes &Attributes,
56885688
SmallVectorImpl<Decl *> &Decls) {
56895689
bool Invalid = false;
5690-
5690+
5691+
auto *pattern = entry.getPattern();
5692+
56915693
// The grammar syntactically requires a simple identifier for the variable
56925694
// name. Complain if that isn't what we got. But for recovery purposes,
56935695
// make an effort to look through other things anyway.
@@ -5730,22 +5732,12 @@ Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags,
57305732
VarDecl::Introducer::Var,
57315733
VarLoc, Identifier(),
57325734
CurDeclContext);
5733-
storage->setImplicit(true);
57345735
storage->setInvalid();
57355736

5736-
Pattern *pattern =
5737+
pattern =
57375738
TypedPattern::createImplicit(Context, new (Context) NamedPattern(storage),
57385739
ErrorType::get(Context));
5739-
PatternBindingEntry entry(pattern, /*EqualLoc*/ SourceLoc(),
5740-
/*Init*/ nullptr, /*InitContext*/ nullptr);
5741-
auto binding = PatternBindingDecl::create(Context, StaticLoc,
5742-
StaticSpelling,
5743-
VarLoc, entry, CurDeclContext);
5744-
binding->setInvalid();
5745-
storage->setParentPatternBinding(binding);
5746-
5747-
Decls.push_back(binding);
5748-
Decls.push_back(storage);
5740+
entry.setPattern(pattern);
57495741
}
57505742

57515743
// Parse getter and setter.
@@ -6157,7 +6149,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
61576149
if (Tok.is(tok::l_brace)) {
61586150
HasAccessors = true;
61596151
auto boundVar =
6160-
parseDeclVarGetSet(pattern, Flags, StaticLoc, StaticSpelling, VarLoc,
6152+
parseDeclVarGetSet(PBDEntries.back(),
6153+
Flags, StaticLoc, StaticSpelling, VarLoc,
61616154
PatternInit != nullptr, Attributes, Decls);
61626155
if (boundVar.hasCodeCompletion())
61636156
return makeResult(makeParserCodeCompletionStatus());

lib/Sema/BuilderTransform.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ class BuilderClosureRewriter
10641064
auto pbd = PatternBindingDecl::create(
10651065
ctx, SourceLoc(), StaticSpellingKind::None, temporaryVar->getLoc(),
10661066
pattern, SourceLoc(), initExpr, dc);
1067+
if (temporaryVar->isImplicit())
1068+
pbd->setImplicit();
10671069
elements.push_back(temporaryVar);
10681070
elements.push_back(pbd);
10691071
}

test/Index/invalid_code.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: %target-swift-ide-test -print-indexed-symbols -include-locals -source-filename %s | %FileCheck %s
22

3-
// CHECK: [[@LINE+1]]:8 | struct/Swift | Int | {{.*}} | Ref | rel: 0
43
var _: Int { get { return 1 } }
54

65
func test() {

test/Parse/pattern_without_variables.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,4 @@ func testVarLetPattern(a : SimpleEnum) {
4040

4141
class SR10903 {
4242
static var _: Int { 0 } //expected-error {{getter/setter can only be defined for a single variable}}
43-
//expected-error@-1 {{property declaration does not bind any variables}}
4443
}

test/SourceKit/DocumentStructure/structure.swift.empty.response

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,10 @@
573573
key.kind: source.lang.swift.decl.var.global,
574574
key.accessibility: source.lang.swift.accessibility.internal,
575575
key.setter_accessibility: source.lang.swift.accessibility.internal,
576-
key.name: "Qtys",
577576
key.offset: 1079,
578-
key.length: 15,
579-
key.nameoffset: 1089,
580-
key.namelength: 4
577+
key.length: 3,
578+
key.nameoffset: 1079,
579+
key.namelength: 0
581580
},
582581
{
583582
key.kind: source.lang.swift.stmt.foreach,

0 commit comments

Comments
 (0)