Skip to content

Commit a3035eb

Browse files
committed
[NFC] Add helpers for unresolved AST node synthesis
This change adds UnresolvedDotExpr::createImplicit() and UnresolvedDeclRefExpr::createImplicit() helpers. These calls simplify several tedious bits of code synthesis that would otherwise become even more tedious with DeclNameRef in the picture.
1 parent 027e4b7 commit a3035eb

7 files changed

+79
-71
lines changed

include/swift/AST/Expr.h

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,26 @@ class UnresolvedDeclRefExpr : public Expr {
14991499
static_cast<unsigned>(Loc.isCompound() ? FunctionRefKind::Compound
15001500
: FunctionRefKind::Unapplied);
15011501
}
1502-
1502+
1503+
static UnresolvedDeclRefExpr *createImplicit(
1504+
ASTContext &C, DeclName name,
1505+
DeclRefKind refKind = DeclRefKind::Ordinary) {
1506+
return new (C) UnresolvedDeclRefExpr(name, refKind,
1507+
DeclNameLoc());
1508+
}
1509+
1510+
static UnresolvedDeclRefExpr *createImplicit(
1511+
ASTContext &C, DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
1512+
return UnresolvedDeclRefExpr::createImplicit(C,
1513+
DeclName(C, baseName, argLabels));
1514+
}
1515+
1516+
static UnresolvedDeclRefExpr *createImplicit(
1517+
ASTContext &C, DeclBaseName baseName, ParameterList *paramList) {
1518+
return UnresolvedDeclRefExpr::createImplicit(C,
1519+
DeclName(C, baseName, paramList));
1520+
}
1521+
15031522
bool hasName() const { return static_cast<bool>(Name); }
15041523
DeclName getName() const { return Name; }
15051524

