From b6b16774cacdf4f343f73917de97ee2de6dc96d0 Mon Sep 17 00:00:00 2001 From: mlch911 Date: Fri, 27 Dec 2024 17:06:45 +0800 Subject: [PATCH 1/5] Fix Build --- DictionaryStorage.podspec | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/DictionaryStorage.podspec b/DictionaryStorage.podspec index 246606d..02e4a5a 100644 --- a/DictionaryStorage.podspec +++ b/DictionaryStorage.podspec @@ -19,7 +19,28 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/naan/DictionaryStorage.git", :tag => "#{s.version}" } - s.prepare_command = 'swift build -c release && cp -f .build/release/DictionaryStorageMacros ./Binary' + s.prepare_command = <<-CMD + set -e + swift build -c release + if [ $? -ne 0 ]; then + echo "Error: Failed to build DictionaryStorage" + exit 1 + fi + + if [ -f ".build/release/DictionaryStorageMacros-tool" ]; then + cp -f .build/release/DictionaryStorageMacros-tool ./Binary/DictionaryStorageMacros + elif [ -f ".build/release/DictionaryStorageMacros" ]; then + cp -f .build/release/DictionaryStorageMacros ./Binary/DictionaryStorageMacros + else + echo "Error: Neither DictionaryStorageMacros-tool nor DictionaryStorageMacros found in .build/release" + exit 1 + fi + + if [ $? -ne 0 ]; then + echo "Error: Failed to copy DictionaryStorageMacros to Binary directory" + exit 1 + fi + CMD s.source_files = "Sources/DictionaryStorage/*.swift" s.swift_versions = "5.9" From 710c9a7fc58fdcce47b66c74263fb1bdc9b37dba Mon Sep 17 00:00:00 2001 From: mlch911 Date: Tue, 7 Jan 2025 15:31:38 +0800 Subject: [PATCH 2/5] Fix StringRepresentation: default should at the end of switch --- .../StringRepresentationMacro.swift | 19 +++++++------ .../StringRepresentationMacroTests.swift | 28 ++++++++++++------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift index fc12837..c34f687 100644 --- a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift +++ b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift @@ -60,7 +60,7 @@ extension StringRepresentationMacro: MemberMacro { let initializer = try InitializerDeclSyntax("\(modifier) init?(rawValue: String)") { try SwitchExprSyntax("switch rawValue") { - var hasDefault = false + var defaultValue: TokenSyntax? for caseDecl in cases { let customName = customName(for: caseDecl) let customPrefix = customPrefix(for: caseDecl) @@ -83,17 +83,18 @@ extension StringRepresentationMacro: MemberMacro { """ ) } else { - let _ = (hasDefault = true) - SwitchCaseSyntax( - """ - default: - self = .\(name)(rawValue) - """ - ) + let _ = (defaultValue = name) } } } - if !hasDefault { + if let name = defaultValue { + SwitchCaseSyntax( + """ + default: + self = .\(name)(rawValue) + """ + ) + } else { SwitchCaseSyntax( """ default: diff --git a/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift b/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift index 4b56624..a38281c 100644 --- a/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift +++ b/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift @@ -263,32 +263,40 @@ final class StringRepresentationMacroTests: XCTestCase { """ @StringRawRepresentation public enum Visa { - case hello, world + case hello_world + case hello_world_2 case custom(String) + case hello_world_3 } """, expandedSource: """ public enum Visa { - case hello, world + case hello_world + case hello_world_2 case custom(String) + case hello_world_3 public var rawValue: String { switch self { - case .hello: - return "hello" - case .world: - return "world" + case .hello_world: + return "hello_world" + case .hello_world_2: + return "hello_world_2" case .custom(let value): return value + case .hello_world_3: + return "hello_world_3" } } public init?(rawValue: String) { switch rawValue { - case "hello": - self = .hello - case "world": - self = .world + case "hello_world": + self = .hello_world + case "hello_world_2": + self = .hello_world_2 + case "hello_world_3": + self = .hello_world_3 default: self = .custom(rawValue) } From f67c3b40a155eeeb238907882ecd659803b2bd2d Mon Sep 17 00:00:00 2001 From: mlch911 Date: Thu, 13 Mar 2025 15:14:19 +0800 Subject: [PATCH 3/5] Add noInit & pureName --- .../DictionaryStorage/DictionaryStorage.swift | 2 +- .../StringRepresentationMacro.swift | 100 +++++++++++------- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/Sources/DictionaryStorage/DictionaryStorage.swift b/Sources/DictionaryStorage/DictionaryStorage.swift index 4217404..442dceb 100644 --- a/Sources/DictionaryStorage/DictionaryStorage.swift +++ b/Sources/DictionaryStorage/DictionaryStorage.swift @@ -60,7 +60,7 @@ public macro DictionaryStorageProperty(_ key: String) = /// Automating RawRepresentable Conformance or enum with string. @attached(member, names: named(rawValue), named(init)) @attached(extension, conformances: RawRepresentable, Equatable) -public macro StringRawRepresentation() = +public macro StringRawRepresentation(noInit: Bool = false, pureName: Bool = false) = #externalMacro(module: "DictionaryStorageMacros", type: "StringRepresentationMacro") /// Customize name of the key for @StringRawRepresentation. diff --git a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift index c34f687..40dbb42 100644 --- a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift +++ b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift @@ -32,7 +32,12 @@ extension StringRepresentationMacro: ExtensionMacro { """ guard let rawRepresentable = rawRepresentableExtension.as(ExtensionDeclSyntax.self) else { return [] } guard let equtable = equatableExtension.as(ExtensionDeclSyntax.self) else { return [] } - + + let noInit = node.getInputParameter("noInit")?.as(BooleanLiteralExprSyntax.self)?.literal.tokenKind == .keyword(.true) + + if noInit { + return [equtable] + } return [rawRepresentable, equtable] } } @@ -58,6 +63,51 @@ extension StringRepresentationMacro: MemberMacro { let modifier: TokenSyntax = declaration.modifiers.isPublic ? "public" : "" + let noInit = node.getInputParameter("noInit")?.as(BooleanLiteralExprSyntax.self)?.literal.tokenKind == .keyword(.true) + let pureName = node.getInputParameter("pureName")?.as(BooleanLiteralExprSyntax.self)?.literal.tokenKind == .keyword(.true) + + let variable = try VariableDeclSyntax("\(modifier) var rawValue: String") { + try SwitchExprSyntax("switch self") { + for caseDecl in cases { + let customName = customName(for: caseDecl) + let customPrefix = customPrefix(for: caseDecl) + for element in caseDecl.elements { + + let value = customName ?? element.name.trimmed + + if element.parameterClause == nil || pureName { + SwitchCaseSyntax( + """ + case .\(element.name.trimmed): + return "\(value)" + """ + ) + } else if let customPrefix { + SwitchCaseSyntax( + """ + case .\(element.name.trimmed)(let value): + return "\(customPrefix)" + value + """ + ) + } else { + SwitchCaseSyntax( + """ + case .\(element.name.trimmed)(let value): + return value + """ + ) + } + } + } + } + } + + if noInit { + return [ + DeclSyntax(variable) + ] + } + let initializer = try InitializerDeclSyntax("\(modifier) init?(rawValue: String)") { try SwitchExprSyntax("switch rawValue") { var defaultValue: TokenSyntax? @@ -105,42 +155,6 @@ extension StringRepresentationMacro: MemberMacro { } } - let variable = try VariableDeclSyntax("\(modifier) var rawValue: String") { - try SwitchExprSyntax("switch self") { - for caseDecl in cases { - let customName = customName(for: caseDecl) - let customPrefix = customPrefix(for: caseDecl) - for element in caseDecl.elements { - - let value = customName ?? element.name.trimmed - - if element.parameterClause == nil { - SwitchCaseSyntax( - """ - case .\(element.name.trimmed): - return "\(value)" - """ - ) - } else if let customPrefix { - SwitchCaseSyntax( - """ - case .\(element.name.trimmed)(let value): - return "\(customPrefix)" + value - """ - ) - } else { - SwitchCaseSyntax( - """ - case .\(element.name.trimmed)(let value): - return value - """ - ) - } - } - } - } - } - return [ DeclSyntax(variable), DeclSyntax(initializer) @@ -172,3 +186,15 @@ extension StringRepresentationMacro { return true } } + +extension AttributeSyntax { + /// 获取宏的参数 + func getInputParameter(_ name: String) -> ExprSyntax? { + if case let .argumentList(arguments) = arguments, + let element = arguments.first(where: { $0.label?.text == name }) + { + return element.expression + } + return nil + } +} From 026230c4684eda6b33d2f32a7c3bca8d2eaac2ff Mon Sep 17 00:00:00 2001 From: mlch911 Date: Fri, 19 Dec 2025 12:33:25 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0stringValue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DictionaryStorage/DictionaryStorage.swift | 2 +- .../StringRepresentationMacro.swift | 13 ++++++---- .../StringRepresentationMacroTests.swift | 24 +++++++++++++++++++ .../StringRepresentationTests.swift | 11 +++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/Sources/DictionaryStorage/DictionaryStorage.swift b/Sources/DictionaryStorage/DictionaryStorage.swift index 442dceb..41e3515 100644 --- a/Sources/DictionaryStorage/DictionaryStorage.swift +++ b/Sources/DictionaryStorage/DictionaryStorage.swift @@ -58,7 +58,7 @@ public macro DictionaryStorageProperty(_ key: String) = // MARK: - RawRepresentable /// Automating RawRepresentable Conformance or enum with string. -@attached(member, names: named(rawValue), named(init)) +@attached(member, names: named(rawValue), named(init), named(stringValue)) @attached(extension, conformances: RawRepresentable, Equatable) public macro StringRawRepresentation(noInit: Bool = false, pureName: Bool = false) = #externalMacro(module: "DictionaryStorageMacros", type: "StringRepresentationMacro") diff --git a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift index 40dbb42..e3e9a02 100644 --- a/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift +++ b/Sources/DictionaryStorageMacros/StringRepresentationMacro.swift @@ -65,8 +65,11 @@ extension StringRepresentationMacro: MemberMacro { let noInit = node.getInputParameter("noInit")?.as(BooleanLiteralExprSyntax.self)?.literal.tokenKind == .keyword(.true) let pureName = node.getInputParameter("pureName")?.as(BooleanLiteralExprSyntax.self)?.literal.tokenKind == .keyword(.true) - - let variable = try VariableDeclSyntax("\(modifier) var rawValue: String") { + + let rawValueVariable = try VariableDeclSyntax("\(modifier) var rawValue: String") { + "stringValue" + } + let stringValueVariable = try VariableDeclSyntax("\(modifier) var stringValue: String") { try SwitchExprSyntax("switch self") { for caseDecl in cases { let customName = customName(for: caseDecl) @@ -104,7 +107,8 @@ extension StringRepresentationMacro: MemberMacro { if noInit { return [ - DeclSyntax(variable) + DeclSyntax(rawValueVariable), + DeclSyntax(stringValueVariable) ] } @@ -156,7 +160,8 @@ extension StringRepresentationMacro: MemberMacro { } return [ - DeclSyntax(variable), + DeclSyntax(rawValueVariable), + DeclSyntax(stringValueVariable), DeclSyntax(initializer) ] } diff --git a/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift b/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift index a38281c..996d59c 100644 --- a/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift +++ b/Tests/DictionaryStorageMacrosTests/StringRepresentationMacroTests.swift @@ -38,6 +38,10 @@ final class StringRepresentationMacroTests: XCTestCase { case other(String) var rawValue: String { + stringValue + } + + var stringValue: String { switch self { case .tourist: return "tourist" @@ -94,6 +98,10 @@ final class StringRepresentationMacroTests: XCTestCase { case other(String) var rawValue: String { + stringValue + } + + var stringValue: String { switch self { case .text: return "text" @@ -189,6 +197,10 @@ final class StringRepresentationMacroTests: XCTestCase { case world(String) public var rawValue: String { + stringValue + } + + public var stringValue: String { switch self { case .hello: return "hello" @@ -231,6 +243,10 @@ final class StringRepresentationMacroTests: XCTestCase { case hello public var rawValue: String { + stringValue + } + + public var stringValue: String { switch self { case .hello: return "hello" @@ -277,6 +293,10 @@ final class StringRepresentationMacroTests: XCTestCase { case hello_world_3 public var rawValue: String { + stringValue + } + + public var stringValue: String { switch self { case .hello_world: return "hello_world" @@ -333,6 +353,10 @@ final class StringRepresentationMacroTests: XCTestCase { case custom(String) public var rawValue: String { + stringValue + } + + public var stringValue: String { switch self { case .hello: return "hello" diff --git a/Tests/DictionaryStorageTests/StringRepresentationTests.swift b/Tests/DictionaryStorageTests/StringRepresentationTests.swift index 93b33c0..ccd8935 100644 --- a/Tests/DictionaryStorageTests/StringRepresentationTests.swift +++ b/Tests/DictionaryStorageTests/StringRepresentationTests.swift @@ -24,5 +24,16 @@ final class StringRepresentationTests: XCTestCase { XCTAssertEqual(InputType(rawValue: "select-one"), .option) XCTAssertEqual(InputType(rawValue: "password"), .password) + XCTAssertEqual(InputType.email.rawValue, "email") + XCTAssertEqual(InputType.text.rawValue, "text") + XCTAssertEqual(InputType.unknown("custom").rawValue, "custom") + XCTAssertEqual(InputType.option.rawValue, "select-one") + XCTAssertEqual(InputType.password.rawValue, "password") + + XCTAssertEqual(InputType.email.stringValue, "email") + XCTAssertEqual(InputType.text.stringValue, "text") + XCTAssertEqual(InputType.unknown("custom").stringValue, "custom") + XCTAssertEqual(InputType.option.stringValue, "select-one") + XCTAssertEqual(InputType.password.stringValue, "password") } } From 788f80ed0221ba2f1a264639440e52a7f80fdf8e Mon Sep 17 00:00:00 2001 From: mlch911 Date: Tue, 25 Aug 2026 23:09:20 +0800 Subject: [PATCH 5/5] build: align SwiftSyntax with macro packages --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index a3c3aa9..04fd2e7 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"), + .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.0"), .package(url: "https://github.com/pointfreeco/swift-macro-testing.git", from: "0.3.0") ], targets: [