Skip to content

Commit 557b1e0

Browse files
authored
Merge pull request #70173 from apple/ApolloZhu/5.10/const-extract/macros
[5.10][Compile Time Constant Extraction] Extract from all macro expansions
2 parents 0e6e274 + 188f2d3 commit 557b1e0

File tree

3 files changed

+294
-2
lines changed

3 files changed

+294
-2
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class NominalTypeConformanceCollector : public ASTWalker {
5858
for (auto &Protocol : NTD->getAllProtocols())
5959
if (Protocols.count(Protocol->getName().str().str()) != 0)
6060
ConformanceTypeDecls.push_back(NTD);
61+
// Visit peers expanded from macros
62+
D->visitAuxiliaryDecls([&](Decl *decl) { decl->walk(*this); },
63+
/*visitFreestandingExpanded=*/false);
6164
return Action::Continue();
6265
}
6366
};
@@ -473,7 +476,7 @@ ConstantValueInfoRequest::evaluate(Evaluator &Evaluator,
473476
Properties.push_back(extractTypePropertyInfo(Property));
474477
}
475478

476-
for (auto Member : Decl->getMembers()) {
479+
for (auto Member : Decl->getAllMembers()) {
477480
auto *VD = dyn_cast<VarDecl>(Member);
478481
// Ignore plain stored properties collected above,
479482
// instead gather up remaining static and computed properties.
@@ -483,7 +486,7 @@ ConstantValueInfoRequest::evaluate(Evaluator &Evaluator,
483486
}
484487

485488
for (auto Extension: Decl->getExtensions()) {
486-
for (auto Member : Extension->getMembers()) {
489+
for (auto Member : Extension->getAllMembers()) {
487490
if (auto *VD = dyn_cast<VarDecl>(Member)) {
488491
Properties.push_back(extractTypePropertyInfo(VD));
489492
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// REQUIRES: swift_swift_parser
2+
// RUN: %empty-directory(%t)
3+
// RUN: echo "[MyProto]" > %t/protocols.json
4+
5+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/Macros.swift -g -no-toolchain-stdlib-rpath
6+
7+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractFromMacroExpansion.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s -load-plugin-library %t/%target-library-name(MacroDefinition)
8+
// RUN: cat %t/ExtractFromMacroExpansion.swiftconstvalues 2>&1 | %FileCheck %s
9+
10+
protocol MyProto { }
11+
12+
@freestanding(declaration, names: named(MacroAddedStruct))
13+
macro AddMacroAddedStruct() = #externalMacro(module: "MacroDefinition", type: "AddStructDeclMacro")
14+
15+
@freestanding(declaration, names: named(macroAddedVar))
16+
macro AddMacroAddedVar() = #externalMacro(module: "MacroDefinition", type: "AddVarDeclMacro")
17+
18+
@attached(extension, conformances: MyProto, names: prefixed(_extension_))
19+
macro AddExtension() = #externalMacro(module: "MacroDefinition", type: "AddExtensionMacro")
20+
21+
@attached(peer, names: prefixed(_peer_))
22+
macro AddPeerVar() = #externalMacro(module: "MacroDefinition", type: "AddPeerVarMacro")
23+
24+
@attached(member, names: prefixed(_member_))
25+
macro AddMemberVar() = #externalMacro(module: "MacroDefinition", type: "AddMemberMacro")
26+
27+
@attached(memberAttribute)
28+
macro AddMacro() = #externalMacro(module: "MacroDefinition", type: "AddMemberAttributeMacro")
29+
30+
@attached(accessor)
31+
macro AddGetter() = #externalMacro(module: "MacroDefinition", type: "GetterMacro")
32+
33+
@attached(peer, names: prefixed(_Peer_))
34+
macro AddPeerStruct() = #externalMacro(module: "MacroDefinition", type: "AddPeerStructMacro")
35+
36+
37+
#AddMacroAddedStruct
38+
39+
@AddExtension
40+
@AddMemberVar
41+
@AddPeerStruct
42+
struct MyStruct {
43+
#AddMacroAddedVar
44+
45+
@AddPeerVar
46+
struct Inner { }
47+
}
48+
49+
@AddMacro
50+
extension MyStruct {
51+
func fromFunc() { }
52+
53+
@AddGetter
54+
var fromVar = 123
55+
}
56+
57+
// CHECK: "typeName": "ExtractFromMacroExpansion.MacroAddedStruct",
58+
// CHECK: "properties": [
59+
// CHECK: "label": "macroAddedStructMember",
60+
// CHECK: "type": "Swift.Int",
61+
// CHECK: "valueKind": "RawLiteral",
62+
// CHECK: "value": "1"
63+
64+
// CHECK: "label": "_extension_MacroAddedStruct",
65+
// CHECK: "type": "Swift.Int",
66+
// CHECK: "valueKind": "RawLiteral",
67+
// CHECK: "value": "3"
68+
69+
70+
// CHECK: "typeName": "ExtractFromMacroExpansion.MyStruct",
71+
// CHECK: "properties": [
72+
// CHECK: "label": "macroAddedVar",
73+
// CHECK: "type": "Swift.Int",
74+
// CHECK: "valueKind": "RawLiteral",
75+
// CHECK: "value": "2"
76+
77+
// CHECK: "label": "_peer_Inner",
78+
// CHECK: "type": "Swift.Int",
79+
// CHECK: "valueKind": "RawLiteral",
80+
// CHECK: "value": "4"
81+
82+
// CHECK: "label": "_member_MyStruct",
83+
// CHECK: "type": "Swift.Int",
84+
// CHECK: "valueKind": "RawLiteral",
85+
// CHECK: "value": "5"
86+
87+
// CHECK: "label": "_peer_fromFunc",
88+
// CHECK: "type": "Swift.Int",
89+
// CHECK: "valueKind": "RawLiteral",
90+
// CHECK: "value": "4"
91+
92+
// CHECK: "label": "_peer_fromVar",
93+
// CHECK: "type": "Swift.Int",
94+
// CHECK: "valueKind": "RawLiteral",
95+
// CHECK: "value": "4"
96+
97+
// CHECK: "label": "fromVar",
98+
// CHECK: "type": "Swift.Int",
99+
// CHECK: "valueKind": "RawLiteral",
100+
// CHECK: "value": "123"
101+
102+
// CHECK: "label": "_extension_MyStruct",
103+
// CHECK: "type": "Swift.Int",
104+
// CHECK: "valueKind": "RawLiteral",
105+
// CHECK: "value": "3"
106+
107+
108+
// CHECK: "typeName": "ExtractFromMacroExpansion._Peer_MyStruct",
109+
// CHECK: "properties": [
110+
// CHECK: "label": "peerMacroVar",
111+
// CHECK: "type": "Swift.Int",
112+
// CHECK: "valueKind": "RawLiteral",
113+
// CHECK: "value": "7"
114+
115+
// CHECK: "label": "macroAddedVar",
116+
// CHECK: "type": "Swift.Int",
117+
// CHECK: "valueKind": "RawLiteral",
118+
// CHECK: "value": "2"
119+
120+
// CHECK: "label": "_peer_peerMacroVar",
121+
// CHECK: "type": "Swift.Int",
122+
// CHECK: "valueKind": "RawLiteral",
123+
// CHECK: "value": "4"
124+
125+
// CHECK: "label": "_member__Peer_MyStruct",
126+
// CHECK: "type": "Swift.Int",
127+
// CHECK: "valueKind": "RawLiteral",
128+
// CHECK: "value": "5"
129+
130+
// CHECK: "label": "_extension__Peer_MyStruct",
131+
// CHECK: "type": "Swift.Int",
132+
// CHECK: "valueKind": "RawLiteral",
133+
// CHECK: "value": "3"
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import SwiftDiagnostics
2+
import SwiftOperators
3+
import SwiftSyntax
4+
import SwiftSyntaxBuilder
5+
import SwiftSyntaxMacros
6+
7+
public struct AddStructDeclMacro: DeclarationMacro {
8+
public static func expansion(
9+
of node: some FreestandingMacroExpansionSyntax,
10+
in context: some MacroExpansionContext
11+
) throws -> [DeclSyntax] {
12+
return [
13+
"""
14+
@AddExtension
15+
struct MacroAddedStruct {
16+
var macroAddedStructMember = 1
17+
}
18+
"""
19+
]
20+
}
21+
}
22+
23+
public struct AddVarDeclMacro: DeclarationMacro {
24+
public static func expansion(
25+
of node: some FreestandingMacroExpansionSyntax,
26+
in context: some MacroExpansionContext
27+
) throws -> [DeclSyntax] {
28+
return [
29+
"""
30+
static let macroAddedVar = 2
31+
"""
32+
]
33+
}
34+
}
35+
36+
public struct AddExtensionMacro: ExtensionMacro {
37+
public static func expansion(
38+
of node: AttributeSyntax,
39+
attachedTo declaration: some DeclGroupSyntax,
40+
providingExtensionsOf type: some TypeSyntaxProtocol,
41+
conformingTo protocols: [TypeSyntax],
42+
in context: some MacroExpansionContext
43+
) throws -> [ExtensionDeclSyntax] {
44+
let typeName = declaration.declGroupName
45+
return protocols.map {
46+
("extension \(typeName): \($0) { }" as DeclSyntax)
47+
.cast(ExtensionDeclSyntax.self)
48+
} + [
49+
("""
50+
extension \(typeName) {
51+
static let _extension_\(typeName) = 3
52+
}
53+
""" as DeclSyntax).cast(ExtensionDeclSyntax.self)
54+
]
55+
}
56+
}
57+
58+
public struct AddPeerVarMacro: PeerMacro {
59+
public static func expansion(
60+
of node: AttributeSyntax,
61+
providingPeersOf declaration: some DeclSyntaxProtocol,
62+
in context: some MacroExpansionContext
63+
) throws -> [DeclSyntax] {
64+
let name = declaration.declName
65+
return [
66+
"""
67+
static var _peer_\(name) = 4
68+
"""
69+
]
70+
}
71+
}
72+
73+
public struct AddMemberMacro: MemberMacro {
74+
public static func expansion(
75+
of node: AttributeSyntax,
76+
providingMembersOf declaration: some DeclGroupSyntax,
77+
in context: some MacroExpansionContext
78+
) throws -> [DeclSyntax] {
79+
let typeName = declaration.declGroupName
80+
return [
81+
"""
82+
static let _member_\(typeName) = 5
83+
"""
84+
]
85+
}
86+
}
87+
88+
public struct AddMemberAttributeMacro: MemberAttributeMacro {
89+
public static func expansion(
90+
of node: AttributeSyntax,
91+
attachedTo declaration: some DeclGroupSyntax,
92+
providingAttributesFor member: some DeclSyntaxProtocol,
93+
in context: some MacroExpansionContext
94+
) throws -> [AttributeSyntax] {
95+
if member.isProtocol(DeclGroupSyntax.self) {
96+
return ["@AddExtension"]
97+
}
98+
return ["@AddPeerVar"]
99+
}
100+
}
101+
102+
public struct GetterMacro: AccessorMacro {
103+
public static func expansion(
104+
of node: AttributeSyntax,
105+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
106+
in context: some MacroExpansionContext
107+
) throws -> [AccessorDeclSyntax] {
108+
return ["get { 6 }"]
109+
}
110+
}
111+
112+
public struct AddPeerStructMacro: PeerMacro {
113+
public static func expansion(
114+
of node: AttributeSyntax,
115+
providingPeersOf declaration: some DeclSyntaxProtocol,
116+
in context: some MacroExpansionContext
117+
) throws -> [DeclSyntax] {
118+
let name = declaration.declName
119+
return [
120+
"""
121+
@AddExtension
122+
@AddMemberVar
123+
struct _Peer_\(name) {
124+
#AddMacroAddedVar
125+
126+
@AddPeerVar
127+
var peerMacroVar = 7
128+
}
129+
"""
130+
]
131+
}
132+
}
133+
134+
extension DeclGroupSyntax {
135+
var declGroupName: TokenSyntax {
136+
if let structDecl = self.as(StructDeclSyntax.self) {
137+
return structDecl.name.trimmed
138+
}
139+
fatalError("Not implemented")
140+
}
141+
}
142+
143+
extension DeclSyntaxProtocol {
144+
var declName: TokenSyntax {
145+
if let varDecl = self.as(VariableDeclSyntax.self),
146+
let first = varDecl.bindings.first,
147+
let pattern = first.pattern.as(IdentifierPatternSyntax.self) {
148+
return pattern.identifier.trimmed
149+
} else if let funcDecl = self.as(FunctionDeclSyntax.self) {
150+
return funcDecl.name.trimmed
151+
} else if let structDecl = self.as(StructDeclSyntax.self) {
152+
return structDecl.name.trimmed
153+
}
154+
fatalError("Not implemented")
155+
}
156+
}

0 commit comments

Comments
 (0)