@@ -19,6 +19,7 @@ public struct GenerableMacro: MemberMacro, ExtensionMacro {
1919
2020 return [
2121 generateRawContentProperty ( ) ,
22+ generateMemberwiseInit ( properties: properties) ,
2223 generateInitFromGeneratedContent ( structName: structName, properties: properties) ,
2324 generateGeneratedContentProperty (
2425 structName: structName,
@@ -69,7 +70,10 @@ public struct GenerableMacro: MemberMacro, ExtensionMacro {
6970 conformingTo protocols: [ TypeSyntax ] ,
7071 in context: some MacroExpansionContext
7172 ) throws -> [ ExtensionDeclSyntax ] {
73+ let nonisolatedModifier = DeclModifierSyntax ( name: . keyword( . nonisolated) )
74+
7275 let extensionDecl = ExtensionDeclSyntax (
76+ modifiers: DeclModifierListSyntax ( [ nonisolatedModifier] ) ,
7377 extendedType: type,
7478 inheritanceClause: InheritanceClauseSyntax (
7579 inheritedTypes: InheritedTypeListSyntax ( [
@@ -247,6 +251,91 @@ public struct GenerableMacro: MemberMacro, ExtensionMacro {
247251 )
248252 }
249253
254+ private static func generateMemberwiseInit( properties: [ PropertyInfo ] ) -> DeclSyntax {
255+ if properties. isEmpty {
256+ return DeclSyntax (
257+ stringLiteral: """
258+ nonisolated public init() {
259+ self._rawGeneratedContent = GeneratedContent(kind: .structure(properties: [:], orderedKeys: []))
260+ }
261+ """
262+ )
263+ }
264+
265+ let parameters = properties. map { prop in
266+ " \( prop. name) : \( prop. type) "
267+ } . joined ( separator: " , " )
268+
269+ let assignments = properties. map { prop in
270+ " self. \( prop. name) = \( prop. name) "
271+ } . joined ( separator: " \n " )
272+
273+ let propertyConversions = properties. map { prop in
274+ let propName = prop. name
275+ let propType = prop. type
276+
277+ if propType. hasSuffix ( " ? " ) {
278+ let baseType = String ( propType. dropLast ( ) )
279+ if baseType == " String " {
280+ return
281+ " properties[ \" \( propName) \" ] = \( propName) .map { GeneratedContent($0) } ?? GeneratedContent(kind: .null) "
282+ } else if baseType == " Int " || baseType == " Double " || baseType == " Float "
283+ || baseType == " Bool " || baseType == " Decimal "
284+ {
285+ return
286+ " properties[ \" \( propName) \" ] = \( propName) .map { $0.generatedContent } ?? GeneratedContent(kind: .null) "
287+ } else if isDictionaryType ( baseType) {
288+ return
289+ " properties[ \" \( propName) \" ] = \( propName) .map { $0.generatedContent } ?? GeneratedContent(kind: .null) "
290+ } else if baseType. hasPrefix ( " [ " ) && baseType. hasSuffix ( " ] " ) {
291+ return
292+ " properties[ \" \( propName) \" ] = \( propName) .map { GeneratedContent(elements: $0) } ?? GeneratedContent(kind: .null) "
293+ } else {
294+ return """
295+ if let value = \( propName) {
296+ properties[ " \( propName) " ] = value.generatedContent
297+ } else {
298+ properties[ " \( propName) " ] = GeneratedContent(kind: .null)
299+ }
300+ """
301+ }
302+ } else if isDictionaryType ( propType) {
303+ return " properties[ \" \( propName) \" ] = \( propName) .generatedContent "
304+ } else if propType. hasPrefix ( " [ " ) && propType. hasSuffix ( " ] " ) {
305+ return " properties[ \" \( propName) \" ] = GeneratedContent(elements: \( propName) ) "
306+ } else {
307+ switch propType {
308+ case " String " :
309+ return " properties[ \" \( propName) \" ] = GeneratedContent( \( propName) ) "
310+ case " Int " , " Double " , " Float " , " Bool " , " Decimal " :
311+ return " properties[ \" \( propName) \" ] = \( propName) .generatedContent "
312+ default :
313+ return " properties[ \" \( propName) \" ] = \( propName) .generatedContent "
314+ }
315+ }
316+ } . joined ( separator: " \n " )
317+
318+ let orderedKeys = properties. map { " \" \( $0. name) \" " } . joined ( separator: " , " )
319+
320+ return DeclSyntax (
321+ stringLiteral: """
322+ nonisolated public init( \( parameters) ) {
323+ \( assignments)
324+
325+ var properties: [String: GeneratedContent] = [:]
326+ \( propertyConversions)
327+
328+ self._rawGeneratedContent = GeneratedContent(
329+ kind: .structure(
330+ properties: properties,
331+ orderedKeys: [ \( orderedKeys) ]
332+ )
333+ )
334+ }
335+ """
336+ )
337+ }
338+
250339 private static func generateInitFromGeneratedContent(
251340 structName: String ,
252341 properties: [ PropertyInfo ]
@@ -457,16 +546,7 @@ public struct GenerableMacro: MemberMacro, ExtensionMacro {
457546 } else if isDictionaryType ( propType) {
458547 return " properties[ \" \( propName) \" ] = \( propName) .generatedContent "
459548 } else if propType. hasPrefix ( " [ " ) && propType. hasSuffix ( " ] " ) {
460- let elementType = String ( propType. dropFirst ( ) . dropLast ( ) )
461- if elementType == " String " {
462- return " properties[ \" \( propName) \" ] = GeneratedContent(elements: \( propName) ) "
463- } else if elementType == " Int " || elementType == " Double " || elementType == " Bool "
464- || elementType == " Float " || elementType == " Decimal "
465- {
466- return " properties[ \" \( propName) \" ] = GeneratedContent(elements: \( propName) ) "
467- } else {
468- return " properties[ \" \( propName) \" ] = GeneratedContent(elements: \( propName) ) "
469- }
549+ return " properties[ \" \( propName) \" ] = GeneratedContent(elements: \( propName) ) "
470550 } else {
471551 switch propType {
472552 case " String " :
0 commit comments