From 854b1c8cff3a953f37e4e8db5a2f95c9513d3768 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Sun, 28 Apr 2024 16:10:17 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=F0=9F=93=8C=20swift-syntax=20510.0.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Package.resolved | 8 ++++---- Package.swift | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Package.resolved b/Package.resolved index 0a3cc86..5a736cb 100644 --- a/Package.resolved +++ b/Package.resolved @@ -3,7 +3,7 @@ { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", - "location" : "git@github.com:apple/swift-argument-parser.git", + "location" : "https://github.com/apple/swift-argument-parser.git", "state" : { "revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d", "version" : "1.2.0" @@ -12,10 +12,10 @@ { "identity" : "swift-syntax", "kind" : "remoteSourceControl", - "location" : "git@github.com:apple/swift-syntax.git", + "location" : "https://github.com/apple/swift-syntax.git", "state" : { - "branch" : "main", - "revision" : "1d555c8fb517e5e9cee3aca149466bc6a429611b" + "revision" : "fa8f95c2d536d6620cc2f504ebe8a6167c9fc2dd", + "version" : "510.0.1" } } ], diff --git a/Package.swift b/Package.swift index ccef627..2568e54 100644 --- a/Package.swift +++ b/Package.swift @@ -12,7 +12,7 @@ let package = Package( .executable(name: "tca-diagram", targets: ["TCADiagram"]), ], dependencies: [ - .package(url: "https://github.com/apple/swift-syntax.git", branch: "main"), + .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1"), .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), ], targets: [ From f9b919012176ceb9ba959b5fa667a2efbe38b566 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Apr 2024 02:05:52 +0900 Subject: [PATCH 02/12] =?UTF-8?q?=E2=9C=85=20add=20test=20for=20\.$detail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/Resources/Sources.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/TCADiagramLibTests/Resources/Sources.swift b/Tests/TCADiagramLibTests/Resources/Sources.swift index b7c8d2c..85be16d 100644 --- a/Tests/TCADiagramLibTests/Resources/Sources.swift +++ b/Tests/TCADiagramLibTests/Resources/Sources.swift @@ -169,7 +169,7 @@ let reducerSampleSource: [String] = [ .ifLet(\\.filter, action: /Action.filter) { SelfLessonDetailFilter() } - .ifLet(\\.selection, action: /Action.web) { + .ifLet(\\.$selection, action: /Action.web) { SantaWeb() } .ifLet(\\SelfLessonDetail.State.selection, action: /SelfLessonDetail.Action.webView) { From e0e17b607713c28ee8c9faed84ac2816010f1e56 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Mon, 29 Apr 2024 02:06:35 +0900 Subject: [PATCH 03/12] =?UTF-8?q?=E2=9C=85=20add=20test=20case=20for=20ext?= =?UTF-8?q?ensions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/Sources.swift | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Tests/TCADiagramLibTests/Resources/Sources.swift b/Tests/TCADiagramLibTests/Resources/Sources.swift index 85be16d..4807411 100644 --- a/Tests/TCADiagramLibTests/Resources/Sources.swift +++ b/Tests/TCADiagramLibTests/Resources/Sources.swift @@ -264,3 +264,55 @@ let reducerMacroSampleSource: [String] = [ } """ ] + +let reducerWithExtensionSampleSource: [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 + } + } + + .subFeatures1() + } + } + extension Reducer where State == SelfLessonDetail.State, Action == SelfLessonDetail.Action { + func subFeatures1() -> some ReducerOf { + .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() + } + } + } + } + """ +] From 7b4cd061fc2e1a9d7afc48fbb93614d16171d29f Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:52:19 +0900 Subject: [PATCH 04/12] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20update=20deprecated?= =?UTF-8?q?=20params=20and=20Types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Internal/Parser.swift | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Sources/TCADiagramLib/Internal/Parser.swift b/Sources/TCADiagramLib/Internal/Parser.swift index 5cbe4f1..77d0f3d 100644 --- a/Sources/TCADiagramLib/Internal/Parser.swift +++ b/Sources/TCADiagramLib/Internal/Parser.swift @@ -66,7 +66,6 @@ extension SourceFileSyntax { } extension SourceFileSyntax { - /// Get parent name from feature. private func predicateReducerProtocol(_ node: Syntax) throws -> String? { if @@ -74,14 +73,14 @@ extension SourceFileSyntax { { /// Has @Reducer macro if - node.attributes?.contains(where: { element in + 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 + debugPrint(node.name.text) + return node.name.text } /// superclass of ReducerProtocol or Reducer if @@ -91,7 +90,7 @@ extension SourceFileSyntax { || $0.tokenKind == .identifier("Reducer") }) == true { - return node.identifier.text + return node.name.text } } return nil @@ -101,7 +100,7 @@ extension SourceFileSyntax { private func predicateChildReducerProtocol(_ node: Syntax) throws -> ([String], Bool)? { if let node = FunctionCallExprSyntax(node), - node.argumentList.contains(where: { syntax in syntax.label?.text == "action" }) + node.arguments.contains(where: { syntax in syntax.label?.text == "action" }) { if node.tokens(viewMode: .fixedUp).contains(where: { $0.tokenKind == .identifier("Scope") }), @@ -140,7 +139,7 @@ extension SourceFileSyntax { private func predicatePullbackCall(_ node: Syntax) throws -> (FunctionCallExprSyntax, String, String)? { if let node = FunctionCallExprSyntax(node), - let action = node.argumentList.first(where: { syntax in syntax.label?.text == "action" })?.expression + let action = node.arguments.first(where: { syntax in syntax.label?.text == "action" })?.expression { let child = node.description.firstMatch(of: try Regex("\\s+(.+?)Reducer"))?[1].substring?.description let parent = "\(action)".firstMatch(of: try Regex("\\/(.+?)Action.+"))?[1].substring?.description @@ -173,13 +172,13 @@ extension SourceFileSyntax { /// parse `enum` Action for feature name. private func predicateActionDecl(_ node: Syntax) throws -> String? { if let node = EnumDeclSyntax(node) { - if node.identifier.text == "Action" { + if node.name.text == "Action" { var parent = node.parent while parent != nil { if let ext = ExtensionDeclSyntax(parent), let name = ext.children(viewMode: .fixedUp) - .compactMap(SimpleTypeIdentifierSyntax.init) + .compactMap(IdentifierTypeSyntax.init) .first? .name .text @@ -190,8 +189,8 @@ extension SourceFileSyntax { } } return .none - } else if node.identifier.text.hasSuffix("Action") { - return node.identifier.text.replacing("Action", with: "") + } else if node.name.text.hasSuffix("Action") { + return node.name.text.replacing("Action", with: "") } else { return .none } From 563c12e17e248f9adeac7eb084cfd2a52ce87585 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:53:22 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=92=A1=20translate=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Diagram.swift | 12 ++++++------ Sources/TCADiagramLib/Internal/StringProtocol.swift | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/TCADiagramLib/Diagram.swift b/Sources/TCADiagramLib/Diagram.swift index 8a739ca..5f37c81 100644 --- a/Sources/TCADiagramLib/Diagram.swift +++ b/Sources/TCADiagramLib/Diagram.swift @@ -6,10 +6,10 @@ import SwiftParser public enum Diagram { public static func dump(_ sources: [String]) throws -> String { var relations: [Relation] = [] // Parent ---> Child - var actions: Set = [] // 파일에 존재하는 모든 Action 이름 - var pullbackCount: [String: Int] = [:] // 액션이름: pullback count + var actions: Set = [] // All Action names in file + var pullbackCount: [String: Int] = [:] // [Action name: pullback count] - // 각 소스 파일을 순회하여 actions, relations를 채웁니다. + // go through all files and fill in actions and relations. try sources.enumerated().forEach { index, source in print("Parsing... (\(index + 1)/\(sources.count))") let root: SourceFileSyntax = Parser.parse(source: source) @@ -42,15 +42,15 @@ public enum Diagram { ) -> String { relations .sorted( - // parent 먼저 정렬 후 child를 정렬합니다. + // order parent first, then child. using: [ KeyPathComparator(\.parent, order: .forward), KeyPathComparator(\.child, order: .forward), ] ) .map { (relation: Relation) -> Relation in - // AITutor, aiTutor, AiTutor와 같은 문제를 해결하기 위해 - // 실제 정의된 Action 이름에서 같은 이름이 있다면 Action 이름으로 대체합니다. + // to fix case problems like AITutor, aiTutor, AiTutor, + // if there is defined Action, use that name. if let action = actions.first(where: { action in action.lowercased() == relation.child.lowercased() }) { pullbackCount[action] = (pullbackCount[action] ?? 0) + 1 return Relation( diff --git a/Sources/TCADiagramLib/Internal/StringProtocol.swift b/Sources/TCADiagramLib/Internal/StringProtocol.swift index 508f421..05b3266 100644 --- a/Sources/TCADiagramLib/Internal/StringProtocol.swift +++ b/Sources/TCADiagramLib/Internal/StringProtocol.swift @@ -1,10 +1,10 @@ extension StringProtocol { - /// 제일 처음 문자를 대문자로 변경합니다. + /// uppercase first letter var firstUppercased: String { prefix(1).uppercased() + dropFirst() } - /// 문자열 앞에 4개의 공백을 추가합니다. + /// add 4 space indent as prefix var indent: String { " \(self)" } From a0a50669872c60512927c4d6140da0aa6bb881a0 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:54:21 +0900 Subject: [PATCH 06/12] =?UTF-8?q?=F0=9F=A7=AA=20add=20failing=20test=20hav?= =?UTF-8?q?ing=20iflet=20inside=20extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/DiagramTests.swift | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Tests/TCADiagramLibTests/DiagramTests.swift b/Tests/TCADiagramLibTests/DiagramTests.swift index e9d27db..4f75138 100644 --- a/Tests/TCADiagramLibTests/DiagramTests.swift +++ b/Tests/TCADiagramLibTests/DiagramTests.swift @@ -89,4 +89,26 @@ final class DiagramTests: XCTestCase { """ XCTAssertEqual(result, expected) } + + func testreducerWithExtensionSampleSource() throws { + let result = try Diagram.dump(reducerWithExtensionSampleSource) + 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) + } } From 406ddbc375469bc3025357104e967d6fd5ef08c7 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:57:04 +0900 Subject: [PATCH 07/12] =?UTF-8?q?=F0=9F=91=94=20chain=20ifLet=20declaratio?= =?UTF-8?q?n=20to=20provided=20reducer=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Diagram.swift | 3 +- Sources/TCADiagramLib/Internal/Parser.swift | 106 ++++++++++++++------ 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/Sources/TCADiagramLib/Diagram.swift b/Sources/TCADiagramLib/Diagram.swift index 5f37c81..ba51388 100644 --- a/Sources/TCADiagramLib/Diagram.swift +++ b/Sources/TCADiagramLib/Diagram.swift @@ -13,7 +13,8 @@ public enum Diagram { try sources.enumerated().forEach { index, source in print("Parsing... (\(index + 1)/\(sources.count))") let root: SourceFileSyntax = Parser.parse(source: source) - try root.travel(node: Syntax(root), actions: &actions, relations: &relations) + let reducer = root.description.firstMatch(of: try Regex("Reducer\n.*struct (.*) {"))?[1].substring?.description ?? "" + try root.travel(reducer: reducer, node: Syntax(root), actions: &actions, relations: &relations) } return Array diff --git a/Sources/TCADiagramLib/Internal/Parser.swift b/Sources/TCADiagramLib/Internal/Parser.swift index 77d0f3d..4983cdb 100644 --- a/Sources/TCADiagramLib/Internal/Parser.swift +++ b/Sources/TCADiagramLib/Internal/Parser.swift @@ -2,11 +2,11 @@ import SwiftSyntax extension SourceFileSyntax { func travel( + reducer: String = "", node: Syntax, actions: inout Set, relations: inout [Relation] ) throws { - if let reducerProtocolParent = try predicateReducerProtocol(node) { try travel(parent: reducerProtocolParent, node: node, actions: &actions, relations: &relations) } @@ -22,12 +22,23 @@ extension SourceFileSyntax { } else if let name = try predicateActionDecl(node) { actions.insert(name) } else { - for child in node.children(viewMode: .all) { - try travel( - node: child, - actions: &actions, - relations: &relations - ) + if reducer.isEmpty { + for child in node.children(viewMode: .all) { + try travel( + node: child, + actions: &actions, + relations: &relations + ) + } + } else { + for child in node.children(viewMode: .all) { + try travel( + parent: reducer, + node: child, + actions: &actions, + relations: &relations + ) + } } } } @@ -42,7 +53,17 @@ extension SourceFileSyntax { actions: inout Set, relations: inout [Relation] ) throws { - if let (children, isOptional) = try predicateChildReducerProtocol(node) { + if let children = try predicateIfLetDecl(node) { + children.forEach { child in + relations.append( + .init( + parent: parent, + child: child.firstUppercased, + optional: true + ) + ) + } + } else if let (children, isOptional) = try predicateChildReducerProtocol(node) { children.forEach { child in relations.append( .init( @@ -141,29 +162,29 @@ extension SourceFileSyntax { let node = FunctionCallExprSyntax(node), let action = node.arguments.first(where: { syntax in syntax.label?.text == "action" })?.expression { - let child = node.description.firstMatch(of: try Regex("\\s+(.+?)Reducer"))?[1].substring?.description - let parent = "\(action)".firstMatch(of: try Regex("\\/(.+?)Action.+"))?[1].substring?.description - switch (child, parent) { - case (.some("Any"), .some(let parent)): - if - let child = node.description - .firstMatch(of: try Regex("(?s)\\s+AnyReducer.*\\{.+?\\s+(\\w+?)\\("))?[1] - .substring? - .description, - node.tokens(viewMode: .fixedUp).map(\.text).contains("pullback") - { - return (node, parent, child) - } - return .none + if + let child = node.description.firstMatch(of: try Regex("\\s+(.+?)Reducer"))?[1].substring?.description, + let parent = "\(action)".firstMatch(of: try Regex("\\/(.+?)Action.+"))?[1].substring?.description + { + switch (child, parent) { + case ("Any", let parent): + if + let child = node.description + .firstMatch(of: try Regex("(?s)\\s+AnyReducer.*\\{.+?\\s+(\\w+?)\\("))?[1] + .substring? + .description, + node.tokens(viewMode: .fixedUp).map(\.text).contains("pullback") + { + return (node, parent, child) + } + return .none - case (.some(let child), .some(let parent)): - if node.tokens(viewMode: .fixedUp).map(\.text).contains("pullback") { - return (node, parent, child) + case (let child, let parent): + if node.tokens(viewMode: .fixedUp).map(\.text).contains("pullback") { + return (node, parent, child) + } + return .none } - return .none - - default: - return .none } } return .none @@ -213,4 +234,31 @@ extension SourceFileSyntax { } return false } + + /// parse `enum` Action for feature name. + private func predicateIfLetDecl(_ node: Syntax) throws -> [String]? { + // let parent = "\(action)".firstMatch(of: try Regex("\\/(.+?)Action.+"))?[1].substring?.description { + if + let node = FunctionCallExprSyntax(node), + node.arguments.contains(where: { syntax in syntax.label?.text == "action" }) + { + + // 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 children = node.description + .matches(of: try Regex("ifLet.+{\\s+(.+?)\\(\\)")) + .compactMap { + $0[1].substring?.description + } + .filter { + $0 != "EmptyReducer" + } + return children + } + } + return .none + } } From e0892207a69e93b34403f4ee5179647815628a8a Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:59:38 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=E2=9C=85=20add=20test=20for=20action=20k?= =?UTF-8?q?eyPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/Resources/Sources.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/TCADiagramLibTests/Resources/Sources.swift b/Tests/TCADiagramLibTests/Resources/Sources.swift index 4807411..2347677 100644 --- a/Tests/TCADiagramLibTests/Resources/Sources.swift +++ b/Tests/TCADiagramLibTests/Resources/Sources.swift @@ -169,7 +169,7 @@ let reducerSampleSource: [String] = [ .ifLet(\\.filter, action: /Action.filter) { SelfLessonDetailFilter() } - .ifLet(\\.$selection, action: /Action.web) { + .ifLet(\\.$selection, action: \\.web) { SantaWeb() } .ifLet(\\SelfLessonDetail.State.selection, action: /SelfLessonDetail.Action.webView) { From 92bfefa1b2ad0b4b9ac4ddeab733e5364f152e14 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 07:59:52 +0900 Subject: [PATCH 09/12] =?UTF-8?q?=F0=9F=93=9D=20update=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index ebf4fd7..7a9cc34 100644 --- a/readme.md +++ b/readme.md @@ -65,9 +65,9 @@ OPTIONS: VERSION= make release ``` -## Limits +## Todos - [x] ~~Scopes~~ - [x] ~~optionals~~ - [x] ~~ifLet~~ -- [ ] functions inside `extension Reducer {...}` isn't parsed. -- [ ] case paths like `.ifLet(\.$destination, action: \.destination) {` +- [x] functions inside `extension Reducer {...}` isn't parsed. +- [x] case paths like `.ifLet(\.$destination, action: \.destination) {` From 9d5f64c2caf0dcbdda603b9a442fb3e0b8fc5f07 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 08:58:58 +0900 Subject: [PATCH 10/12] =?UTF-8?q?=F0=9F=91=94=20also=20parse=20older=20ver?= =?UTF-8?q?sion=20of=20Reducer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Diagram.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/TCADiagramLib/Diagram.swift b/Sources/TCADiagramLib/Diagram.swift index ba51388..71bc1dc 100644 --- a/Sources/TCADiagramLib/Diagram.swift +++ b/Sources/TCADiagramLib/Diagram.swift @@ -13,7 +13,12 @@ public enum Diagram { try sources.enumerated().forEach { index, source in print("Parsing... (\(index + 1)/\(sources.count))") let root: SourceFileSyntax = Parser.parse(source: source) - let reducer = root.description.firstMatch(of: try Regex("Reducer\n.*struct (.*) {"))?[1].substring?.description ?? "" + var reducer = root.description.firstMatch(of: try Regex("Reducer\n.*struct (.*) {"))?[1].substring? + .description ?? "" + if reducer == "" { + reducer = root.description.firstMatch(of: try Regex("\\s+struct (.+?): Reducer"))?[1].substring? + .description ?? "" + } try root.travel(reducer: reducer, node: Syntax(root), actions: &actions, relations: &relations) } From d4257708469536163359d729496776078ea2bd31 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 09:02:09 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=E2=9C=85=20test=20reducer=20implementati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/TCADiagramLibTests/Resources/Sources.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/TCADiagramLibTests/Resources/Sources.swift b/Tests/TCADiagramLibTests/Resources/Sources.swift index 2347677..136acbc 100644 --- a/Tests/TCADiagramLibTests/Resources/Sources.swift +++ b/Tests/TCADiagramLibTests/Resources/Sources.swift @@ -267,8 +267,7 @@ let reducerMacroSampleSource: [String] = [ let reducerWithExtensionSampleSource: [String] = [ """ - @Reducer - public struct SelfLessonDetail { + public struct SelfLessonDetail: Reducer { @Dependency(\\.environmentSelfLessonDetail) private var environment public init() {} From 1cc7262230ca025a4f685394162a11594fea2021 Mon Sep 17 00:00:00 2001 From: Minho Yi Date: Wed, 1 May 2024 09:02:21 +0900 Subject: [PATCH 12/12] =?UTF-8?q?=F0=9F=9A=A8=20run=20lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/TCADiagramLib/Diagram.swift | 31 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Sources/TCADiagramLib/Diagram.swift b/Sources/TCADiagramLib/Diagram.swift index 71bc1dc..c6edb51 100644 --- a/Sources/TCADiagramLib/Diagram.swift +++ b/Sources/TCADiagramLib/Diagram.swift @@ -1,12 +1,12 @@ import Foundation -import SwiftSyntax import SwiftParser +import SwiftSyntax public enum Diagram { public static func dump(_ sources: [String]) throws -> String { - var relations: [Relation] = [] // Parent ---> Child - var actions: Set = [] // All Action names in file + var relations: [Relation] = [] // Parent ---> Child + var actions: Set = [] // All Action names in file var pullbackCount: [String: Int] = [:] // [Action name: pullback count] // go through all files and fill in actions and relations. @@ -22,18 +22,17 @@ public enum Diagram { try root.travel(reducer: reducer, node: Syntax(root), actions: &actions, relations: &relations) } - return Array - .init( - [ - "```mermaid", - Self.mermaidHeader, - Self.relationSection(relations: relations, actions: actions, pullbackCount: &pullbackCount), - "", - Self.idSection(pullbackCount: pullbackCount), - "```" - ] - ) - .joined(separator: "\n") + return Array( + [ + "```mermaid", + Self.mermaidHeader, + Self.relationSection(relations: relations, actions: actions, pullbackCount: &pullbackCount), + "", + Self.idSection(pullbackCount: pullbackCount), + "```" + ] + ) + .joined(separator: "\n") } private static let mermaidHeader = """ @@ -81,7 +80,7 @@ public enum Diagram { ) -> String { pullbackCount .sorted(by: { $0.0 < $1.0 }) - .map { (key, value) in "\(key)(\(key): \(value))".indent } + .map { key, value in "\(key)(\(key): \(value))".indent } .joined(separator: "\n") } }