@@ -128,69 +128,116 @@ static std::string extractLiteralOutput(Expr *expr) {
128
128
return LiteralOutput;
129
129
}
130
130
131
- static std::shared_ptr<CompileTimeValue>
132
- extractPropertyInitializationValue (VarDecl *propertyDecl) {
133
- auto binding = propertyDecl->getParentPatternBinding ();
134
- if (binding) {
135
- auto originalInit = binding->getOriginalInit (0 );
136
- if (originalInit) {
137
- auto literalOutput = extractLiteralOutput (originalInit);
138
- if (!literalOutput.empty ()) {
139
- return std::make_shared<RawLiteralValue>(literalOutput);
140
- }
131
+ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue (Expr *expr) {
132
+ switch (expr->getKind ()) {
133
+ case ExprKind::Array:
134
+ case ExprKind::Dictionary:
135
+ case ExprKind::BooleanLiteral:
136
+ case ExprKind::IntegerLiteral:
137
+ case ExprKind::FloatLiteral:
138
+ case ExprKind::NilLiteral:
139
+ case ExprKind::StringLiteral: {
140
+ std::string literalOutput;
141
+ llvm::raw_string_ostream OutputStream (literalOutput);
142
+ expr->printConstExprValue (&OutputStream, nullptr );
143
+
144
+ if (literalOutput.empty ()) {
145
+ return std::make_shared<RuntimeValue>();
146
+ }
141
147
142
- if (auto callExpr = dyn_cast<CallExpr>(originalInit)) {
143
- if (callExpr->getFn ()->getKind () != ExprKind::ConstructorRefCall) {
144
- return std::make_shared<RuntimeValue>();
145
- }
148
+ return std::make_shared<RawLiteralValue>(literalOutput);
149
+ }
146
150
147
- std::vector<FunctionParameter> parameters;
148
- const auto args = callExpr->getArgs ();
149
- for (auto arg : *args) {
150
- auto label = arg.getLabel ().str ().str ();
151
- auto expr = arg.getExpr ();
151
+ case ExprKind::Tuple: {
152
+ auto tupleExpr = cast<TupleExpr>(expr);
152
153
153
- switch (expr->getKind ()) {
154
- case ExprKind::DefaultArgument: {
155
- auto defaultArgument = cast<DefaultArgumentExpr>(expr);
156
- auto *decl = defaultArgument->getParamDecl ();
154
+ std::vector<TupleElement> elements;
155
+ if (tupleExpr->hasElementNames ()) {
156
+ for (auto pair :
157
+ llvm::zip (tupleExpr->getElements (), tupleExpr->getElementNames ())) {
158
+ auto elementExpr = std::get<0 >(pair);
159
+ auto elementName = std::get<1 >(pair);
157
160
158
- if (decl-> hasDefaultExpr ()) {
159
- literalOutput =
160
- extractLiteralOutput (decl-> getTypeCheckedDefaultExpr ());
161
- }
161
+ Optional<std::string> label =
162
+ elementName. empty ()
163
+ ? Optional<std::string>()
164
+ : Optional<std::string>(elementName. str (). str ());
162
165
163
- break ;
164
- }
165
- default :
166
- literalOutput = extractLiteralOutput (expr);
167
- break ;
168
- }
166
+ elements.push_back ({label, elementExpr->getType (),
167
+ extractCompileTimeValue (elementExpr)});
168
+ }
169
+ } else {
170
+ for (auto elementExpr : tupleExpr->getElements ()) {
171
+ elements.push_back ({Optional<std::string>(), elementExpr->getType (),
172
+ extractCompileTimeValue (elementExpr)});
173
+ }
174
+ }
175
+ return std::make_shared<TupleValue>(elements);
176
+ }
169
177
170
- if (literalOutput.empty ()) {
171
- parameters.push_back (
172
- {label, expr->getType (), std::make_shared<RuntimeValue>()});
173
- } else {
174
- parameters.push_back (
175
- {label, expr->getType (),
176
- std::make_shared<RawLiteralValue>(literalOutput)});
177
- }
178
+ case ExprKind::Call: {
179
+ auto callExpr = cast<CallExpr>(expr);
180
+
181
+ if (callExpr->getFn ()->getKind () != ExprKind::ConstructorRefCall) {
182
+ return std::make_shared<RuntimeValue>();
183
+ }
184
+
185
+ std::vector<FunctionParameter> parameters;
186
+ const auto args = callExpr->getArgs ();
187
+ for (auto arg : *args) {
188
+ auto label = arg.getLabel ().str ().str ();
189
+ auto expr = arg.getExpr ();
190
+
191
+ std::string literalOutput;
192
+ switch (expr->getKind ()) {
193
+ case ExprKind::DefaultArgument: {
194
+ auto defaultArgument = cast<DefaultArgumentExpr>(expr);
195
+ auto *decl = defaultArgument->getParamDecl ();
196
+
197
+ if (decl->hasDefaultExpr ()) {
198
+ literalOutput =
199
+ extractLiteralOutput (decl->getTypeCheckedDefaultExpr ());
178
200
}
179
201
180
- auto name = toFullyQualifiedTypeNameString (callExpr->getType ());
181
- return std::make_shared<InitCallValue>(name, parameters);
202
+ break ;
203
+ }
204
+ default :
205
+ literalOutput = extractLiteralOutput (expr);
206
+ break ;
207
+ }
208
+
209
+ if (literalOutput.empty ()) {
210
+ parameters.push_back (
211
+ {label, expr->getType (), std::make_shared<RuntimeValue>()});
212
+ } else {
213
+ parameters.push_back (
214
+ {label, expr->getType (),
215
+ std::make_shared<RawLiteralValue>(literalOutput)});
182
216
}
183
217
}
218
+
219
+ auto name = toFullyQualifiedTypeNameString (callExpr->getType ());
220
+ return std::make_shared<InitCallValue>(name, parameters);
221
+ }
222
+
223
+ default :
224
+ return std::make_shared<RuntimeValue>();
225
+ }
226
+ }
227
+
228
+ static std::shared_ptr<CompileTimeValue>
229
+ extractPropertyInitializationValue (VarDecl *propertyDecl) {
230
+ if (auto binding = propertyDecl->getParentPatternBinding ()) {
231
+ if (auto originalInit = binding->getOriginalInit (0 )) {
232
+ return extractCompileTimeValue (originalInit);
233
+ }
184
234
}
185
235
186
236
if (auto accessorDecl = propertyDecl->getAccessor (AccessorKind::Get)) {
187
237
auto node = accessorDecl->getTypecheckedBody ()->getFirstElement ();
188
238
if (node.is <Stmt *>()) {
189
239
if (auto returnStmt = dyn_cast<ReturnStmt>(node.get <Stmt *>())) {
190
- auto expr = returnStmt->getResult ();
191
- std::string LiteralOutput = extractLiteralOutput (expr);
192
- if (!LiteralOutput.empty ())
193
- return std::make_shared<RawLiteralValue>(LiteralOutput);
240
+ return extractCompileTimeValue (returnStmt->getResult ());
194
241
}
195
242
}
196
243
}
@@ -284,6 +331,22 @@ void writeValue(llvm::json::OStream &JSON,
284
331
break ;
285
332
}
286
333
334
+ case CompileTimeValue::ValueKind::Tuple: {
335
+ auto tupleValue = cast<TupleValue>(value);
336
+
337
+ JSON.attribute (" valueKind" , " Tuple" );
338
+ JSON.attributeArray (" value" , [&] {
339
+ for (auto TV : tupleValue->getElements ()) {
340
+ JSON.object ([&] {
341
+ JSON.attribute (" label" , TV.Label );
342
+ JSON.attribute (" type" , toFullyQualifiedTypeNameString (TV.Type ));
343
+ writeValue (JSON, TV.Value );
344
+ });
345
+ }
346
+ });
347
+ break ;
348
+ }
349
+
287
350
case CompileTimeValue::ValueKind::Builder: {
288
351
JSON.attribute (" valueKind" , " Builder" );
289
352
break ;
0 commit comments