Skip to content

Commit 5a12075

Browse files
authored
[Compile Time Constant Extraction] Extract line numbers (swiftlang#62870)
1 parent 3f808f7 commit 5a12075

File tree

4 files changed

+259
-148
lines changed

4 files changed

+259
-148
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,31 @@ gatherConstValuesForPrimary(const std::unordered_set<std::string> &Protocols,
352352
return Result;
353353
}
354354

355+
void writeFileInformation(llvm::json::OStream &JSON, const VarDecl *VD) {
356+
SourceRange sourceRange = VD->getSourceRange();
357+
if (sourceRange.isInvalid())
358+
return;
359+
360+
const ASTContext &ctx = VD->getDeclContext()->getASTContext();
361+
JSON.attribute("file", ctx.SourceMgr.getDisplayNameForLoc(sourceRange.Start));
362+
JSON.attribute(
363+
"line",
364+
ctx.SourceMgr.getPresumedLineAndColumnForLoc(sourceRange.Start).first);
365+
}
366+
367+
void writeFileInformation(llvm::json::OStream &JSON,
368+
const NominalTypeDecl *NTD) {
369+
DeclContext *DC = NTD->getInnermostDeclContext();
370+
SourceLoc loc = extractNearestSourceLoc(DC);
371+
if (loc.isInvalid())
372+
return;
373+
374+
const ASTContext &ctx = DC->getASTContext();
375+
JSON.attribute("file", ctx.SourceMgr.getDisplayNameForLoc(loc));
376+
JSON.attribute("line",
377+
ctx.SourceMgr.getPresumedLineAndColumnForLoc(loc).first);
378+
}
379+
355380
void writeValue(llvm::json::OStream &JSON,
356381
std::shared_ptr<CompileTimeValue> Value) {
357382
auto value = Value.get();
@@ -476,6 +501,7 @@ bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
476501
"kind",
477502
TypeDecl->getDescriptiveKindName(TypeDecl->getDescriptiveKind())
478503
.str());
504+
writeFileInformation(JSON, TypeDecl);
479505
JSON.attributeArray("properties", [&] {
480506
for (const auto &PropertyInfo : TypeInfo.Properties) {
481507
JSON.object([&] {
@@ -486,6 +512,7 @@ bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
486512
JSON.attribute("isStatic", decl->isStatic() ? "true" : "false");
487513
JSON.attribute("isComputed",
488514
!decl->hasStorage() ? "true" : "false");
515+
writeFileInformation(JSON, decl);
489516
writeValue(JSON, PropertyInfo.Value);
490517
writeAttributes(JSON, PropertyInfo.PropertyWrappers);
491518
});

test/ConstExtraction/ExtractCalls.swift

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,50 @@
44
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractCalls.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s
55
// RUN: cat %t/ExtractCalls.swiftconstvalues 2>&1 | %FileCheck %s
66

7+
protocol MyProto {}
8+
9+
public struct Foo : MyProto {
10+
let init1 = Bar()
11+
let init2: Bat = .init()
12+
let init3 = Bat(buz: "hello", fuz: adder(2, 3))
13+
let func1: Int = adder(2, 3)
14+
}
15+
16+
extension Foo {
17+
struct Boo {}
18+
19+
var ext1: Boo { Boo() }
20+
}
21+
22+
func adder(_ x: Int, _ y: Int) -> Int {
23+
x + y
24+
}
25+
26+
public struct Bar {}
27+
public struct Bat {
28+
let buz: String
29+
let fuz: Int
30+
31+
init(buz: String = "", fuz: Int = 0) {
32+
self.buz = buz
33+
self.fuz = fuz
34+
}
35+
}
36+
737
// CHECK: [
838
// CHECK-NEXT: {
939
// CHECK-NEXT: "typeName": "ExtractCalls.Foo",
1040
// CHECK-NEXT: "kind": "struct",
41+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
42+
// CHECK-NEXT: "line": 9,
1143
// CHECK-NEXT: "properties": [
1244
// CHECK-NEXT: {
1345
// CHECK-NEXT: "label": "init1",
1446
// CHECK-NEXT: "type": "ExtractCalls.Bar",
1547
// CHECK-NEXT: "isStatic": "false",
1648
// CHECK-NEXT: "isComputed": "false",
49+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
50+
// CHECK-NEXT: "line": 10,
1751
// CHECK-NEXT: "valueKind": "InitCall",
1852
// CHECK-NEXT: "value": {
1953
// CHECK-NEXT: "type": "ExtractCalls.Bar",
@@ -25,6 +59,8 @@
2559
// CHECK-NEXT: "type": "ExtractCalls.Bat",
2660
// CHECK-NEXT: "isStatic": "false",
2761
// CHECK-NEXT: "isComputed": "false",
62+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
63+
// CHECK-NEXT: "line": 11,
2864
// CHECK-NEXT: "valueKind": "InitCall",
2965
// CHECK-NEXT: "value": {
3066
// CHECK-NEXT: "type": "ExtractCalls.Bat",
@@ -49,6 +85,8 @@
4985
// CHECK-NEXT: "type": "ExtractCalls.Bat",
5086
// CHECK-NEXT: "isStatic": "false",
5187
// CHECK-NEXT: "isComputed": "false",
88+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
89+
// CHECK-NEXT: "line": 12,
5290
// CHECK-NEXT: "valueKind": "InitCall",
5391
// CHECK-NEXT: "value": {
5492
// CHECK-NEXT: "type": "ExtractCalls.Bat",
@@ -72,13 +110,17 @@
72110
// CHECK-NEXT: "type": "Swift.Int",
73111
// CHECK-NEXT: "isStatic": "false",
74112
// CHECK-NEXT: "isComputed": "false",
113+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
114+
// CHECK-NEXT: "line": 13,
75115
// CHECK-NEXT: "valueKind": "Runtime"
76116
// CHECK-NEXT: },
77117
// CHECK-NEXT: {
78118
// CHECK-NEXT: "label": "ext1",
79119
// CHECK-NEXT: "type": "ExtractCalls.Foo.Boo",
80120
// CHECK-NEXT: "isStatic": "false",
81121
// CHECK-NEXT: "isComputed": "true",
122+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractCalls.swift",
123+
// CHECK-NEXT: "line": 19,
82124
// CHECK-NEXT: "valueKind": "InitCall",
83125
// CHECK-NEXT: "value": {
84126
// CHECK-NEXT: "type": "ExtractCalls.Foo.Boo",
@@ -88,33 +130,3 @@
88130
// CHECK-NEXT: ]
89131
// CHECK-NEXT: }
90132
// CHECK-NEXT:]
91-
92-
protocol MyProto {}
93-
94-
public struct Foo : MyProto {
95-
let init1 = Bar()
96-
let init2: Bat = .init()
97-
let init3 = Bat(buz: "hello", fuz: adder(2, 3))
98-
let func1: Int = adder(2, 3)
99-
}
100-
101-
extension Foo {
102-
struct Boo {}
103-
104-
var ext1: Boo { Boo() }
105-
}
106-
107-
func adder(_ x: Int, _ y: Int) -> Int {
108-
x + y
109-
}
110-
111-
public struct Bar {}
112-
public struct Bat {
113-
let buz: String
114-
let fuz: Int
115-
116-
init(buz: String = "", fuz: Int = 0) {
117-
self.buz = buz
118-
self.fuz = fuz
119-
}
120-
}

test/ConstExtraction/ExtractGroups.swift

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,51 @@
44
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractGroups.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s
55
// RUN: cat %t/ExtractGroups.swiftconstvalues 2>&1 | %FileCheck %s
66

7+
protocol MyProto {}
8+
9+
public struct Arrays : MyProto {
10+
let array1: [Int] = [1, 2, 3]
11+
let array2: [Foo] = [Bar(), 1, "hi"]
12+
let array3: [Bar] = [Bar()]
13+
}
14+
15+
public struct Dictionaries : MyProto {
16+
let dict1: [String: Int] = ["One": 1, "Two": 2, "Three": 3]
17+
let dict2: [Int: [String]] = [
18+
1: ["a", "b", "c"],
19+
2: ["z"]
20+
]
21+
let dict3: [String: Foo] = [
22+
"Bar": Bar(),
23+
"Int": 42
24+
]
25+
}
26+
27+
public struct Tuples : MyProto {
28+
let tuple1: (String, Bar) = ("foo", Bar())
29+
let tuple2: (lat: Float, lng: Float) = (lat: 42.7, lng: -73.9)
30+
let tuple3: Void = ()
31+
}
32+
33+
public protocol Foo {}
34+
public struct Bar: Foo {}
35+
extension Int: Foo {}
36+
extension String: Foo {}
37+
738
// CHECK: [
839
// CHECK-NEXT: {
940
// CHECK-NEXT: "typeName": "ExtractGroups.Arrays",
1041
// CHECK-NEXT: "kind": "struct",
42+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
43+
// CHECK-NEXT: "line": 9,
1144
// CHECK-NEXT: "properties": [
1245
// CHECK-NEXT: {
1346
// CHECK-NEXT: "label": "array1",
1447
// CHECK-NEXT: "type": "[Swift.Int]",
1548
// CHECK-NEXT: "isStatic": "false",
1649
// CHECK-NEXT: "isComputed": "false",
50+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
51+
// CHECK-NEXT: "line": 10,
1752
// CHECK-NEXT: "valueKind": "Array",
1853
// CHECK-NEXT: "value": [
1954
// CHECK-NEXT: {
@@ -35,6 +70,8 @@
3570
// CHECK-NEXT: "type": "[ExtractGroups.Foo]",
3671
// CHECK-NEXT: "isStatic": "false",
3772
// CHECK-NEXT: "isComputed": "false",
73+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
74+
// CHECK-NEXT: "line": 11,
3875
// CHECK-NEXT: "valueKind": "Array",
3976
// CHECK-NEXT: "value": [
4077
// CHECK-NEXT: {
@@ -59,6 +96,8 @@
5996
// CHECK-NEXT: "type": "[ExtractGroups.Bar]",
6097
// CHECK-NEXT: "isStatic": "false",
6198
// CHECK-NEXT: "isComputed": "false",
99+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
100+
// CHECK-NEXT: "line": 12,
62101
// CHECK-NEXT: "valueKind": "Array",
63102
// CHECK-NEXT: "value": [
64103
// CHECK-NEXT: {
@@ -75,12 +114,16 @@
75114
// CHECK-NEXT: {
76115
// CHECK-NEXT: "typeName": "ExtractGroups.Dictionaries",
77116
// CHECK-NEXT: "kind": "struct",
117+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
118+
// CHECK-NEXT: "line": 15,
78119
// CHECK-NEXT: "properties": [
79120
// CHECK-NEXT: {
80121
// CHECK-NEXT: "label": "dict1",
81122
// CHECK-NEXT: "type": "[Swift.String : Swift.Int]",
82123
// CHECK-NEXT: "isStatic": "false",
83124
// CHECK-NEXT: "isComputed": "false",
125+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
126+
// CHECK-NEXT: "line": 16,
84127
// CHECK-NEXT: "valueKind": "Dictionary",
85128
// CHECK-NEXT: "value": [
86129
// CHECK-NEXT: {
@@ -120,6 +163,8 @@
120163
// CHECK-NEXT: "type": "[Swift.Int : [Swift.String]]",
121164
// CHECK-NEXT: "isStatic": "false",
122165
// CHECK-NEXT: "isComputed": "false",
166+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
167+
// CHECK-NEXT: "line": 17,
123168
// CHECK-NEXT: "valueKind": "Dictionary",
124169
// CHECK-NEXT: "value": [
125170
// CHECK-NEXT: {
@@ -167,6 +212,8 @@
167212
// CHECK-NEXT: "type": "[Swift.String : ExtractGroups.Foo]",
168213
// CHECK-NEXT: "isStatic": "false",
169214
// CHECK-NEXT: "isComputed": "false",
215+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
216+
// CHECK-NEXT: "line": 21,
170217
// CHECK-NEXT: "valueKind": "Dictionary",
171218
// CHECK-NEXT: "value": [
172219
// CHECK-NEXT: {
@@ -199,12 +246,16 @@
199246
// CHECK-NEXT: {
200247
// CHECK-NEXT: "typeName": "ExtractGroups.Tuples",
201248
// CHECK-NEXT: "kind": "struct",
249+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
250+
// CHECK-NEXT: "line": 27,
202251
// CHECK-NEXT: "properties": [
203252
// CHECK-NEXT: {
204253
// CHECK-NEXT: "label": "tuple1",
205254
// CHECK-NEXT: "type": "(Swift.String, ExtractGroups.Bar)",
206255
// CHECK-NEXT: "isStatic": "false",
207256
// CHECK-NEXT: "isComputed": "false",
257+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
258+
// CHECK-NEXT: "line": 28,
208259
// CHECK-NEXT: "valueKind": "Tuple",
209260
// CHECK-NEXT: "value": [
210261
// CHECK-NEXT: {
@@ -227,6 +278,8 @@
227278
// CHECK-NEXT: "type": "(lat: Swift.Float, lng: Swift.Float)",
228279
// CHECK-NEXT: "isStatic": "false",
229280
// CHECK-NEXT: "isComputed": "false",
281+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
282+
// CHECK-NEXT: "line": 29,
230283
// CHECK-NEXT: "valueKind": "Tuple",
231284
// CHECK-NEXT: "value": [
232285
// CHECK-NEXT: {
@@ -248,40 +301,11 @@
248301
// CHECK-NEXT: "type": "Swift.Void",
249302
// CHECK-NEXT: "isStatic": "false",
250303
// CHECK-NEXT: "isComputed": "false",
304+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractGroups.swift",
305+
// CHECK-NEXT: "line": 30,
251306
// CHECK-NEXT: "valueKind": "Tuple",
252307
// CHECK-NEXT: "value": []
253308
// CHECK-NEXT: }
254309
// CHECK-NEXT: ]
255310
// CHECK-NEXT: }
256311
// CHECK-NEXT:]
257-
258-
protocol MyProto {}
259-
260-
public struct Arrays : MyProto {
261-
let array1: [Int] = [1, 2, 3]
262-
let array2: [Foo] = [Bar(), 1, "hi"]
263-
let array3: [Bar] = [Bar()]
264-
}
265-
266-
public struct Dictionaries : MyProto {
267-
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-
]
276-
}
277-
278-
public struct Tuples : MyProto {
279-
let tuple1: (String, Bar) = ("foo", Bar())
280-
let tuple2: (lat: Float, lng: Float) = (lat: 42.7, lng: -73.9)
281-
let tuple3: Void = ()
282-
}
283-
284-
public protocol Foo {}
285-
public struct Bar: Foo {}
286-
extension Int: Foo {}
287-
extension String: Foo {}

0 commit comments

Comments
 (0)