File tree Expand file tree Collapse file tree 3 files changed +56
-14
lines changed
Expand file tree Collapse file tree 3 files changed +56
-14
lines changed Original file line number Diff line number Diff line change @@ -174,14 +174,24 @@ public struct ControllableMacro: PeerMacro {
174174 }
175175
176176 let callPrefix = ControllableMacroSupport . callPrefix ( for: functionDecl. signature)
177- let copyKeyword = ControllableMacroSupport . requiresMutableCopy ( functionDecl. modifiers) ? " var " : " let "
178177 let arguments = ControllableMacroSupport . argumentList ( from: functionDecl. signature. parameterClause)
179- let invocation = arguments. isEmpty ? " controllable. \( identifier) () " : " controllable. \( identifier) ( \( arguments) ) "
180- let bodyLines = [
181- " \( copyKeyword) controllable = self " ,
182- " let _: Void = \( callPrefix) \( invocation) " ,
183- " return controllable "
184- ]
178+ let isReferenceType = MacroSupport . isReferenceTypeContext ( for: functionDecl)
179+ let requiresCopy = ControllableMacroSupport . requiresMutableCopy ( functionDecl. modifiers) && !isReferenceType
180+
181+ let invocationTarget = requiresCopy ? " controllable " : " self "
182+ let invocation = arguments. isEmpty
183+ ? " \( invocationTarget) . \( identifier) () "
184+ : " \( invocationTarget) . \( identifier) ( \( arguments) ) "
185+
186+ var bodyLines : [ String ] = [ ]
187+ if requiresCopy {
188+ bodyLines. append ( " var controllable = self " )
189+ bodyLines. append ( " let _: Void = \( callPrefix) \( invocation) " )
190+ bodyLines. append ( " return controllable " )
191+ } else {
192+ bodyLines. append ( " let _: Void = \( callPrefix) \( invocation) " )
193+ bodyLines. append ( " return self " )
194+ }
185195
186196 var lines : [ String ] = [ ]
187197 if !attributesText. isEmpty {
Original file line number Diff line number Diff line change @@ -83,13 +83,27 @@ public struct DelegatableMacro: PeerMacro {
8383 let accessModifier = MacroSupport . enclosingAccessModifier ( for: varDecl)
8484 let accessModifierText = accessModifier. map { " \( $0. text) " } ?? " "
8585
86- let functionDecl : DeclSyntax = """
87- \( raw: accessModifierText) func \( raw: propertyName) (_ perform: @escaping \( raw: parameterTypeDescription) ) -> Self {
88- var delegator = self
89- delegator. \( raw: propertyName) = perform
90- return delegator
91- }
92- """
86+ let isReferenceType = MacroSupport . isReferenceTypeContext ( for: varDecl)
87+ let functionDecl : DeclSyntax
88+
89+ if isReferenceType {
90+ functionDecl = """
91+ @discardableResult
92+ \( raw: accessModifierText) func \( raw: propertyName) (_ perform: @escaping \( raw: parameterTypeDescription) ) -> Self {
93+ self. \( raw: propertyName) = perform
94+ return self
95+ }
96+ """
97+ } else {
98+ functionDecl = """
99+ @discardableResult
100+ \( raw: accessModifierText) func \( raw: propertyName) (_ perform: @escaping \( raw: parameterTypeDescription) ) -> Self {
101+ var delegator = self
102+ delegator. \( raw: propertyName) = perform
103+ return delegator
104+ }
105+ """
106+ }
93107
94108 return [ functionDecl]
95109 }
Original file line number Diff line number Diff line change @@ -21,6 +21,24 @@ enum MacroSupport {
2121 accessModifier ( from: enclosingDeclModifierList ( for: declaration) )
2222 }
2323
24+ static func isReferenceTypeContext( for declaration: some SyntaxProtocol ) -> Bool {
25+ var currentParent = Syntax ( declaration) . parent
26+
27+ while let parent = currentParent {
28+ if parent. is ( ClassDeclSyntax . self) || parent. is ( ActorDeclSyntax . self) {
29+ return true
30+ }
31+
32+ if parent. is ( StructDeclSyntax . self) || parent. is ( EnumDeclSyntax . self) {
33+ return false
34+ }
35+
36+ currentParent = parent. parent
37+ }
38+
39+ return false
40+ }
41+
2442 static func isAccessModifier( _ modifier: DeclModifierSyntax ) -> Bool {
2543 switch modifier. name. tokenKind {
2644 case . keyword( . public) ,
You can’t perform that action at this time.
0 commit comments