From db3350361322b72ba6e63cb557fb5d5ff6475ca4 Mon Sep 17 00:00:00 2001 From: Serhii Shevchenko Date: Thu, 27 Nov 2025 21:34:51 +0700 Subject: [PATCH 1/5] Update `swift-syntax` version and improve type constraints - [x] Bumped `swift-syntax` dependency to allow up to `603.0.0`. - [x] Added `SendableMetatype` constraint to `NumberCodingStrategy` extension. - [x] Refactored `caseEncodeExpr` in `EnumVariable` for consistent `FunctionCallExprSyntax` usage. --- Package.swift | 2 +- Sources/HelperCoders/ValueCoders/Number.swift | 2 +- .../Variables/Type/EnumVariable.swift | 22 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Package.swift b/Package.swift index b7352bd3c..76c25ad60 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ let package = Package( .plugin(name: "MetaProtocolCodable", targets: ["MetaProtocolCodable"]), ], dependencies: [ - .package(url: "https://github.com/swiftlang/swift-syntax.git", "509.1.0"..<"602.0.0"), + .package(url: "https://github.com/swiftlang/swift-syntax.git", "509.1.0"..<"603.0.0"), .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.4"), .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2"), .package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.0.0"), diff --git a/Sources/HelperCoders/ValueCoders/Number.swift b/Sources/HelperCoders/ValueCoders/Number.swift index 24a01c75e..403642fb4 100644 --- a/Sources/HelperCoders/ValueCoders/Number.swift +++ b/Sources/HelperCoders/ValueCoders/Number.swift @@ -3,7 +3,7 @@ protocol NumberCodingStrategy: ValueCodingStrategy where Value == Self {} public extension ValueCodingStrategy -where Value: Decodable & ExpressibleByIntegerLiteral & LosslessStringConvertible +where Value: Decodable & ExpressibleByIntegerLiteral & LosslessStringConvertible & SendableMetatype { /// Decodes numeric data from the given `decoder`. /// diff --git a/Sources/PluginCore/Variables/Type/EnumVariable.swift b/Sources/PluginCore/Variables/Type/EnumVariable.swift index 3c621b995..bb5e36479 100644 --- a/Sources/PluginCore/Variables/Type/EnumVariable.swift +++ b/Sources/PluginCore/Variables/Type/EnumVariable.swift @@ -81,17 +81,17 @@ package struct EnumVariable: TypeVariable, DeclaredVariable { "self = .\(name)" } } - let caseEncodeExpr: CaseCode = { name, variables in - let args = Self.encodingArgs(representing: variables) - let callee: ExprSyntax = ".\(name)" - let fExpr = - if !args.isEmpty { - FunctionCallExprSyntax(callee: callee) { args } - } else { - FunctionCallExprSyntax(calledExpression: callee) {} - } - return ExprSyntax(fExpr) - } + let caseEncodeExpr: CaseCode = { name, variables in + let args = Self.encodingArgs(representing: variables) + let callee: ExprSyntax = ".\(name)" + let fExpr = + if !args.isEmpty { + FunctionCallExprSyntax(calledExpression: callee) { args } + } else { + FunctionCallExprSyntax(calledExpression: callee) {} + } + return ExprSyntax(fExpr) + } self.init( from: decl, in: context, caseDecodeExpr: caseDecodeExpr, caseEncodeExpr: caseEncodeExpr, From a9b3f019b18a8a8c930e5198efc54a1c7a2ec070 Mon Sep 17 00:00:00 2001 From: Serhii Shevchenko Date: Thu, 27 Nov 2025 21:39:34 +0700 Subject: [PATCH 2/5] Bring indentation back in `EnumVariable.swift` - [x] Corrected indentation for the `caseEncodeExpr` closure to maintain consistent formatting. --- .../Variables/Type/EnumVariable.swift | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Sources/PluginCore/Variables/Type/EnumVariable.swift b/Sources/PluginCore/Variables/Type/EnumVariable.swift index bb5e36479..4c716693f 100644 --- a/Sources/PluginCore/Variables/Type/EnumVariable.swift +++ b/Sources/PluginCore/Variables/Type/EnumVariable.swift @@ -81,17 +81,17 @@ package struct EnumVariable: TypeVariable, DeclaredVariable { "self = .\(name)" } } - let caseEncodeExpr: CaseCode = { name, variables in - let args = Self.encodingArgs(representing: variables) - let callee: ExprSyntax = ".\(name)" - let fExpr = - if !args.isEmpty { - FunctionCallExprSyntax(calledExpression: callee) { args } - } else { - FunctionCallExprSyntax(calledExpression: callee) {} - } - return ExprSyntax(fExpr) - } + let caseEncodeExpr: CaseCode = { name, variables in + let args = Self.encodingArgs(representing: variables) + let callee: ExprSyntax = ".\(name)" + let fExpr = + if !args.isEmpty { + FunctionCallExprSyntax(calledExpression: callee) { args } + } else { + FunctionCallExprSyntax(calledExpression: callee) {} + } + return ExprSyntax(fExpr) + } self.init( from: decl, in: context, caseDecodeExpr: caseDecodeExpr, caseEncodeExpr: caseEncodeExpr, From 551c9a1094a127676e1bf604d60b8a6b037c8ba2 Mon Sep 17 00:00:00 2001 From: Serhii Shevchenko Date: Thu, 27 Nov 2025 22:30:22 +0700 Subject: [PATCH 3/5] Update protocol constraint from `SendableMetatype` to `Sendable` Replaces the `SendableMetatype` constraint with `Sendable` in the `ValueCodingStrategy` extension to align with updated protocol requirements or type definitions. --- Sources/HelperCoders/ValueCoders/Number.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/HelperCoders/ValueCoders/Number.swift b/Sources/HelperCoders/ValueCoders/Number.swift index 403642fb4..60bcc5df0 100644 --- a/Sources/HelperCoders/ValueCoders/Number.swift +++ b/Sources/HelperCoders/ValueCoders/Number.swift @@ -3,7 +3,7 @@ protocol NumberCodingStrategy: ValueCodingStrategy where Value == Self {} public extension ValueCodingStrategy -where Value: Decodable & ExpressibleByIntegerLiteral & LosslessStringConvertible & SendableMetatype +where Value: Decodable & ExpressibleByIntegerLiteral & LosslessStringConvertible & Sendable { /// Decodes numeric data from the given `decoder`. /// From af382dff2664362161bb48263091664e2f690119 Mon Sep 17 00:00:00 2001 From: Serhii Shevchenko Date: Thu, 27 Nov 2025 22:31:24 +0700 Subject: [PATCH 4/5] Fix enum case encoding for cases without arguments - [x] Refactors `caseEncodeExpr` to return only the case name for enum cases without associated values, avoiding unnecessary parentheses. This improves code generation for enums with simple cases. --- .../Variables/Type/EnumVariable.swift | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Sources/PluginCore/Variables/Type/EnumVariable.swift b/Sources/PluginCore/Variables/Type/EnumVariable.swift index 4c716693f..3914db302 100644 --- a/Sources/PluginCore/Variables/Type/EnumVariable.swift +++ b/Sources/PluginCore/Variables/Type/EnumVariable.swift @@ -84,13 +84,19 @@ package struct EnumVariable: TypeVariable, DeclaredVariable { let caseEncodeExpr: CaseCode = { name, variables in let args = Self.encodingArgs(representing: variables) let callee: ExprSyntax = ".\(name)" - let fExpr = - if !args.isEmpty { - FunctionCallExprSyntax(calledExpression: callee) { args } - } else { - FunctionCallExprSyntax(calledExpression: callee) {} - } - return ExprSyntax(fExpr) + if args.isEmpty { + /// No associated values: return just the case name without parentheses + return callee + } else { + let fExpr = FunctionCallExprSyntax( + calledExpression: callee, + leftParen: .leftParenToken(), + arguments: args, + rightParen: .rightParenToken(), + trailingClosure: nil + ) + return ExprSyntax(fExpr) + } } self.init( from: decl, in: context, @@ -878,3 +884,4 @@ fileprivate extension EnumVariable { /// This encoder is passed to each case for encoding. static var contentEncoder: TokenSyntax { "contentEncoder" } } + From 44558a51537794a3eb59639048f2073aaed4c7e5 Mon Sep 17 00:00:00 2001 From: Serhii Shevchenko Date: Thu, 27 Nov 2025 22:36:59 +0700 Subject: [PATCH 5/5] Align `misuseWithCodable` diagnostics with actual macro output - [x] Update `ConformEncodableTests.misuseWithCodable` to expect four diagnostics. - [x] Ensure diagnostic IDs, messages, fix-its, and line/column positions match emitted results: - [x] Two diagnostics for `@ConformEncodable` at line 1, column 1. - [x] Two diagnostics for `@Codable` at line 2, column 1. - [x] Mirrors the pattern already used in `misuseWithDecodable`. --- Tests/MetaCodableTests/ConformCodableTests.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Tests/MetaCodableTests/ConformCodableTests.swift b/Tests/MetaCodableTests/ConformCodableTests.swift index 6a8a793ce..3f294cd03 100644 --- a/Tests/MetaCodableTests/ConformCodableTests.swift +++ b/Tests/MetaCodableTests/ConformCodableTests.swift @@ -38,6 +38,15 @@ struct ConformEncodableTests { .init(message: "Remove @ConformEncodable attribute") ] ), + .init( + id: Codable.misuseID, + message: + "@Codable can't be used in combination with @ConformEncodable", + line: 2, column: 1, + fixIts: [ + .init(message: "Remove @Codable attribute") + ] + ), .init( id: ConformEncodable.misuseID, message: @@ -491,3 +500,4 @@ struct ConformDecodableTests { } } } +