Skip to content

Commit 813f542

Browse files
author
Quinn Taylor
committed
[Compile Time Constant Extraction] Add extraction of Dictionary values.
1 parent 77527c9 commit 813f542

File tree

3 files changed

+151
-6
lines changed

3 files changed

+151
-6
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 10 additions & 2 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
@@ -105,11 +105,19 @@ class BuilderValue : public CompileTimeValue {
105105
/// A dictionary literal value representation
106106
class DictionaryValue : public CompileTimeValue {
107107
public:
108-
DictionaryValue() : CompileTimeValue(ValueKind::Dictionary) {}
108+
DictionaryValue(std::vector<std::shared_ptr<CompileTimeValue>> elements)
109+
: CompileTimeValue(ValueKind::Dictionary), elements(elements) {}
109110

110111
static bool classof(const CompileTimeValue *T) {
111112
return T->getKind() == ValueKind::Dictionary;
112113
}
114+
115+
std::vector<std::shared_ptr<CompileTimeValue>> getElements() const {
116+
return elements;
117+
}
118+
119+
private:
120+
std::vector<std::shared_ptr<CompileTimeValue>> elements;
113121
};
114122

115123
struct TupleElement {

lib/ConstExtract/ConstExtract.cpp

Lines changed: 21 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,16 @@ 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<CompileTimeValue>> elementValues;
152+
for (unsigned n = dictionaryExpr->getNumElements(), i = 0; i != n; i++) {
153+
auto elementExpr = dictionaryExpr->getElement(i);
154+
elementValues.push_back(extractCompileTimeValue(elementExpr));
155+
}
156+
return std::make_shared<DictionaryValue>(elementValues);
157+
}
158+
151159
case ExprKind::Tuple: {
152160
auto tupleExpr = cast<TupleExpr>(expr);
153161

@@ -383,6 +391,17 @@ void writeValue(llvm::json::OStream &JSON,
383391

384392
case CompileTimeValue::ValueKind::Dictionary: {
385393
JSON.attribute("valueKind", "Dictionary");
394+
JSON.attributeArray("value", [&] {
395+
for (auto element : cast<DictionaryValue>(value)->getElements()) {
396+
auto tupleElements = cast<TupleValue>(element.get())->getElements();
397+
JSON.object([&] {
398+
JSON.attributeObject(
399+
"key", [&] { writeValue(JSON, tupleElements[0].Value); });
400+
JSON.attributeObject(
401+
"value", [&] { writeValue(JSON, tupleElements[1].Value); });
402+
});
403+
}
404+
});
386405
break;
387406
}
388407

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)