@@ -71,10 +71,6 @@ class BuilderClosureVisitor
71
71
72
72
ResultBuilder builder;
73
73
74
- // / The variable used as a base for all `build*` operations added
75
- // / by this transform.
76
- VarDecl *builderVar = nullptr ;
77
-
78
74
SkipUnhandledConstructInResultBuilder::UnhandledNode unhandledNode;
79
75
80
76
// / Whether an error occurred during application of the builder closure,
@@ -96,27 +92,7 @@ class BuilderClosureVisitor
96
92
if (!cs)
97
93
return nullptr ;
98
94
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);
120
96
}
121
97
122
98
// / Build an implicit variable in this context.
@@ -175,20 +151,9 @@ class BuilderClosureVisitor
175
151
public:
176
152
BuilderClosureVisitor (ASTContext &ctx, ConstraintSystem *cs, DeclContext *dc,
177
153
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) {
180
155
applied.builderType = builder.getType ();
181
156
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
- }
192
157
}
193
158
194
159
// / Apply the builder transform to the given statement.
@@ -2198,6 +2163,26 @@ void swift::printResultBuilderBuildFunction(
2198
2163
}
2199
2164
}
2200
2165
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
+
2201
2186
bool ResultBuilder::supports (Identifier fnBaseName,
2202
2187
ArrayRef<Identifier> argLabels,
2203
2188
bool checkAvailability) {
@@ -2211,3 +2196,33 @@ bool ResultBuilder::supports(Identifier fnBaseName,
2211
2196
BuilderType, DC, fnBaseName, argLabels, /* allResults*/ {},
2212
2197
checkAvailability);
2213
2198
}
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