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