Skip to content

Commit 37d0027

Browse files
authored
Merge pull request #1225 from hborla/type-wrapper-macro
[Macros] Implement a type wrapper transformation as a macro.
2 parents 3916bdb + 0842f41 commit 37d0027

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

Tests/SwiftSyntaxMacrosTest/MacroSystemTests.swift

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,74 @@ public struct WrapStoredProperties: MemberAttributeMacro {
468468
}
469469
}
470470

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+
471539
// MARK: Assertion helper functions
472540

473541
/// Assert that expanding the given macros in the original source produces
@@ -534,6 +602,7 @@ public let testMacros: [String: Macro.Type] = [
534602
"addBackingStorage": AddBackingStorage.self,
535603
"wrapAllProperties": WrapAllProperties.self,
536604
"wrapStoredProperties": WrapStoredProperties.self,
605+
"customTypeWrapper": CustomTypeWrapperMacro.self,
537606
]
538607

539608
final class MacroSystemTests: XCTestCase {
@@ -788,4 +857,41 @@ final class MacroSystemTests: XCTestCase {
788857
"""
789858
)
790859
}
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+
}
791897
}

0 commit comments

Comments
 (0)