Skip to content

Commit e087489

Browse files
committed
[BuilderTransform] Move buildCall to ResultBuilder type
1 parent 95d9362 commit e087489

File tree

2 files changed

+59
-47
lines changed

2 files changed

+59
-47
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,15 @@ namespace constraints {
108108
struct ResultBuilder {
109109
private:
110110
DeclContext *DC;
111+
/// An implicit variable that represents `Self` type of the result builder.
112+
VarDecl *BuilderSelf;
111113
Type BuilderType;
112114
llvm::SmallDenseMap<DeclName, bool> SupportedOps;
113115

114116
Identifier BuildOptionalId;
115117

116118
public:
117-
ResultBuilder(DeclContext *DC, Type builderType)
118-
: DC(DC), BuilderType(builderType) {
119-
auto &ctx = DC->getASTContext();
120-
// Use buildOptional(_:) if available, otherwise fall back to buildIf
121-
// when available.
122-
BuildOptionalId =
123-
(supports(ctx.Id_buildOptional) || !supports(ctx.Id_buildIf))
124-
? ctx.Id_buildOptional
125-
: ctx.Id_buildIf;
126-
}
119+
ResultBuilder(ConstraintSystem *CS, DeclContext *DC, Type builderType);
127120

128121
DeclContext *getDeclContext() const { return DC; }
129122

@@ -139,6 +132,10 @@ struct ResultBuilder {
139132
bool checkAvailability = false);
140133

141134
bool supportsOptional() { return supports(getBuildOptionalId()); }
135+
136+
Expr *buildCall(SourceLoc loc, Identifier fnName,
137+
ArrayRef<Expr *> argExprs,
138+
ArrayRef<Identifier> argLabels) const;
142139
};
143140

144141
/// Describes the algorithm to use for trailing closure matching.

lib/Sema/BuilderTransform.cpp

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ class BuilderClosureVisitor
7171

7272
ResultBuilder builder;
7373

74-
/// The variable used as a base for all `build*` operations added
75-
/// by this transform.
76-
VarDecl *builderVar = nullptr;
77-
7874
SkipUnhandledConstructInResultBuilder::UnhandledNode unhandledNode;
7975

8076
/// Whether an error occurred during application of the builder closure,
@@ -96,27 +92,7 @@ class BuilderClosureVisitor
9692
if (!cs)
9793
return nullptr;
9894

99-
SmallVector<Argument, 4> args;
100-
for (auto i : indices(argExprs)) {
101-
auto *expr = argExprs[i];
102-
auto label = argLabels.empty() ? Identifier() : argLabels[i];
103-
auto labelLoc = argLabels.empty() ? SourceLoc() : expr->getStartLoc();
104-
args.emplace_back(labelLoc, label, expr);
105-
}
106-
107-
auto *baseExpr = new (ctx) DeclRefExpr({builderVar}, DeclNameLoc(loc),
108-
/*isImplicit=*/true);
109-
110-
auto memberRef = new (ctx) UnresolvedDotExpr(
111-
baseExpr, loc, DeclNameRef(fnName), DeclNameLoc(loc),
112-
/*implicit=*/true);
113-
memberRef->setFunctionRefKind(FunctionRefKind::SingleApply);
114-
115-
auto openLoc = args.empty() ? loc : argExprs.front()->getStartLoc();
116-
auto closeLoc = args.empty() ? loc : argExprs.back()->getEndLoc();
117-
118-
auto *argList = ArgumentList::createImplicit(ctx, openLoc, args, closeLoc);
119-
return CallExpr::createImplicit(ctx, memberRef, argList);
95+
return builder.buildCall(loc, fnName, argExprs, argLabels);
12096
}
12197

