Skip to content

Commit 0d666e2

Browse files
authored
[Compile Time Constant Extraction] Add extraction of tuples (#62436)
1 parent 850c280 commit 0d666e2

File tree

3 files changed

+119
-6
lines changed

3 files changed

+119
-6
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Type;
2727
/// in a type property initializer expression
2828
class CompileTimeValue {
2929
public:
30-
enum ValueKind { RawLiteral, InitCall, Builder, Dictionary, Runtime };
30+
enum ValueKind { RawLiteral, InitCall, Builder, Dictionary, Runtime, Tuple };
3131

3232
ValueKind getKind() const { return Kind; }
3333

@@ -104,6 +104,28 @@ class DictionaryValue : public CompileTimeValue {
104104
}
105105
};
106106

107+
struct TupleElement {
108+
Optional<std::string> Label;
109+
swift::Type Type;
110+
std::shared_ptr<CompileTimeValue> Value;
111+
};
112+
113+
/// A representation of a tuple and each tuple-element
114+
class TupleValue : public CompileTimeValue {
115+
public:
116+
TupleValue(std::vector<TupleElement> Elements)
117+
: CompileTimeValue(ValueKind::Tuple), Elements(Elements) {}
118+
119+
static bool classof(const CompileTimeValue *T) {
120+
return T->getKind() == ValueKind::Tuple;
121+
}
122+
123+
std::vector<TupleElement> getElements() const { return Elements; }
124+
125+
private:
126+
std::vector<TupleElement> Elements;
127+
};
128+
107129
/// A representation of an arbitrary value that does not fall under
108130
/// any of the above categories.
109131
class RuntimeValue : public CompileTimeValue {

lib/ConstExtract/ConstExtract.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
125125
switch (expr->getKind()) {
126126
case ExprKind::Array:
127127
case ExprKind::Dictionary:
128-
case ExprKind::Tuple:
129128

130129
case ExprKind::BooleanLiteral:
131130
case ExprKind::FloatLiteral:
@@ -141,6 +140,33 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
141140
break;
142141
}
143142

143+
case ExprKind::Tuple: {
144+
auto tupleExpr = cast<TupleExpr>(expr);
145+
146+
std::vector<TupleElement> elements;
147+
if (tupleExpr->hasElementNames()) {
148+
for (auto pair : llvm::zip(tupleExpr->getElements(),
149+
tupleExpr->getElementNames())) {
150+
auto elementExpr = std::get<0>(pair);
151+
auto elementName = std::get<1>(pair);
152+
153+
Optional<std::string> label =
154+
elementName.empty()
155+
? Optional<std::string>()
156+
: Optional<std::string>(elementName.str().str());
157+
158+
elements.push_back({label, elementExpr->getType(),
159+
extractCompileTimeValue(elementExpr)});
160+
}
161+
} else {
162+
for (auto elementExpr : tupleExpr->getElements()) {
163+
elements.push_back({Optional<std::string>(), elementExpr->getType(),
164+
extractCompileTimeValue(elementExpr)});
165+
}
166+
}
167+
return std::make_shared<TupleValue>(elements);
168+
}
169+
144170
case ExprKind::Call: {
145171
auto callExpr = cast<CallExpr>(expr);
146172
if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) {
@@ -287,6 +313,24 @@ void writeValue(llvm::json::OStream &JSON,
287313
break;
288314
}
289315

316+
case CompileTimeValue::ValueKind::Tuple: {
317+
auto tupleValue = cast<TupleValue>(value);
318+
319+
JSON.attribute("valueKind", "Tuple");
320+
JSON.attributeArray("value", [&] {
321+
for (auto TV : tupleValue->getElements()) {
322+
JSON.object([&] {
323+
if (auto Label = TV.Label) {
324+
JSON.attribute("label", Label);
325+
}
326+
JSON.attribute("type", toFullyQualifiedTypeNameString(TV.Type));
327+
writeValue(JSON, TV.Value);
328+
});
329+
}
330+
});
331+
break;
332+
}
333+
290334
case CompileTimeValue::ValueKind::Builder: {
291335
JSON.attribute("valueKind", "Builder");
292336
break;

test/ConstExtraction/ExtractGroups.swift

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,54 @@
3939
// CHECK-NEXT: "properties": [
4040
// CHECK-NEXT: {
4141
// CHECK-NEXT: "label": "tuple1",
42-
// CHECK-NEXT: "type": "(Swift.Int, Swift.Float)",
42+
// CHECK-NEXT: "type": "(Swift.String, ExtractGroups.Bar)",
4343
// CHECK-NEXT: "isStatic": "false",
4444
// CHECK-NEXT: "isComputed": "false",
45-
// CHECK-NEXT: "valueKind": "RawLiteral",
46-
// CHECK-NEXT: "value": "(42, 6.6)"
45+
// CHECK-NEXT: "valueKind": "Tuple",
46+
// CHECK-NEXT: "value": [
47+
// CHECK-NEXT: {
48+
// CHECK-NEXT: "type": "Swift.String",
49+
// CHECK-NEXT: "valueKind": "RawLiteral",
50+
// CHECK-NEXT: "value": "\"foo\""
51+
// CHECK-NEXT: },
52+
// CHECK-NEXT: {
53+
// CHECK-NEXT: "type": "ExtractGroups.Bar",
54+
// CHECK-NEXT: "valueKind": "InitCall",
55+
// CHECK-NEXT: "value": {
56+
// CHECK-NEXT: "type": "ExtractGroups.Bar",
57+
// CHECK-NEXT: "arguments": []
58+
// CHECK-NEXT: }
59+
// CHECK-NEXT: }
60+
// CHECK-NEXT: ]
61+
// CHECK-NEXT: },
62+
// CHECK-NEXT: {
63+
// CHECK-NEXT: "label": "tuple2",
64+
// CHECK-NEXT: "type": "(lat: Swift.Float, lng: Swift.Float)",
65+
// CHECK-NEXT: "isStatic": "false",
66+
// CHECK-NEXT: "isComputed": "false",
67+
// CHECK-NEXT: "valueKind": "Tuple",
68+
// CHECK-NEXT: "value": [
69+
// CHECK-NEXT: {
70+
// CHECK-NEXT: "label": "lat",
71+
// CHECK-NEXT: "type": "Swift.Float",
72+
// CHECK-NEXT: "valueKind": "RawLiteral",
73+
// CHECK-NEXT: "value": "42.7"
74+
// CHECK-NEXT: },
75+
// CHECK-NEXT: {
76+
// CHECK-NEXT: "label": "lng",
77+
// CHECK-NEXT: "type": "Swift.Float",
78+
// CHECK-NEXT: "valueKind": "RawLiteral",
79+
// CHECK-NEXT: "value": "-73.9"
80+
// CHECK-NEXT: }
81+
// CHECK-NEXT: ]
82+
// CHECK-NEXT: },
83+
// CHECK-NEXT: {
84+
// CHECK-NEXT: "label": "tuple3",
85+
// CHECK-NEXT: "type": "Swift.Void",
86+
// CHECK-NEXT: "isStatic": "false",
87+
// CHECK-NEXT: "isComputed": "false",
88+
// CHECK-NEXT: "valueKind": "Tuple",
89+
// CHECK-NEXT: "value": []
4790
// CHECK-NEXT: }
4891
// CHECK-NEXT: ]
4992
// CHECK-NEXT: }
@@ -60,5 +103,9 @@ public struct Dictionaries : MyProto {
60103
}
61104

62105
public struct Tuples : MyProto {
63-
let tuple1: (Int, Float) = (42, 6.6)
106+
let tuple1: (String, Bar) = ("foo", Bar())
107+
let tuple2: (lat: Float, lng: Float) = (lat: 42.7, lng: -73.9)
108+
let tuple3: Void = ()
64109
}
110+
111+
public struct Bar {}

0 commit comments

Comments
 (0)