@@ -467,6 +467,74 @@ public struct WrapStoredProperties: MemberAttributeMacro {
467
467
}
468
468
}
469
469
470
+ struct CustomTypeWrapperMacro { }
471
+
472
+ extension CustomTypeWrapperMacro : MemberDeclarationMacro {
473
+ static func expansion(
474
+ of node: CustomAttributeSyntax ,
475
+ attachedTo declaration: DeclSyntax ,
476
+ in context: inout MacroExpansionContext
477
+ ) throws -> [ DeclSyntax ] {
478
+ return [
479
+ """
480
+
481
+ var _storage: Wrapper<Self>
482
+ """
483
+ ]
484
+ }
485
+ }
486
+
487
+ extension CustomTypeWrapperMacro : MemberAttributeMacro {
488
+ static func expansion(
489
+ of node: CustomAttributeSyntax ,
490
+ attachedTo declaration: DeclSyntax ,
491
+ annotating member: DeclSyntax ,
492
+ in context: inout MacroExpansionContext
493
+ ) throws -> [ CustomAttributeSyntax ] {
494
+ return [
495
+ CustomAttributeSyntax (
496
+ attributeName: SimpleTypeIdentifierSyntax (
497
+ name: . identifier( " customTypeWrapper " )
498
+ )
499
+ )
500
+ . withLeadingTrivia ( [ . newlines( 1 ) , . spaces( 2 ) ] )
501
+ ]
502
+ }
503
+ }
504
+
505
+ extension CustomTypeWrapperMacro : AccessorDeclarationMacro {
506
+ static func expansion(
507
+ of node: CustomAttributeSyntax ,
508
+ attachedTo declaration: DeclSyntax ,
509
+ in context: inout MacroExpansionContext
510
+ ) throws -> [ AccessorDeclSyntax ] {
511
+ guard let property = declaration. as ( VariableDeclSyntax . self) ,
512
+ let binding = property. bindings. first,
513
+ let identifier = binding. pattern. as ( IdentifierPatternSyntax . self) ? . identifier,
514
+ binding. accessor == nil
515
+ else {
516
+ return [ ]
517
+ }
518
+
519
+ if identifier. text == " _storage " { return [ ] }
520
+
521
+ return [
522
+ """
523
+
524
+ get {
525
+ _storage[wrappedKeyPath: \\ . \( identifier) ]
526
+ }
527
+ """ ,
528
+ """
529
+
530
+ set {
531
+ _storage[wrappedKeyPath: \\ . \( identifier) ] = newValue
532
+ }
533
+ """ ,
534
+ ]
535
+ }
536
+ }
537
+
470
538
// MARK: Assertion helper functions
471
539
472
540
/// Assert that expanding the given macros in the original source produces
@@ -533,6 +601,7 @@ public let testMacros: [String: Macro.Type] = [
533
601
" addBackingStorage " : AddBackingStorage . self,
534
602
" wrapAllProperties " : WrapAllProperties . self,
535
603
" wrapStoredProperties " : WrapStoredProperties . self,
604
+ " customTypeWrapper " : CustomTypeWrapperMacro . self,
536
605
]
537
606
538
607
final class MacroSystemTests : XCTestCase {
@@ -787,4 +856,41 @@ final class MacroSystemTests: XCTestCase {
787
856
"""
788
857
)
789
858
}
859
+
860
+ func testTypeWrapperTransform( ) {
861
+ AssertMacroExpansion (
862
+ macros: testMacros,
863
+ """
864
+ @customTypeWrapper
865
+ struct Point {
866
+ var x: Int
867
+ var y: Int
868
+ }
869
+ """ ,
870
+ // FIXME: Accessor brace indentation is off
871
+ """
872
+
873
+ struct Point {
874
+ var x: Int {
875
+ get {
876
+ _storage[wrappedKeyPath: \\ .x]
877
+ }
878
+ set {
879
+ _storage[wrappedKeyPath: \\ .x] = newValue
880
+ }
881
+ }
882
+ var y: Int {
883
+ get {
884
+ _storage[wrappedKeyPath: \\ .y]
885
+ }
886
+ set {
887
+ _storage[wrappedKeyPath: \\ .y] = newValue
888
+ }
889
+ }
890
+ var _storage: Wrapper<Self>
891
+ }
892
+ """
893
+ )
894
+
895
+ }
790
896
}
0 commit comments