@@ -248,9 +248,6 @@ extension ObservableStateMacro: MemberMacro {
248248
249249 var declarations = [ DeclSyntax] ( )
250250
251- let access = declaration. modifiers. first {
252- $0. name. tokenKind == . keyword( . public) || $0. name. tokenKind == . keyword( . package )
253- }
254251 declaration. addIfNeeded (
255252 ObservableStateMacro . registrarVariable ( observableType) , to: & declarations)
256253 declaration. addIfNeeded ( ObservableStateMacro . idVariable ( ) , to: & declarations)
@@ -260,6 +257,106 @@ extension ObservableStateMacro: MemberMacro {
260257 }
261258}
262259
260+ extension Array where Element == ObservableStateCase {
261+ init ( members: MemberBlockItemListSyntax ) {
262+ var tag = 0
263+ self . init ( members: members, tag: & tag)
264+ }
265+
266+ init ( members: MemberBlockItemListSyntax , tag: inout Int ) {
267+ self = members. flatMap { member -> [ ObservableStateCase ] in
268+ if let enumCaseDecl = member. decl. as ( EnumCaseDeclSyntax . self) {
269+ return enumCaseDecl. elements. map {
270+ defer { tag += 1 }
271+ return ObservableStateCase . element ( $0, tag: tag)
272+ }
273+ }
274+ if let ifConfigDecl = member. decl. as ( IfConfigDeclSyntax . self) {
275+ let configs = ifConfigDecl. clauses. flatMap { decl -> [ ObservableStateCase . IfConfig ] in
276+ guard let elements = decl. elements? . as ( MemberBlockItemListSyntax . self)
277+ else { return [ ] }
278+ return [
279+ ObservableStateCase . IfConfig (
280+ poundKeyword: decl. poundKeyword,
281+ condition: decl. condition,
282+ cases: Array ( members: elements, tag: & tag)
283+ )
284+ ]
285+ }
286+ return [ . ifConfig( configs) ]
287+ }
288+ return [ ]
289+ }
290+ }
291+ }
292+
293+ enum ObservableStateCase {
294+ case element( EnumCaseElementSyntax , tag: Int )
295+ indirect case ifConfig( [ IfConfig ] )
296+
297+ struct IfConfig {
298+ let poundKeyword : TokenSyntax
299+ let condition : ExprSyntax ?
300+ let cases : [ ObservableStateCase ]
301+ }
302+
303+ var getCase : String {
304+ switch self {
305+ case let . element( element, tag) :
306+ if let parameters = element. parameterClause? . parameters, parameters. count == 1 {
307+ return """
308+ case let . \( element. name. text) (state):
309+ return ._$id(for: state)._$tag( \( tag) )
310+ """
311+ } else {
312+ return """
313+ case . \( element. name. text) :
314+ return ._$inert._$tag( \( tag) )
315+ """
316+ }
317+ case let . ifConfig( configs) :
318+ return configs
319+ . map {
320+ """
321+ \( $0. poundKeyword. text) \( $0. condition? . trimmedDescription ?? " " )
322+ \( $0. cases. map ( \. getCase) . joined ( separator: " \n " ) )
323+ """
324+ }
325+ . joined ( separator: " \n " ) + " #endif \n "
326+ }
327+ }
328+
329+ var willModifyCase : String {
330+ switch self {
331+ case let . element( element, _) :
332+ if let parameters = element. parameterClause? . parameters,
333+ parameters. count == 1 ,
334+ let parameter = parameters. first
335+ {
336+ return """
337+ case var . \( element. name. text) (state):
338+ \( ObservableStateMacro . moduleName) ._$willModify(&state)
339+ self = . \( element. name. text) ( \( parameter. firstName. map { " \( $0) : " } ?? " " ) state)
340+ """
341+ } else {
342+ return """
343+ case . \( element. name. text) :
344+ break
345+ """
346+ }
347+ case let . ifConfig( configs) :
348+ return configs
349+ . map {
350+ """
351+ \( $0. poundKeyword. text) \( $0. condition? . trimmedDescription ?? " " )
352+ \( $0. cases. map ( \. willModifyCase) . joined ( separator: " \n " ) )
353+ """
354+ }
355+ . joined ( separator: " \n " ) + " #endif \n "
356+ }
357+ }
358+ }
359+
263360extension ObservableStateMacro {
264361 public static func enumExpansion<
265362 Declaration: DeclGroupSyntax ,
@@ -269,43 +366,12 @@ extension ObservableStateMacro {
269366 providingMembersOf declaration: Declaration ,
270367 in context: Context
271368 ) throws -> [ DeclSyntax ] {
272- let enumCaseDecls = declaration. memberBlock. members
273- . flatMap { $0. decl. as ( EnumCaseDeclSyntax . self) ? . elements ?? [ ] }
369+ let cases = [ ObservableStateCase] ( members: declaration. memberBlock. members)
274370 var getCases : [ String ] = [ ]
275371 var willModifyCases : [ String ] = [ ]
276- for (tag, enumCaseDecl) in enumCaseDecls. enumerated ( ) {
277- // TODO: Support multiple parameters of observable state?
278- if let parameters = enumCaseDecl. parameterClause? . parameters,
279- parameters. count == 1 ,
280- let parameter = parameters. first
281- {
282- getCases. append (
283- """
284- case let . \( enumCaseDecl. name. text) (state):
285- return ._$id(for: state)._$tag( \( tag) )
286- """
287- )
288- willModifyCases. append (
289- """
290- case var . \( enumCaseDecl. name. text) (state):
291- \( moduleName) ._$willModify(&state)
292- self = . \( enumCaseDecl. name. text) ( \( parameter. firstName. map { " \( $0) : " } ?? " " ) state)
293- """
294- )
295- } else {
296- getCases. append (
297- """
298- case . \( enumCaseDecl. name. text) :
299- return ._$inert._$tag( \( tag) )
300- """
301- )
302- willModifyCases. append (
303- """
304- case . \( enumCaseDecl. name. text) :
305- break
306- """
307- )
308- }
372+ for enumCase in cases {
373+ getCases. append ( enumCase. getCase)
374+ willModifyCases. append ( enumCase. willModifyCase)
309375 }
310376
311377 return [
0 commit comments