Skip to content

Commit d4c5ca6

Browse files
committed
[Compile Time Constant Extraction] Extract result builder-type information
1 parent 4eefefa commit d4c5ca6

File tree

2 files changed

+152
-1
lines changed

2 files changed

+152
-1
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,17 @@ void writeFileInformation(llvm::json::OStream &JSON, const VarDecl *VD) {
364364
ctx.SourceMgr.getPresumedLineAndColumnForLoc(sourceRange.Start).first);
365365
}
366366

367+
void writeFileInformation(llvm::json::OStream &JSON, const ASTContext &ctx,
368+
const CustomAttr *Attr) {
369+
SourceLoc loc = Attr->getLocation();
370+
if (loc.isInvalid())
371+
return;
372+
373+
JSON.attribute("file", ctx.SourceMgr.getDisplayNameForLoc(loc));
374+
JSON.attribute("line",
375+
ctx.SourceMgr.getPresumedLineAndColumnForLoc(loc).first);
376+
}
377+
367378
void writeFileInformation(llvm::json::OStream &JSON,
368379
const NominalTypeDecl *NTD) {
369380
DeclContext *DC = NTD->getInnermostDeclContext();
@@ -489,14 +500,45 @@ void writeAttributes(
489500
});
490501
}
491502

503+
void writeResultBuilderInformation(llvm::json::OStream &JSON,
504+
const swift::NominalTypeDecl *TypeDecl,
505+
const swift::VarDecl *VarDecl) {
506+
if (auto *attr = VarDecl->getAttachedResultBuilder()) {
507+
JSON.attributeObject("resultBuilder", [&] {
508+
JSON.attribute("type", toFullyQualifiedTypeNameString(attr->getType()));
509+
writeFileInformation(JSON, VarDecl->getASTContext(), attr);
510+
});
511+
512+
return;
513+
}
514+
515+
for (ProtocolDecl *Decl :
516+
TypeDecl->getLocalProtocols(ConformanceLookupKind::All)) {
517+
for (auto Member : Decl->getMembers()) {
518+
if (auto *VD = dyn_cast<swift::VarDecl>(Member)) {
519+
if (auto *attr = VD->getAttachedResultBuilder()) {
520+
if (VD->getName() == VarDecl->getName()) {
521+
JSON.attributeObject("resultBuilder", [&] {
522+
JSON.attribute("type",
523+
toFullyQualifiedTypeNameString(attr->getType()));
524+
writeFileInformation(JSON, VD->getASTContext(), attr);
525+
});
526+
}
527+
}
528+
}
529+
}
530+
}
531+
}
532+
492533
bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
493534
llvm::raw_fd_ostream &OS) {
494535
llvm::json::OStream JSON(OS, 2);
495536
JSON.array([&] {
496537
for (const auto &TypeInfo : ConstValueInfos) {
497538
JSON.object([&] {
498539
const auto *TypeDecl = TypeInfo.TypeDecl;
499-
JSON.attribute("typeName", toFullyQualifiedTypeNameString(TypeDecl->getDeclaredInterfaceType()));
540+
JSON.attribute("typeName", toFullyQualifiedTypeNameString(
541+
TypeDecl->getDeclaredInterfaceType()));
500542
JSON.attribute(
501543
"kind",
502544
TypeDecl->getDescriptiveKindName(TypeDecl->getDescriptiveKind())
@@ -515,6 +557,7 @@ bool writeAsJSONToFile(const std::vector<ConstValueTypeInfo> &ConstValueInfos,
515557
writeFileInformation(JSON, decl);
516558
writeValue(JSON, PropertyInfo.Value);
517559
writeAttributes(JSON, PropertyInfo.PropertyWrappers);
560+
writeResultBuilderInformation(JSON, TypeDecl, decl);
518561
});
519562
}
520563
});
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/inputs)
3+
// RUN: echo "[FooProvider]" > %t/inputs/protocols.json
4+
5+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractResultBuilders.swiftconstvalues -const-gather-protocols-file %t/inputs/protocols.json -primary-file %s
6+
// RUN: cat %t/ExtractResultBuilders.swiftconstvalues 2>&1 | %FileCheck %s
7+
8+
public struct Foo {
9+
let name: String
10+
}
11+
12+
@resultBuilder
13+
public enum FooBuilder {
14+
public static func buildExpression(_ component: Foo) -> Foo {
15+
component
16+
}
17+
18+
public static func buildBlock(_ components: Foo...) -> [Foo] {
19+
components
20+
}
21+
}
22+
23+
public protocol FooProvider {
24+
@FooBuilder
25+
static var foos: [Foo] { get }
26+
}
27+
28+
public struct MyFooProvider: FooProvider {
29+
@FooBuilder
30+
public static var foos: [Foo] {
31+
Foo(name: "AAA")
32+
Foo(name: "BBB")
33+
}
34+
35+
@FooBuilder
36+
public static var fooTwo: [Foo] {
37+
Foo(name: "111")
38+
Foo(name: "222")
39+
}
40+
}
41+
42+
public struct MyFooProviderInferred: FooProvider {
43+
public static var foos: [Foo] {
44+
Foo(name: "CCC")
45+
Foo(name: "DDD")
46+
}
47+
}
48+
49+
// CHECK: [
50+
// CHECK-NEXT: {
51+
// CHECK-NEXT: "typeName": "ExtractResultBuilders.MyFooProvider",
52+
// CHECK-NEXT: "kind": "struct",
53+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
54+
// CHECK-NEXT: "line": 28,
55+
// CHECK-NEXT: "properties": [
56+
// CHECK-NEXT: {
57+
// CHECK-NEXT: "label": "foos",
58+
// CHECK-NEXT: "type": "[ExtractResultBuilders.Foo]",
59+
// CHECK-NEXT: "isStatic": "true",
60+
// CHECK-NEXT: "isComputed": "true",
61+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
62+
// CHECK-NEXT: "line": 30,
63+
// CHECK-NEXT: "valueKind": "Runtime",
64+
// CHECK-NEXT: "resultBuilder": {
65+
// CHECK-NEXT: "type": "ExtractResultBuilders.FooBuilder",
66+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
67+
// CHECK-NEXT: "line": 29
68+
// CHECK-NEXT: }
69+
// CHECK-NEXT: },
70+
// CHECK-NEXT: {
71+
// CHECK-NEXT: "label": "fooTwo",
72+
// CHECK-NEXT: "type": "[ExtractResultBuilders.Foo]",
73+
// CHECK-NEXT: "isStatic": "true",
74+
// CHECK-NEXT: "isComputed": "true",
75+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
76+
// CHECK-NEXT: "line": 36,
77+
// CHECK-NEXT: "valueKind": "Runtime",
78+
// CHECK-NEXT: "resultBuilder": {
79+
// CHECK-NEXT: "type": "ExtractResultBuilders.FooBuilder",
80+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
81+
// CHECK-NEXT: "line": 35
82+
// CHECK-NEXT: }
83+
// CHECK-NEXT: }
84+
// CHECK-NEXT: ]
85+
// CHECK-NEXT: },
86+
// CHECK-NEXT: {
87+
// CHECK-NEXT: "typeName": "ExtractResultBuilders.MyFooProviderInferred",
88+
// CHECK-NEXT: "kind": "struct",
89+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
90+
// CHECK-NEXT: "line": 42,
91+
// CHECK-NEXT: "properties": [
92+
// CHECK-NEXT: {
93+
// CHECK-NEXT: "label": "foos",
94+
// CHECK-NEXT: "type": "[ExtractResultBuilders.Foo]",
95+
// CHECK-NEXT: "isStatic": "true",
96+
// CHECK-NEXT: "isComputed": "true",
97+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
98+
// CHECK-NEXT: "line": 43,
99+
// CHECK-NEXT: "valueKind": "Runtime",
100+
// CHECK-NEXT: "resultBuilder": {
101+
// CHECK-NEXT: "type": "ExtractResultBuilders.FooBuilder",
102+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractResultBuilders.swift",
103+
// CHECK-NEXT: "line": 24
104+
// CHECK-NEXT: }
105+
// CHECK-NEXT: }
106+
// CHECK-NEXT: ]
107+
// CHECK-NEXT: }
108+
// CHECK-NEXT: ]

0 commit comments

Comments
 (0)