From 8bdb10007aae405e9bdbf53dcb9aa1e08afc0249 Mon Sep 17 00:00:00 2001 From: MahdiBM Date: Sat, 20 Jul 2024 13:01:52 +0330 Subject: [PATCH] more diagnostics --- Package.resolved | 6 ++-- Package.swift | 2 +- Sources/EnumeratorMacroImpl/MacroError.swift | 5 +++ .../EnumeratorMacroImpl/Types/EArray.swift | 16 +++++---- .../EnumeratorMacroImpl/Types/EComments.swift | 11 +++--- .../Types/EOptionalsArray.swift | 15 +++++--- .../EnumeratorMacroTests.swift | 35 +++++++++++++++++++ 7 files changed, 71 insertions(+), 19 deletions(-) diff --git a/Package.resolved b/Package.resolved index ce231a6..f346b2c 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "5fb3f3f652f6046ecafacd4cf94fd7cbc6347977cdfde61d767ba9728638b23b", + "originHash" : "471e59eb3ce1f697200ce8e807d75c97a2b2065d8033fd5c430fc887e3c33f05", "pins" : [ { "identity" : "swift-mustache", "kind" : "remoteSourceControl", "location" : "https://github.com/hummingbird-project/swift-mustache", "state" : { - "revision" : "5bb66ac425ec25fd45e0cd7d3829d73e45096352", - "version" : "2.0.0-beta.2" + "revision" : "cde358e364ab26f2b72a5f70613cfb0a574de6c9", + "version" : "2.0.0-beta.3" } }, { diff --git a/Package.swift b/Package.swift index f09a83f..375e040 100644 --- a/Package.swift +++ b/Package.swift @@ -25,7 +25,7 @@ let package = Package( ), .package( url: "https://github.com/hummingbird-project/swift-mustache", - from: "2.0.0-beta.2" + from: "2.0.0-beta.3" ), ], targets: [ diff --git a/Sources/EnumeratorMacroImpl/MacroError.swift b/Sources/EnumeratorMacroImpl/MacroError.swift index 2695049..2526813 100644 --- a/Sources/EnumeratorMacroImpl/MacroError.swift +++ b/Sources/EnumeratorMacroImpl/MacroError.swift @@ -15,6 +15,7 @@ enum MacroError: Error, CustomStringConvertible { case invalidTransform(transform: String, normalizedTypeName: String) case commentKeyNotAllowed(key: String) case declaredHere(name: String) + case redundantKeyValuesFunctionCall var caseName: String { switch self { @@ -44,6 +45,8 @@ enum MacroError: Error, CustomStringConvertible { "commentKeyNotAllowed" case .declaredHere: "declaredHere" + case .redundantKeyValuesFunctionCall: + "redundantKeyValuesFunctionCall" } } @@ -75,6 +78,8 @@ enum MacroError: Error, CustomStringConvertible { "Comment key '\(key)' is not allowed by the 'allowedComments' of the macro declaration" case let .declaredHere(name): "\(name) declared here:" + case .redundantKeyValuesFunctionCall: + "Redundant 'keyValues' function used. The array is already of type '\(EArray.self)'" } } } diff --git a/Sources/EnumeratorMacroImpl/Types/EArray.swift b/Sources/EnumeratorMacroImpl/Types/EArray.swift index 7a5037e..db5bde9 100644 --- a/Sources/EnumeratorMacroImpl/Types/EArray.swift +++ b/Sources/EnumeratorMacroImpl/Types/EArray.swift @@ -1,5 +1,5 @@ +import SwiftDiagnostics import Mustache -import Foundation struct EArray { let underlying: [Element] @@ -7,11 +7,6 @@ struct EArray { init(underlying: [Element]) { self.underlying = underlying } - - @available(*, unavailable, message: "Unwrap the array first") - init(underlying: EArray) { - fatalError() - } } extension EArray: Sequence, MustacheSequence { @@ -58,6 +53,15 @@ extension EArray: EMustacheTransformable { let string = EString(joined) return string case "keyValues": + if Self.self is EArray.Type { + RenderingContext.current.context.diagnose( + Diagnostic( + node: RenderingContext.current.node, + message: MacroError.redundantKeyValuesFunctionCall + ) + ) + return self + } let split: [EKeyValue] = self.underlying .map { String(describing: $0) } .compactMap(EKeyValue.init(from:)) diff --git a/Sources/EnumeratorMacroImpl/Types/EComments.swift b/Sources/EnumeratorMacroImpl/Types/EComments.swift index ea17e6e..87129e2 100644 --- a/Sources/EnumeratorMacroImpl/Types/EComments.swift +++ b/Sources/EnumeratorMacroImpl/Types/EComments.swift @@ -60,10 +60,13 @@ extension EComments: EMustacheTransformable { case "sorted": return EComments(underlying: self.underlying.underlying.sorted()) case "keyValues": - let split: [EKeyValue] = self.underlying.underlying - .map { String(describing: $0) } - .compactMap(EKeyValue.init(from:)) - return EComments(underlying: split) + RenderingContext.current.context.diagnose( + Diagnostic( + node: RenderingContext.current.node, + message: MacroError.redundantKeyValuesFunctionCall + ) + ) + return self default: if let context = RenderingContext.current, let allowedComments = context.allowedComments, diff --git a/Sources/EnumeratorMacroImpl/Types/EOptionalsArray.swift b/Sources/EnumeratorMacroImpl/Types/EOptionalsArray.swift index e9c27c8..c194fe2 100644 --- a/Sources/EnumeratorMacroImpl/Types/EOptionalsArray.swift +++ b/Sources/EnumeratorMacroImpl/Types/EOptionalsArray.swift @@ -1,3 +1,4 @@ +import SwiftDiagnostics import Mustache struct EOptionalsArray { @@ -10,11 +11,6 @@ struct EOptionalsArray { init(underlying: [EOptional]) { self.underlying = underlying } - - @available(*, unavailable, message: "Unwrap the optionals-array first") - init(underlying: EOptionalsArray) { - fatalError() - } } extension EOptionalsArray: Sequence, MustacheSequence { @@ -62,6 +58,15 @@ extension EOptionalsArray: EMustacheTransformable { let string = EString(joined) return string case "keyValues": + if Self.self is EOptionalsArray.Type { + RenderingContext.current.context.diagnose( + Diagnostic( + node: RenderingContext.current.node, + message: MacroError.redundantKeyValuesFunctionCall + ) + ) + return self + } let split: [EKeyValue] = self.underlying .compactMap { $0.toOptional().map { String(describing: $0) } } .compactMap(EKeyValue.init(from:)) diff --git a/Tests/EnumeratorMacroTests/EnumeratorMacroTests.swift b/Tests/EnumeratorMacroTests/EnumeratorMacroTests.swift index cb417a6..0279015 100644 --- a/Tests/EnumeratorMacroTests/EnumeratorMacroTests.swift +++ b/Tests/EnumeratorMacroTests/EnumeratorMacroTests.swift @@ -573,6 +573,41 @@ final class EnumeratorMacroTests: XCTestCase { ) } + func testRejectsDoubleKeyValueTransform() { + let diagnostic = DiagnosticSpec( + id: .init( + domain: "EnumeratorMacro.MacroError", + id: "redundantKeyValuesFunctionCall" + ), + message: "Redundant 'keyValues' function used. The array is already of type 'EArray'", + line: 1, + column: 13, + severity: .error + ) + assertMacroExpansion( + #""" + @Enumerator(""" + /// {{#cases}} {{keyValues(comments)}} {{/cases}} + """) + public enum ErrorMessage { + case case1 // business_error + case case2 // business_error: true + } + """#, + expandedSource: #""" + public enum ErrorMessage { + case case1 // business_error + case case2 // business_error: true + } + """#, + diagnostics: [ + diagnostic, + diagnostic + ], + macros: EnumeratorMacroEntryPoint.macros + ) + } + /// Test name is referenced in the README. func testRemovesExcessiveTrivia() { assertMacroExpansion(