Skip to content

Commit e8709d1

Browse files
authored
Merge pull request #70104 from apple/ApolloZhu/const-extract/macros
2 parents 9858f39 + 9f9b3ab commit e8709d1

File tree

5 files changed

+359
-21
lines changed

5 files changed

+359
-21
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,21 @@ class NominalTypeConformanceCollector : public ASTWalker {
6161
if (!isa<ProtocolDecl>(NTD) && CheckedDecls.insert(NTD).second) {
6262
if (NTD->getAttrs().hasAttribute<ExtractConstantsFromMembersAttr>()) {
6363
ConformanceTypeDecls.push_back(NTD);
64-
return Action::Continue();
64+
goto visitAuxiliaryDecls;
6565
}
6666

6767
for (auto &Protocol : NTD->getAllProtocols())
68-
if (Protocol->getAttrs().hasAttribute<ExtractConstantsFromMembersAttr>() ||
69-
Protocols.count(Protocol->getName().str().str()) != 0)
68+
if (Protocol->getAttrs()
69+
.hasAttribute<ExtractConstantsFromMembersAttr>() ||
70+
Protocols.count(Protocol->getName().str().str()) != 0) {
7071
ConformanceTypeDecls.push_back(NTD);
72+
goto visitAuxiliaryDecls;
73+
}
7174
}
75+
visitAuxiliaryDecls:
76+
// Visit peers expanded from macros
77+
D->visitAuxiliaryDecls([&](Decl *decl) { decl->walk(*this); },
78+
/*visitFreestandingExpanded=*/false);
7279
return Action::Continue();
7380
}
7481

@@ -490,33 +497,36 @@ ConstValueTypeInfo ConstantValueInfoRequest::evaluate(
490497
std::vector<ConstValueTypePropertyInfo> Properties;
491498
llvm::Optional<std::vector<EnumElementDeclValue>> EnumCases;
492499

493-
if (shouldExtract(Decl)) {
494-
// Use 'getStoredProperties' to get lowered lazy and wrapped properties
495-
auto StoredProperties = Decl->getStoredProperties();
496-
std::unordered_set<VarDecl *> StoredPropertiesSet(StoredProperties.begin(),
497-
StoredProperties.end());
498-
for (auto Property : StoredProperties) {
500+
// Use 'getStoredProperties' to get lowered lazy and wrapped properties.
501+
// @_objcImplementation extensions might contain stored properties.
502+
auto StoredProperties = Decl->getStoredProperties();
503+
std::unordered_set<VarDecl *> StoredPropertiesSet(StoredProperties.begin(),
504+
StoredProperties.end());
505+
for (auto Property : StoredProperties) {
506+
if (shouldExtract(Property->getDeclContext())) {
499507
Properties.push_back(extractTypePropertyInfo(Property));
500508
}
509+
}
501510

502-
for (auto Member : Decl->getMembers()) {
503-
auto *VD = dyn_cast<VarDecl>(Member);
504-
// Ignore plain stored properties collected above,
505-
// instead gather up remaining static and computed properties.
506-
if (!VD || StoredPropertiesSet.count(VD))
507-
continue;
508-
Properties.push_back(extractTypePropertyInfo(VD));
509-
}
511+
auto extract = [&](class Decl *Member) {
512+
// Ignore plain stored properties collected above,
513+
// instead gather up remaining static and computed properties.
514+
if (auto *VD = dyn_cast<VarDecl>(Member))
515+
if (!StoredPropertiesSet.count(VD))
516+
Properties.push_back(extractTypePropertyInfo(VD));
517+
};
510518

519+
if (shouldExtract(Decl)) {
520+
for (auto Member : Decl->getAllMembers()) {
521+
extract(Member);
522+
}
511523
EnumCases = extractEnumCases(Decl);
512524
}
513525

514526
for (auto Extension: Decl->getExtensions()) {
515527
if (shouldExtract(Extension)) {
516-
for (auto Member : Extension->getMembers()) {
517-
if (auto *VD = dyn_cast<VarDecl>(Member)) {
518-
Properties.push_back(extractTypePropertyInfo(VD));
519-
}
528+
for (auto Member : Extension->getAllMembers()) {
529+
extract(Member);
520530
}
521531
}
522532
}
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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// REQUIRES: objc_interop
2+
// RUN: %empty-directory(%t)
3+
// RUN: echo "[MyProto]" > %t/protocols.json
4+
5+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractFromObjcImplementationExtension.swiftconstvalues -const-gather-protocols-file %t/protocols.json %s -import-objc-header %S/Inputs/objc_implementation.h -disable-objc-attr-requires-foundation-module
6+
// RUN: cat %t/ExtractFromObjcImplementationExtension.swiftconstvalues 2>&1 | %FileCheck %s
7+
8+
protocol MyProto { }
9+
10+
extension ImplClass: MyProto {
11+
static let notStoredProperty = true
12+
}
13+
14+
@_objcImplementation extension ImplClass {
15+
@objc var defaultIntProperty: CInt = 17
16+
final weak var defaultNilProperty: AnyObject?
17+
}
18+
19+
// CHECK: "typeName": "__ObjC.ImplClass",
20+
// CHECK: "properties": [
21+
// CHECK: "label": "defaultIntProperty",
22+
// CHECK: "type": "Swift.Int32",
23+
// CHECK: "value": "17"
24+
25+
// CHECK: "label": "defaultNilProperty",
26+
// CHECK: "type": "Swift.Optional<AnyObject>",
27+
// CHECK: "value": "nil"
28+
29+
// CHECK: "label": "notStoredProperty",
30+
// CHECK: "type": "Swift.Bool",
31+
// CHECK: "value": "true"

0 commit comments

Comments
 (0)