12298
/// Build an implicit variable in this context.
@@ -175,20 +151,9 @@ class BuilderClosureVisitor
175151
public:
176152
BuilderClosureVisitor(ASTContext &ctx, ConstraintSystem *cs, DeclContext *dc,
177153
Type builderType, Type bodyResultType)
178-
: cs(cs), dc(dc), ctx(ctx),
179-
builder(dc, cs ? cs->simplifyType(builderType) : builderType) {
154+
: cs(cs), dc(dc), ctx(ctx), builder(cs, dc, builderType) {
180155
applied.builderType = builder.getType();
181156
applied.bodyResultType = bodyResultType;
182-
183-
// If we are about to generate constraints, let's establish builder
184-
// variable for the base of `build*` calls.
185-
if (cs) {
186-
builderVar = new (ctx) VarDecl(
187-
/*isStatic=*/false, VarDecl::Introducer::Let,
188-
/*nameLoc=*/SourceLoc(), ctx.Id_builderSelf, dc);
189-
builderVar->setImplicit();
190-
cs->setType(builderVar, MetatypeType::get(builder.getType()));
191-
}
192157
}
193158

194159
/// Apply the builder transform to the given statement.
@@ -2198,6 +2163,26 @@ void swift::printResultBuilderBuildFunction(
21982163
}
21992164
}
22002165

2166+
ResultBuilder::ResultBuilder(ConstraintSystem *CS, DeclContext *DC,
2167+
Type builderType)
2168+
: DC(DC), BuilderType(CS ? CS->simplifyType(builderType) : builderType) {
2169+
auto &ctx = DC->getASTContext();
2170+
// Use buildOptional(_:) if available, otherwise fall back to buildIf
2171+
// when available.
2172+
BuildOptionalId =
2173+
(supports(ctx.Id_buildOptional) || !supports(ctx.Id_buildIf))
2174+
? ctx.Id_buildOptional
2175+
: ctx.Id_buildIf;
2176+
2177+
if (CS) {
2178+
BuilderSelf = new (ctx) VarDecl(
2179+
/*isStatic=*/false, VarDecl::Introducer::Let,
2180+
/*nameLoc=*/SourceLoc(), ctx.Id_builderSelf, DC);
2181+
BuilderSelf->setImplicit();
2182+
CS->setType(BuilderSelf, MetatypeType::get(BuilderType));
2183+
}
2184+
}
2185+
22012186
bool ResultBuilder::supports(Identifier fnBaseName,
22022187
ArrayRef<Identifier> argLabels,
22032188
bool checkAvailability) {
@@ -2211,3 +2196,33 @@ bool ResultBuilder::supports(Identifier fnBaseName,
22112196
BuilderType, DC, fnBaseName, argLabels, /*allResults*/ {},
22122197
checkAvailability);
22132198
}
2199+
2200+
Expr *ResultBuilder::buildCall(SourceLoc loc, Identifier fnName,
2201+
ArrayRef<Expr *> argExprs,
2202+
ArrayRef<Identifier> argLabels) const {
2203+
assert(BuilderSelf);
2204+
2205+
auto &ctx = DC->getASTContext();
2206+
2207+
SmallVector<Argument, 4> args;
2208+
for (auto i : indices(argExprs)) {
2209+
auto *expr = argExprs[i];
2210+
auto label = argLabels.empty() ? Identifier() : argLabels[i];
2211+
auto labelLoc = argLabels.empty() ? SourceLoc() : expr->getStartLoc();
2212+
args.emplace_back(labelLoc, label, expr);
2213+
}
2214+
2215+
auto *baseExpr = new (ctx) DeclRefExpr({BuilderSelf}, DeclNameLoc(loc),
2216+
/*isImplicit=*/true);
2217+
2218+
auto memberRef = new (ctx)
2219+
UnresolvedDotExpr(baseExpr, loc, DeclNameRef(fnName), DeclNameLoc(loc),
2220+
/*implicit=*/true);
2221+
memberRef->setFunctionRefKind(FunctionRefKind::SingleApply);
2222+
2223+
auto openLoc = args.empty() ? loc : argExprs.front()->getStartLoc();
2224+
auto closeLoc = args.empty() ? loc : argExprs.back()->getEndLoc();
2225+
2226+
auto *argList = ArgumentList::createImplicit(ctx, openLoc, args, closeLoc);
2227+
return CallExpr::createImplicit(ctx, memberRef, argList);
2228+
}

0 commit comments

Comments
 (0)