@@ -2407,7 +2426,28 @@ class UnresolvedDotExpr : public Expr {
24072426
static_cast<unsigned>(NameLoc.isCompound() ? FunctionRefKind::Compound
24082427
: FunctionRefKind::Unapplied);
24092428
}
2410-
2429+
2430+
static UnresolvedDotExpr *createImplicit(
2431+
ASTContext &C, Expr *base, DeclName name) {
2432+
return new (C) UnresolvedDotExpr(base, SourceLoc(),
2433+
name, DeclNameLoc(),
2434+
/*implicit=*/true);
2435+
}
2436+
2437+
static UnresolvedDotExpr *createImplicit(
2438+
ASTContext &C, Expr *base,
2439+
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
2440+
return UnresolvedDotExpr::createImplicit(C, base,
2441+
DeclName(C, baseName, argLabels));
2442+
}
2443+
2444+
static UnresolvedDotExpr *createImplicit(
2445+
ASTContext &C, Expr *base,
2446+
DeclBaseName baseName, ParameterList *paramList) {
2447+
return UnresolvedDotExpr::createImplicit(C, base,
2448+
DeclName(C, baseName, paramList));
2449+
}
2450+
24112451
SourceLoc getLoc() const {
24122452
if (NameLoc.isValid())
24132453
return NameLoc.getBaseNameLoc();

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,10 @@ static CallExpr *createContainerKeyedByCall(ASTContext &C, DeclContext *DC,
415415
keyedByDecl->setSpecifier(ParamSpecifier::Default);
416416
keyedByDecl->setInterfaceType(returnType);
417417

418-
// container(keyedBy:) method name
419-
auto *paramList = ParameterList::createWithoutLoc(keyedByDecl);
420-
DeclName callName(C, C.Id_container, paramList);
421-
422418
// base.container(keyedBy:) expr
423-
auto *unboundCall = new (C) UnresolvedDotExpr(base, SourceLoc(), callName,
424-
DeclNameLoc(),
425-
/*Implicit=*/true);
419+
auto *paramList = ParameterList::createWithoutLoc(keyedByDecl);
420+
auto *unboundCall = UnresolvedDotExpr::createImplicit(C, base, C.Id_container,
421+
paramList);
426422

427423
// CodingKeys.self expr
428424
auto *codingKeysExpr = TypeExpr::createForDecl(SourceLoc(),
@@ -583,12 +579,10 @@ deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl, void *) {
583579

584580
// encode(_:forKey:)/encodeIfPresent(_:forKey:)
585581
auto methodName = useIfPresentVariant ? C.Id_encodeIfPresent : C.Id_encode;
586-
587582
SmallVector<Identifier, 2> argNames{Identifier(), C.Id_forKey};
588-
DeclName name(C, methodName, argNames);
589-
auto *encodeCall = new (C) UnresolvedDotExpr(containerExpr, SourceLoc(),
590-
name, DeclNameLoc(),
591-
/*Implicit=*/true);
583+
584+
auto *encodeCall = UnresolvedDotExpr::createImplicit(C, containerExpr,
585+
methodName, argNames);
592586

593587
// container.encode(self.x, forKey: CodingKeys.x)
594588
Expr *args[2] = {varExpr, keyExpr};
@@ -608,9 +602,7 @@ deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl, void *) {
608602
// Need to generate `try super.encode(to: container.superEncoder())`
609603

610604
// superEncoder()
611-
auto *method = new (C) UnresolvedDeclRefExpr(DeclName(C.Id_superEncoder),
612-
DeclRefKind::Ordinary,
613-
DeclNameLoc());
605+
auto *method = UnresolvedDeclRefExpr::createImplicit(C, C.Id_superEncoder);
614606

615607
// container.superEncoder()
616608
auto *superEncoderRef = new (C) DotSyntaxCallExpr(containerExpr,
@@ -814,10 +806,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
814806

815807
// decode(_:forKey:)/decodeIfPresent(_:forKey:)
816808
SmallVector<Identifier, 2> argNames{Identifier(), C.Id_forKey};
817-
DeclName name(C, methodName, argNames);
818-
auto *decodeCall = new (C) UnresolvedDotExpr(containerExpr, SourceLoc(),
819-
name, DeclNameLoc(),
820-
/*Implicit=*/true);
809+
auto *decodeCall = UnresolvedDotExpr::createImplicit(
810+
C, containerExpr, methodName, argNames);
821811

822812
// container.decode(Type.self, forKey: CodingKeys.x)
823813
Expr *args[2] = {targetExpr, keyExpr};
@@ -830,10 +820,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
830820
/*Implicit=*/true);
831821

832822
auto *selfRef = DerivedConformance::createSelfDeclRef(initDecl);
833-
auto *varExpr = new (C) UnresolvedDotExpr(selfRef, SourceLoc(),
834-
DeclName(varDecl->getName()),
835-
DeclNameLoc(),
836-
/*implicit=*/true);
823+
auto *varExpr = UnresolvedDotExpr::createImplicit(C, selfRef,
824+
varDecl->getFullName());
837825
auto *assignExpr = new (C) AssignExpr(varExpr, SourceLoc(), tryExpr,
838826
/*Implicit=*/true);
839827
statements.push_back(assignExpr);
@@ -849,9 +837,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
849837

850838
// container.superDecoder
851839
auto *superDecoderRef =
852-
new (C) UnresolvedDotExpr(containerExpr, SourceLoc(),
853-
DeclName(C.Id_superDecoder),
854-
DeclNameLoc(), /*Implicit=*/true);
840+
UnresolvedDotExpr::createImplicit(C, containerExpr,
841+
C.Id_superDecoder);
855842

856843
// container.superDecoder()
857844
auto *superDecoderCall =
@@ -863,10 +850,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
863850
SourceLoc(), /*Implicit=*/true);
864851

865852
// super.init(from:)
866-
auto initName = DeclName(C, DeclBaseName::createConstructor(), C.Id_from);
867-
auto *initCall = new (C) UnresolvedDotExpr(superRef, SourceLoc(),
868-
initName, DeclNameLoc(),
869-
/*Implicit=*/true);
853+
auto *initCall = UnresolvedDotExpr::createImplicit(
854+
C, superRef, DeclBaseName::createConstructor(), {C.Id_from});
870855

871856
// super.decode(from: container.superDecoder())
872857
Expr *args[1] = {superDecoderCall};
@@ -899,9 +884,8 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
899884
SourceLoc(), /*Implicit=*/true);
900885

901886
// super.init()
902-
auto *superInitRef = new (C) UnresolvedDotExpr(superRef, SourceLoc(),
903-
initName, DeclNameLoc(),
904-
/*Implicit=*/true);
887+
auto *superInitRef = UnresolvedDotExpr::createImplicit(C, superRef,
888+
initName);
905889
// super.init() call
906890
Expr *callExpr = CallExpr::createImplicit(C, superInitRef,
907891
ArrayRef<Expr *>(),

lib/Sema/DerivedConformanceCodingKey.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ deriveRawValueReturn(AbstractFunctionDecl *funcDecl, void *) {
5050
auto &C = parentDC->getASTContext();
5151

5252
auto *selfRef = DerivedConformance::createSelfDeclRef(funcDecl);
53-
auto *memberRef = new (C) UnresolvedDotExpr(selfRef, SourceLoc(),
54-
C.Id_rawValue, DeclNameLoc(),
55-
/*Implicit=*/true);
53+
auto *memberRef =
54+
UnresolvedDotExpr::createImplicit(C, selfRef, C.Id_rawValue);
5655

5756
auto *returnStmt = new (C) ReturnStmt(SourceLoc(), memberRef);
5857
auto *body = BraceStmt::create(C, SourceLoc(), ASTNode(returnStmt),
@@ -84,13 +83,10 @@ deriveRawValueInit(AbstractFunctionDecl *initDecl, void *) {
8483
rawValueDecl->setImplicit();
8584
auto *paramList = ParameterList::createWithoutLoc(rawValueDecl);
8685

87-
// init(rawValue:) constructor name
88-
DeclName ctorName(C, DeclBaseName::createConstructor(), paramList);
89-
9086
// self.init(rawValue:) expr
9187
auto *selfRef = DerivedConformance::createSelfDeclRef(initDecl);
92-
auto *initExpr = new (C) UnresolvedDotExpr(selfRef, SourceLoc(), ctorName,
93-
DeclNameLoc(), /*Implicit=*/true);
88+
auto *initExpr = UnresolvedDotExpr::createImplicit(
89+
C, selfRef, DeclBaseName::createConstructor(), paramList);
9490

9591
// Bind the value param in self.init(rawValue: {string,int}Value).
9692
Expr *args[1] = {valueParamExpr};

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -833,11 +833,9 @@ static CallExpr *createHasherCombineCall(ASTContext &C,
833833
Expr *hashable) {
834834
Expr *hasherExpr = new (C) DeclRefExpr(ConcreteDeclRef(hasher),
835835
DeclNameLoc(), /*implicit*/ true);
836-
DeclName name(C, C.Id_combine, {Identifier()});
837836
// hasher.combine(_:)
838-
auto *combineCall = new (C) UnresolvedDotExpr(hasherExpr, SourceLoc(),
839-
name, DeclNameLoc(),
840-
/*implicit*/ true);
837+
auto *combineCall = UnresolvedDotExpr::createImplicit(
838+
C, hasherExpr, C.Id_combine, {Identifier()});
841839

842840
// hasher.combine(hashable)
843841
return CallExpr::createImplicit(C, combineCall, {hashable}, {Identifier()});
@@ -912,9 +910,8 @@ deriveBodyHashable_compat_hashInto(AbstractFunctionDecl *hashIntoDecl, void *) {
912910
auto selfDecl = hashIntoDecl->getImplicitSelfDecl();
913911
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
914912
/*implicit*/ true);
915-
auto hashValueExpr = new (C) UnresolvedDotExpr(selfRef, SourceLoc(),
916-
C.Id_hashValue, DeclNameLoc(),
917-
/*implicit*/ true);
913+
auto hashValueExpr = UnresolvedDotExpr::createImplicit(C, selfRef,
914+
C.Id_hashValue);
918915
auto hasherParam = hashIntoDecl->getParameters()->get(0);
919916
auto hasherExpr = createHasherCombineCall(C, hasherParam, hashValueExpr);
920917

@@ -938,9 +935,8 @@ deriveBodyHashable_enum_rawValue_hashInto(
938935

939936
// generate: self.rawValue
940937
auto *selfRef = DerivedConformance::createSelfDeclRef(hashIntoDecl);
941-
auto *rawValueRef = new (C) UnresolvedDotExpr(selfRef, SourceLoc(),
942-
C.Id_rawValue, DeclNameLoc(),
943-
/*Implicit=*/true);
938+
auto *rawValueRef = UnresolvedDotExpr::createImplicit(C, selfRef,
939+
C.Id_rawValue);
944940

945941
// generate: hasher.combine(discriminator)
946942
auto hasherParam = hashIntoDecl->getParameters()->get(0);

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,8 @@ deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl, void *) {
9191
// a bitcast.
9292

9393
// return unsafeBitCast(self, to: RawType.self)
94-
DeclName name(C, C.getIdentifier("unsafeBitCast"), {Identifier(), C.Id_to});
95-
auto functionRef = new (C) UnresolvedDeclRefExpr(name,
96-
DeclRefKind::Ordinary,
97-
DeclNameLoc());
94+
auto functionRef = UnresolvedDeclRefExpr::createImplicit(
95+
C, C.getIdentifier("unsafeBitCast"), {Identifier(), C.Id_to});
9896
auto selfRef = DerivedConformance::createSelfDeclRef(toRawDecl);
9997
auto bareTypeExpr = TypeExpr::createImplicit(rawTy, C);
10098
auto typeExpr = new (C) DotSelfExpr(bareTypeExpr, SourceLoc(), SourceLoc());
@@ -374,9 +372,8 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl, void *) {
374372
Expr *switchArg = rawRef;
375373
if (isStringEnum) {
376374
// Call _findStringSwitchCase with an array of strings as argument.
377-
auto *Fun = new (C) UnresolvedDeclRefExpr(
378-
C.getIdentifier("_findStringSwitchCase"),
379-
DeclRefKind::Ordinary, DeclNameLoc());
375+
auto *Fun = UnresolvedDeclRefExpr::createImplicit(
376+
C, C.getIdentifier("_findStringSwitchCase"));
380377
auto *strArray = ArrayExpr::create(C, SourceLoc(), stringExprs, {},
381378
SourceLoc());;
382379
Identifier tableId = C.getIdentifier("cases");

lib/Sema/TypeCheckStmt.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,10 +1905,8 @@ static Expr* constructCallToSuperInit(ConstructorDecl *ctor,
19051905
ASTContext &Context = ctor->getASTContext();
19061906
Expr *superRef = new (Context) SuperRefExpr(ctor->getImplicitSelfDecl(),
19071907
SourceLoc(), /*Implicit=*/true);
1908-
Expr *r = new (Context) UnresolvedDotExpr(superRef, SourceLoc(),
1909-
DeclBaseName::createConstructor(),
1910-
DeclNameLoc(),
1911-
/*Implicit=*/true);
1908+
Expr *r = UnresolvedDotExpr::createImplicit(
1909+
Context, superRef, DeclBaseName::createConstructor());
19121910
r = CallExpr::createImplicit(Context, r, { }, { });
19131911

19141912
if (ctor->hasThrows())

lib/Sema/TypeCheckStorage.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -800,18 +800,15 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
800800

801801
// Key path referring to the property being accessed.
802802
Expr *propertyKeyPath = new (ctx) KeyPathDotExpr(SourceLoc());
803-
propertyKeyPath = new (ctx) UnresolvedDotExpr(
804-
propertyKeyPath, SourceLoc(),
805-
enclosingSelfAccess->accessedProperty->getFullName(), DeclNameLoc(),
806-
/*Implicit=*/true);
803+
propertyKeyPath = UnresolvedDotExpr::createImplicit(ctx, propertyKeyPath,
804+
enclosingSelfAccess->accessedProperty->getFullName());
807805
propertyKeyPath = new (ctx) KeyPathExpr(
808806
SourceLoc(), nullptr, propertyKeyPath);
809807

810808
// Key path referring to the backing storage property.
811809
Expr *storageKeyPath = new (ctx) KeyPathDotExpr(SourceLoc());
812-
storageKeyPath = new (ctx) UnresolvedDotExpr(
813-
storageKeyPath, SourceLoc(), storage->getFullName(), DeclNameLoc(),
814-
/*Implicit=*/true);
810+
storageKeyPath = UnresolvedDotExpr::createImplicit(ctx, storageKeyPath,
811+
storage->getFullName());
815812
storageKeyPath = new (ctx) KeyPathExpr(
816813
SourceLoc(), nullptr, storageKeyPath);
817814
Expr *args[3] = {

0 commit comments

Comments
 (0)