Skip to content

Commit e04a791

Browse files
committed
[Macros] Allow synthesized member macros to add member type and method decls.
1 parent 6a17bb6 commit e04a791

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,13 @@ static ArrayRef<Decl *> evaluateMembersRequest(
27892789
}
27902790
}
27912791

2792+
// Expand synthesized member macros.
2793+
auto *mutableDecl = const_cast<Decl *>(idc->getDecl());
2794+
(void)evaluateOrDefault(
2795+
ctx.evaluator,
2796+
ExpandSynthesizedMemberMacroRequest{mutableDecl},
2797+
false);
2798+
27922799
// If the decl has a @main attribute, we need to force synthesis of the
27932800
// $main function.
27942801
(void) evaluateOrDefault(

lib/Sema/TypeCheckStorage.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ static void computeLoweredStoredProperties(NominalTypeDecl *decl,
114114
(void)decl->getTypeWrapperProperty();
115115

116116
// Expand synthesized member macros.
117-
// FIXME: Member macros can add members other than stored properties.
118117
auto &ctx = decl->getASTContext();
119118
evaluateOrDefault(ctx.evaluator,
120119
ExpandSynthesizedMemberMacroRequest{decl},

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,32 @@ public struct AccessViaStorageMacro: AccessorDeclarationMacro {
346346
]
347347
}
348348
}
349+
350+
public struct AddMembers: MemberDeclarationMacro {
351+
public static func expansion(
352+
of node: AttributeSyntax,
353+
attachedTo decl: DeclSyntax,
354+
in context: inout MacroExpansionContext
355+
) throws -> [DeclSyntax] {
356+
let storageStruct: StructDeclSyntax =
357+
"""
358+
struct Nested {}
359+
"""
360+
361+
let storageVariable: VariableDeclSyntax =
362+
"""
363+
var value: Int = 0
364+
"""
365+
366+
let instanceMethod: FunctionDeclSyntax =
367+
"""
368+
func method() { print("synthesized method") }
369+
"""
370+
371+
return [
372+
DeclSyntax(storageStruct),
373+
DeclSyntax(storageVariable),
374+
DeclSyntax(instanceMethod),
375+
]
376+
}
377+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -I %swift-host-lib-dir -L %swift-host-lib-dir -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
3+
// RUNx: %target-swift-frontend -dump-ast -enable-experimental-feature Macros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -module-name MacroUser 2>&1 | %FileCheck --check-prefix CHECK-AST %s
4+
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Macros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
5+
// RUN: %target-build-swift -enable-experimental-feature Macros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -L %swift-host-lib-dir %s -o %t/main -module-name MacroUser -swift-version 5
6+
// RUN: %target-run %t/main | %FileCheck %s
7+
// REQUIRES: executable_test
8+
9+
// FIXME: Swift parser is not enabled on Linux CI yet.
10+
// REQUIRES: OS=macosx
11+
12+
@attached(synthesizedMembers) macro addMembers() = #externalMacro(module: "MacroDefinition", type: "AddMembers")
13+
14+
@addMembers
15+
struct S {
16+
func useSynthesized() {
17+
print(s.value)
18+
print(S.Nested())
19+
s.method()
20+
}
21+
}
22+
23+
let s = S()
24+
25+
// CHECK: 0
26+
// CHECK: Nested
27+
// CHECK: synthesized method
28+
s.useSynthesized()

0 commit comments

Comments
 (0)