10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
- #include " swift/Basic/TypeID.h"
14
13
#include " swift/ConstExtract/ConstExtract.h"
15
- #include " swift/ConstExtract/ConstExtractRequests.h"
16
14
#include " swift/AST/ASTContext.h"
17
15
#include " swift/AST/ASTWalker.h"
18
16
#include " swift/AST/Decl.h"
21
19
#include " swift/AST/Evaluator.h"
22
20
#include " swift/AST/SourceFile.h"
23
21
#include " swift/AST/TypeCheckRequests.h"
22
+ #include " swift/Basic/TypeID.h"
23
+ #include " swift/ConstExtract/ConstExtractRequests.h"
24
+ #include " swift/Subsystems.h"
25
+ #include " llvm/ADT/PointerUnion.h"
24
26
#include " llvm/ADT/StringRef.h"
25
27
#include " llvm/Support/JSON.h"
26
28
#include " llvm/Support/YAMLParser.h"
27
29
#include " llvm/Support/YAMLTraits.h"
28
- #include " swift/Subsystems.h"
29
30
30
31
#include < set>
31
32
#include < sstream>
@@ -119,17 +120,66 @@ parseProtocolListFromFile(StringRef protocolListFilePath,
119
120
return true ;
120
121
}
121
122
123
+ static std::string extractLiteralOutput (Expr *expr) {
124
+ std::string LiteralOutput;
125
+ llvm::raw_string_ostream OutputStream (LiteralOutput);
126
+ expr->printConstExprValue (&OutputStream, nullptr );
127
+
128
+ return LiteralOutput;
129
+ }
130
+
122
131
static std::shared_ptr<CompileTimeValue>
123
132
extractPropertyInitializationValue (VarDecl *propertyDecl) {
124
133
auto binding = propertyDecl->getParentPatternBinding ();
125
134
if (binding) {
126
135
auto originalInit = binding->getOriginalInit (0 );
127
136
if (originalInit) {
128
- std::string LiteralOutput;
129
- llvm::raw_string_ostream OutputStream (LiteralOutput);
130
- originalInit->printConstExprValue (&OutputStream, nullptr );
131
- if (!LiteralOutput.empty ())
132
- return std::make_shared<RawLiteralValue>(LiteralOutput);
137
+ auto literalOutput = extractLiteralOutput (originalInit);
138
+ if (!literalOutput.empty ()) {
139
+ return std::make_shared<RawLiteralValue>(literalOutput);
140
+ }
141
+
142
+ if (auto callExpr = dyn_cast<CallExpr>(originalInit)) {
143
+ if (callExpr->getFn ()->getKind () != ExprKind::ConstructorRefCall) {
144
+ return std::make_shared<RuntimeValue>();
145
+ }
146
+
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 ();
152
+
153
+ switch (expr->getKind ()) {
154
+ case ExprKind::DefaultArgument: {
155
+ auto defaultArgument = cast<DefaultArgumentExpr>(expr);
156
+ auto *decl = defaultArgument->getParamDecl ();
157
+
158
+ if (decl->hasDefaultExpr ()) {
159
+ literalOutput =
160
+ extractLiteralOutput (decl->getTypeCheckedDefaultExpr ());
161
+ }
162
+
163
+ break ;
164
+ }
165
+ default :
166
+ literalOutput = extractLiteralOutput (expr);
167
+ break ;
168
+ }
169
+
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
+ }
179
+
180
+ auto name = toFullyQualifiedTypeNameString (callExpr->getType ());
181
+ return std::make_shared<InitCallValue>(name, parameters);
182
+ }
133
183
}
134
184
}
135
185
@@ -138,9 +188,7 @@ extractPropertyInitializationValue(VarDecl *propertyDecl) {
138
188
if (node.is <Stmt *>()) {
139
189
if (auto returnStmt = dyn_cast<ReturnStmt>(node.get <Stmt *>())) {
140
190
auto expr = returnStmt->getResult ();
141
- std::string LiteralOutput;
142
- llvm::raw_string_ostream OutputStream (LiteralOutput);
143
- expr->printConstExprValue (&OutputStream, nullptr );
191
+ std::string LiteralOutput = extractLiteralOutput (expr);
144
192
if (!LiteralOutput.empty ())
145
193
return std::make_shared<RawLiteralValue>(LiteralOutput);
146
194
}
@@ -207,33 +255,49 @@ gatherConstValuesForPrimary(const std::unordered_set<std::string> &Protocols,
207
255
return Result;
208
256
}
209
257
210
- std::string toString (const CompileTimeValue *Value) {
211
- switch (Value->getKind ()) {
212
- case CompileTimeValue::RawLiteral:
213
- return cast<RawLiteralValue>(Value)->getValue ();
214
- case CompileTimeValue::InitCall:
215
- // TODO
216
- case CompileTimeValue::Builder:
217
- // TODO
218
- case CompileTimeValue::Dictionary:
219
- // TODO
220
- case CompileTimeValue::Runtime:
221
- return " Unknown" ;
258
+ void writeValue (llvm::json::OStream &JSON,
259
+ std::shared_ptr<CompileTimeValue> Value) {
260
+ auto value = Value.get ();
261
+ switch (value->getKind ()) {
262
+ case CompileTimeValue::ValueKind::RawLiteral: {
263
+ JSON.attribute (" valueKind" , " RawLiteral" );
264
+ JSON.attribute (" value" , cast<RawLiteralValue>(value)->getValue ());
265
+ break ;
222
266
}
223
- }
224
267
225
- std::string toString (CompileTimeValue::ValueKind Kind) {
226
- switch (Kind) {
227
- case CompileTimeValue::ValueKind::RawLiteral:
228
- return " RawLiteral" ;
229
- case CompileTimeValue::ValueKind::InitCall:
230
- return " InitCall" ;
231
- case CompileTimeValue::ValueKind::Builder:
232
- return " Builder" ;
233
- case CompileTimeValue::ValueKind::Dictionary:
234
- return " Dictionary" ;
235
- case CompileTimeValue::ValueKind::Runtime:
236
- return " Runtime" ;
268
+ case CompileTimeValue::ValueKind::InitCall: {
269
+ auto initCallValue = cast<InitCallValue>(value);
270
+
271
+ JSON.attribute (" valueKind" , " InitCall" );
272
+ JSON.attributeObject (" value" , [&]() {
273
+ JSON.attribute (" type" , initCallValue->getName ());
274
+ JSON.attributeArray (" arguments" , [&] {
275
+ for (auto FP : initCallValue->getParameters ()) {
276
+ JSON.object ([&] {
277
+ JSON.attribute (" label" , FP.Label );
278
+ JSON.attribute (" type" , toFullyQualifiedTypeNameString (FP.Type ));
279
+ writeValue (JSON, FP.Value );
280
+ });
281
+ }
282
+ });
283
+ });
284
+ break ;
285
+ }
286
+
287
+ case CompileTimeValue::ValueKind::Builder: {
288
+ JSON.attribute (" valueKind" , " Builder" );
289
+ break ;
290
+ }
291
+
292
+ case CompileTimeValue::ValueKind::Dictionary: {
293
+ JSON.attribute (" valueKind" , " Dictionary" );
294
+ break ;
295
+ }
296
+
297
+ case CompileTimeValue::ValueKind::Runtime: {
298
+ JSON.attribute (" valueKind" , " Runtime" );
299
+ break ;
300
+ }
237
301
}
238
302
}
239
303
@@ -252,19 +316,14 @@ bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
252
316
JSON.attributeArray (" properties" , [&] {
253
317
for (const auto &PropertyInfo : TypeInfo.Properties ) {
254
318
JSON.object ([&] {
255
- const auto *PropertyDecl = PropertyInfo.VarDecl ;
256
- JSON.attribute (" label" , PropertyDecl ->getName ().str ().str ());
257
- JSON.attribute (" type" , toFullyQualifiedTypeNameString (PropertyDecl-> getType ()));
258
- JSON. attribute ( " isStatic " ,
259
- PropertyDecl ->isStatic () ? " true" : " false" );
319
+ const auto *decl = PropertyInfo.VarDecl ;
320
+ JSON.attribute (" label" , decl ->getName ().str ().str ());
321
+ JSON.attribute (" type" ,
322
+ toFullyQualifiedTypeNameString (decl-> getType ()));
323
+ JSON. attribute ( " isStatic " , decl ->isStatic () ? " true" : " false" );
260
324
JSON.attribute (" isComputed" ,
261
- !PropertyDecl->hasStorage () ? " true" : " false" );
262
- auto value = PropertyInfo.Value .get ();
263
- auto valueKind = value->getKind ();
264
- JSON.attribute (" valueKind" , toString (valueKind));
265
- if (valueKind != CompileTimeValue::ValueKind::Runtime) {
266
- JSON.attribute (" value" , toString (value));
267
- }
325
+ !decl->hasStorage () ? " true" : " false" );
326
+ writeValue (JSON, PropertyInfo.Value );
268
327
});
269
328
}
270
329
});
0 commit comments