Skip to content

Commit 5683a61

Browse files
authored
Merge pull request #62752 from quinntaylor/const-extract-dictionary
[Compile Time Constant Extraction] Add extraction of Dictionary values.
2 parents 3f151fe + b4a1fc6 commit 5683a61

File tree

3 files changed

+162
-15
lines changed

3 files changed

+162
-15
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -102,16 +102,6 @@ class BuilderValue : public CompileTimeValue {
102102
std::vector<CompileTimeValue> Members;
103103
};
104104

105-
/// A dictionary literal value representation
106-
class DictionaryValue : public CompileTimeValue {
107-
public:
108-
DictionaryValue() : CompileTimeValue(ValueKind::Dictionary) {}
109-
110-
static bool classof(const CompileTimeValue *T) {
111-
return T->getKind() == ValueKind::Dictionary;
112-
}
113-
};
114-
115105
struct TupleElement {
116106
Optional<std::string> Label;
117107
swift::Type Type;
@@ -151,6 +141,24 @@ class ArrayValue : public CompileTimeValue {
151141
std::vector<std::shared_ptr<CompileTimeValue>> Elements;
152142
};
153143

144+
/// A dictionary literal value representation
145+
class DictionaryValue : public CompileTimeValue {
146+
public:
147+
DictionaryValue(std::vector<std::shared_ptr<TupleValue>> elements)
148+
: CompileTimeValue(ValueKind::Dictionary), Elements(elements) {}
149+
150+
static bool classof(const CompileTimeValue *T) {
151+
return T->getKind() == ValueKind::Dictionary;
152+
}
153+
154+
std::vector<std::shared_ptr<TupleValue>> getElements() const {
155+
return Elements;
156+
}
157+
158+
private:
159+
std::vector<std::shared_ptr<TupleValue>> Elements;
160+
};
161+
154162
/// A representation of an arbitrary value that does not fall under
155163
/// any of the above categories.
156164
class RuntimeValue : public CompileTimeValue {

lib/ConstExtract/ConstExtract.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ parseProtocolListFromFile(StringRef protocolListFilePath,
123123
static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
124124
if (expr) {
125125
switch (expr->getKind()) {
126-
case ExprKind::Dictionary:
127-
128126
case ExprKind::BooleanLiteral:
129127
case ExprKind::FloatLiteral:
130128
case ExprKind::IntegerLiteral:
@@ -148,6 +146,18 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
148146
return std::make_shared<ArrayValue>(elementValues);
149147
}
150148

149+
case ExprKind::Dictionary: {
150+
auto dictionaryExpr = cast<DictionaryExpr>(expr);
151+
std::vector<std::shared_ptr<TupleValue>> tuples;
152+
for (auto elementExpr : dictionaryExpr->getElements()) {
153+
auto elementValue = extractCompileTimeValue(elementExpr);
154+
if (isa<TupleValue>(elementValue.get())) {
155+
tuples.push_back(std::static_pointer_cast<TupleValue>(elementValue));
156+
}
157+
}
158+
return std::make_shared<DictionaryValue>(tuples);
159+
}
160+
151161
case ExprKind::Tuple: {
152162
auto tupleExpr = cast<TupleExpr>(expr);
153163

@@ -389,6 +399,17 @@ void writeValue(llvm::json::OStream &JSON,
389399

390400
case CompileTimeValue::ValueKind::Dictionary: {
391401
JSON.attribute("valueKind", "Dictionary");
402+
JSON.attributeArray("value", [&] {
403+
for (auto tupleValue : cast<DictionaryValue>(value)->getElements()) {
404+
auto tupleElements = tupleValue.get()->getElements();
405+
JSON.object([&] {
406+
JSON.attributeObject(
407+
"key", [&] { writeValue(JSON, tupleElements[0].Value); });
408+
JSON.attributeObject(
409+
"value", [&] { writeValue(JSON, tupleElements[1].Value); });
410+
});
411+
}
412+
});
392413
break;
393414
}
394415

test/ConstExtraction/ExtractGroups.swift

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,118 @@
8181
// CHECK-NEXT: "type": "[Swift.String : Swift.Int]",
8282
// CHECK-NEXT: "isStatic": "false",
8383
// CHECK-NEXT: "isComputed": "false",
84-
// CHECK-NEXT: "valueKind": "RawLiteral",
85-
// CHECK-NEXT: "value": "[(\"One\", 1), (\"Two\", 2), (\"Three\", 3)]"
84+
// CHECK-NEXT: "valueKind": "Dictionary",
85+
// CHECK-NEXT: "value": [
86+
// CHECK-NEXT: {
87+
// CHECK-NEXT: "key": {
88+
// CHECK-NEXT: "valueKind": "RawLiteral",
89+
// CHECK-NEXT: "value": "\"One\""
90+
// CHECK-NEXT: },
91+
// CHECK-NEXT: "value": {
92+
// CHECK-NEXT: "valueKind": "RawLiteral",
93+
// CHECK-NEXT: "value": "1"
94+
// CHECK-NEXT: }
95+
// CHECK-NEXT: },
96+
// CHECK-NEXT: {
97+
// CHECK-NEXT: "key": {
98+
// CHECK-NEXT: "valueKind": "RawLiteral",
99+
// CHECK-NEXT: "value": "\"Two\""
100+
// CHECK-NEXT: },
101+
// CHECK-NEXT: "value": {
102+
// CHECK-NEXT: "valueKind": "RawLiteral",
103+
// CHECK-NEXT: "value": "2"
104+
// CHECK-NEXT: }
105+
// CHECK-NEXT: },
106+
// CHECK-NEXT: {
107+
// CHECK-NEXT: "key": {
108+
// CHECK-NEXT: "valueKind": "RawLiteral",
109+
// CHECK-NEXT: "value": "\"Three\""
110+
// CHECK-NEXT: },
111+
// CHECK-NEXT: "value": {
112+
// CHECK-NEXT: "valueKind": "RawLiteral",
113+
// CHECK-NEXT: "value": "3"
114+
// CHECK-NEXT: }
115+
// CHECK-NEXT: }
116+
// CHECK-NEXT: ]
117+
// CHECK-NEXT: },
118+
// CHECK-NEXT: {
119+
// CHECK-NEXT: "label": "dict2",
120+
// CHECK-NEXT: "type": "[Swift.Int : [Swift.String]]",
121+
// CHECK-NEXT: "isStatic": "false",
122+
// CHECK-NEXT: "isComputed": "false",
123+
// CHECK-NEXT: "valueKind": "Dictionary",
124+
// CHECK-NEXT: "value": [
125+
// CHECK-NEXT: {
126+
// CHECK-NEXT: "key": {
127+
// CHECK-NEXT: "valueKind": "RawLiteral",
128+
// CHECK-NEXT: "value": "1"
129+
// CHECK-NEXT: },
130+
// CHECK-NEXT: "value": {
131+
// CHECK-NEXT: "valueKind": "Array",
132+
// CHECK-NEXT: "value": [
133+
// CHECK-NEXT: {
134+
// CHECK-NEXT: "valueKind": "RawLiteral",
135+
// CHECK-NEXT: "value": "\"a\""
136+
// CHECK-NEXT: },
137+
// CHECK-NEXT: {
138+
// CHECK-NEXT: "valueKind": "RawLiteral",
139+
// CHECK-NEXT: "value": "\"b\""
140+
// CHECK-NEXT: },
141+
// CHECK-NEXT: {
142+
// CHECK-NEXT: "valueKind": "RawLiteral",
143+
// CHECK-NEXT: "value": "\"c\""
144+
// CHECK-NEXT: }
145+
// CHECK-NEXT: ]
146+
// CHECK-NEXT: }
147+
// CHECK-NEXT: },
148+
// CHECK-NEXT: {
149+
// CHECK-NEXT: "key": {
150+
// CHECK-NEXT: "valueKind": "RawLiteral",
151+
// CHECK-NEXT: "value": "2"
152+
// CHECK-NEXT: },
153+
// CHECK-NEXT: "value": {
154+
// CHECK-NEXT: "valueKind": "Array",
155+
// CHECK-NEXT: "value": [
156+
// CHECK-NEXT: {
157+
// CHECK-NEXT: "valueKind": "RawLiteral",
158+
// CHECK-NEXT: "value": "\"z\""
159+
// CHECK-NEXT: }
160+
// CHECK-NEXT: ]
161+
// CHECK-NEXT: }
162+
// CHECK-NEXT: }
163+
// CHECK-NEXT: ]
164+
// CHECK-NEXT: },
165+
// CHECK-NEXT: {
166+
// CHECK-NEXT: "label": "dict3",
167+
// CHECK-NEXT: "type": "[Swift.String : ExtractGroups.Foo]",
168+
// CHECK-NEXT: "isStatic": "false",
169+
// CHECK-NEXT: "isComputed": "false",
170+
// CHECK-NEXT: "valueKind": "Dictionary",
171+
// CHECK-NEXT: "value": [
172+
// CHECK-NEXT: {
173+
// CHECK-NEXT: "key": {
174+
// CHECK-NEXT: "valueKind": "RawLiteral",
175+
// CHECK-NEXT: "value": "\"Bar\""
176+
// CHECK-NEXT: },
177+
// CHECK-NEXT: "value": {
178+
// CHECK-NEXT: "valueKind": "InitCall",
179+
// CHECK-NEXT: "value": {
180+
// CHECK-NEXT: "type": "ExtractGroups.Bar",
181+
// CHECK-NEXT: "arguments": []
182+
// CHECK-NEXT: }
183+
// CHECK-NEXT: }
184+
// CHECK-NEXT: },
185+
// CHECK-NEXT: {
186+
// CHECK-NEXT: "key": {
187+
// CHECK-NEXT: "valueKind": "RawLiteral",
188+
// CHECK-NEXT: "value": "\"Int\""
189+
// CHECK-NEXT: },
190+
// CHECK-NEXT: "value": {
191+
// CHECK-NEXT: "valueKind": "RawLiteral",
192+
// CHECK-NEXT: "value": "42"
193+
// CHECK-NEXT: }
194+
// CHECK-NEXT: }
195+
// CHECK-NEXT: ]
86196
// CHECK-NEXT: }
87197
// CHECK-NEXT: ]
88198
// CHECK-NEXT: },
@@ -155,6 +265,14 @@ public struct Arrays : MyProto {
155265

156266
public struct Dictionaries : MyProto {
157267
let dict1: [String: Int] = ["One": 1, "Two": 2, "Three": 3]
268+
let dict2: [Int: [String]] = [
269+
1: ["a", "b", "c"],
270+
2: ["z"]
271+
]
272+
let dict3: [String: Foo] = [
273+
"Bar": Bar(),
274+
"Int": 42
275+
]
158276
}
159277

160278
public struct Tuples : MyProto {

0 commit comments

Comments
 (0)