From 7552b0ac800727ef64690acae9c8f914c46c4d26 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Jan 2024 19:07:46 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9A=A8=20lint=20spacing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/DiagramTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/TCADiagramLibTests/DiagramTests.swift b/Tests/TCADiagramLibTests/DiagramTests.swift index 0aa0094..7cde348 100644 --- a/Tests/TCADiagramLibTests/DiagramTests.swift +++ b/Tests/TCADiagramLibTests/DiagramTests.swift @@ -21,7 +21,7 @@ final class DiagramTests: XCTestCase { SignUpAgreement(SignUpAgreement: 1) ``` """ - XCTAssertEqual(result, expected) + XCTAssertEqual(result, expected) } func testReducerProtocolExample() throws { From 83ec407ca3d9166e7c296afb88697e6f5e1b8af7 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Jan 2024 19:08:03 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=A7=AA=20reducer=20macro=20failing=20?= =?UTF-8?q?test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/DiagramTests.swift | 22 +++++++ .../Resources/Sources.swift | 64 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/Tests/TCADiagramLibTests/DiagramTests.swift b/Tests/TCADiagramLibTests/DiagramTests.swift index 7cde348..e9d27db 100644 --- a/Tests/TCADiagramLibTests/DiagramTests.swift +++ b/Tests/TCADiagramLibTests/DiagramTests.swift @@ -67,4 +67,26 @@ final class DiagramTests: XCTestCase { """ XCTAssertEqual(result, expected) } + + func testReducerMacroExample() throws { + let result = try Diagram.dump(reducerMacroSampleSource) + let expected = """ + ```mermaid + %%{ init : { "theme" : "default", "flowchart" : { "curve" : "monotoneY" }}}%% + graph LR + SelfLessonDetail -- optional --> DoubleIfLetChild + SelfLessonDetail ---> DoubleScopeChild + SelfLessonDetail ---> Payment + SelfLessonDetail -- optional --> SantaWeb + SelfLessonDetail -- optional --> SelfLessonDetailFilter + + DoubleIfLetChild(DoubleIfLetChild: 1) + DoubleScopeChild(DoubleScopeChild: 1) + Payment(Payment: 1) + SantaWeb(SantaWeb: 1) + SelfLessonDetailFilter(SelfLessonDetailFilter: 1) + ``` + """ + XCTAssertEqual(result, expected) + } } diff --git a/Tests/TCADiagramLibTests/Resources/Sources.swift b/Tests/TCADiagramLibTests/Resources/Sources.swift index f1f0741..b7c8d2c 100644 --- a/Tests/TCADiagramLibTests/Resources/Sources.swift +++ b/Tests/TCADiagramLibTests/Resources/Sources.swift @@ -200,3 +200,67 @@ let reducerSampleSource: [String] = [ } """ ] + +let reducerMacroSampleSource: [String] = [ + """ + @Reducer + public struct SelfLessonDetail { + @Dependency(\\.environmentSelfLessonDetail) private var environment + + public init() {} + + public var body: some Reducer { + BindingReducer() + Scope(state: \\State.payment, action: /Action.payment) { + Payment() + } + + Scope(state: \\.subState, action: .self) { + Scope( + state: /State.SubState.promotionWeb, + action: /Action.promotionWeb + ) { + DoubleScopeChild() + } + } + + Reduce { state, action in + switch action { + case default: + return .none + } + } + .ifLet(\\.filter, action: \\.filter) { + SelfLessonDetailFilter() + } + .ifLet(\\.selection, action: \\.web) { + SantaWeb() + } + .ifLet(\\SelfLessonDetail.State.selection, action: /SelfLessonDetail.Action.webView) { + EmptyReducer() + .ifLet(\\Identified.value, action: .self) { + DoubleIfLetChild() + } + } + } + } + """, + """ + extension SelfLessonDetail { + public enum Action: Equatable { + } + } + extension Payment { + public enum Action: Equatable { + } + } + extension SantaWeb { + public enum Action: Equatable { + } + } + extension SelfLessonDetailFilter { + public enum Action: Equatable { + } + } + """ +] From f2721483970af14bca0df07f42394a9d1786cb1c Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Jan 2024 19:12:24 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.gitignore b/.gitignore index 3b29812..03a7043 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,36 @@ DerivedData/ .swiftpm/config/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc + +# Created by https://www.toptal.com/developers/gitignore/api/xcode,swiftpm,swiftpackagemanager +# Edit at https://www.toptal.com/developers/gitignore?templates=xcode,swiftpm,swiftpackagemanager + +### SwiftPackageManager ### +Packages +.build/ +xcuserdata +DerivedData/ +*.xcodeproj + + +### SwiftPM ### + + +### Xcode ### +## User settings +xcuserdata/ + +## Xcode 8 and earlier +*.xcscmblueprint +*.xccheckout + +### Xcode Patch ### +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcodeproj/project.xcworkspace/ +!*.xcworkspace/contents.xcworkspacedata +/*.gcno +**/xcshareddata/WorkspaceSettings.xcsettings + +# End of https://www.toptal.com/developers/gitignore/api/xcode,swiftpm,swiftpackagemanager From 2ff72d2e522d568ac3ae373cac9b00e849298cc6 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Jan 2024 19:17:45 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20childs=20to=20children?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Internal/Parser.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/TCADiagramLib/Internal/Parser.swift b/Sources/TCADiagramLib/Internal/Parser.swift index 3b4ff40..b6d5e75 100644 --- a/Sources/TCADiagramLib/Internal/Parser.swift +++ b/Sources/TCADiagramLib/Internal/Parser.swift @@ -42,8 +42,8 @@ extension SourceFileSyntax { actions: inout Set, relations: inout [Relation] ) throws { - if let (childs, isOptional) = try predicateChildReducerProtocol(node) { - childs.forEach { child in + if let (children, isOptional) = try predicateChildReducerProtocol(node) { + children.forEach { child in relations.append( .init( parent: parent, @@ -100,8 +100,9 @@ extension SourceFileSyntax { // ifLet can be in "method chaining" // therefore find all reducer names that match and save in child if - node.tokens(viewMode: .fixedUp).contains(where: { $0.tokenKind == .identifier("ifLet") }) { - let childs = node.description + node.tokens(viewMode: .fixedUp).contains(where: { $0.tokenKind == .identifier("ifLet") }) + { + let children = node.description .matches(of: try Regex("ifLet.+{\\s+(.+?)\\(\\)")) .compactMap { $0[1].substring?.description @@ -109,7 +110,7 @@ extension SourceFileSyntax { .filter { $0 != "EmptyReducer" } - return (childs, true) + return (children, true) } } return .none From 7c9356b71bf4289a35575c65889d17634cc09a77 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Jan 2024 19:22:58 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=94=A7=20update=20schemes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcschemes/TCADiagram-Package.xcscheme | 35 +++---------------- .../xcschemes/tca-diagram-lib.xcscheme | 9 +++-- .../xcschemes/tca-diagram.xcscheme | 20 +++-------- 3 files changed, 13 insertions(+), 51 deletions(-) diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/TCADiagram-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/TCADiagram-Package.xcscheme index b9885e2..b2bfe19 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/TCADiagram-Package.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/TCADiagram-Package.xcscheme @@ -1,7 +1,7 @@ + LastUpgradeVersion = "1520" + version = "1.7"> @@ -48,41 +48,14 @@ ReferencedContainer = "container:"> - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/tca-diagram-lib.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/tca-diagram-lib.xcscheme index d4edfda..055609b 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/tca-diagram-lib.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/tca-diagram-lib.xcscheme @@ -1,7 +1,7 @@ + LastUpgradeVersion = "1520" + version = "1.7"> @@ -26,9 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> + LastUpgradeVersion = "1520" + version = "1.7"> @@ -40,7 +40,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> @@ -63,8 +64,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES" - viewDebuggingEnabled = "No"> + allowLocationSimulation = "YES"> - - - - - - Date: Mon, 29 Jan 2024 19:26:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=91=94=20add=20@Reducer=20macro=20che?= =?UTF-8?q?ck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Internal/Parser.swift | 36 +++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Sources/TCADiagramLib/Internal/Parser.swift b/Sources/TCADiagramLib/Internal/Parser.swift index b6d5e75..5cbe4f1 100644 --- a/Sources/TCADiagramLib/Internal/Parser.swift +++ b/Sources/TCADiagramLib/Internal/Parser.swift @@ -67,17 +67,32 @@ extension SourceFileSyntax { extension SourceFileSyntax { - /// Get parent name from feature with superclass of ReducerProtocol + /// Get parent name from feature. private func predicateReducerProtocol(_ node: Syntax) throws -> String? { if - let node = StructDeclSyntax(node), - node.inheritanceClause?.tokens(viewMode: .fixedUp) - .contains(where: { - $0.tokenKind == .identifier("ReducerProtocol") - || $0.tokenKind == .identifier("Reducer") - }) == true + let node = StructDeclSyntax(node) { - return node.identifier.text + /// Has @Reducer macro + if + node.attributes?.contains(where: { element in + element.tokens(viewMode: .fixedUp).contains { el in + el.tokenKind == .identifier("Reducer") + } + }) == true + { + debugPrint(node.identifier.text) + return node.identifier.text + } + /// superclass of ReducerProtocol or Reducer + if + node.inheritanceClause?.tokens(viewMode: .fixedUp) + .contains(where: { + $0.tokenKind == .identifier("ReducerProtocol") + || $0.tokenKind == .identifier("Reducer") + }) == true + { + return node.identifier.text + } } return nil } @@ -93,7 +108,8 @@ extension SourceFileSyntax { let child = node.trailingClosure?.statements.first?.description .firstMatch(of: try Regex("\\s*(.+?)\\(\\)"))?[1] .substring? - .description { + .description + { return ([child], false) } @@ -186,7 +202,7 @@ extension SourceFileSyntax { /// check if `pullback` chains `optional()`. private func isOptionalPullback(_ node: FunctionCallExprSyntax) -> Bool { var stack: [Syntax] = node.children(viewMode: .fixedUp).reversed() - while(!stack.isEmpty) { + while !stack.isEmpty { let node = stack.removeFirst() if let node = FunctionCallExprSyntax(node),