Skip to content

Commit

Permalink
Fix @CasePathable when using Element generic. (#183)
Browse files Browse the repository at this point in the history
* Fix @CasePathable when using Eement generic.

* wip
  • Loading branch information
mbrandonw authored Jul 18, 2024
1 parent bdd3bf5 commit 0a0403b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
8 changes: 4 additions & 4 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-macro-testing",
"state" : {
"revision" : "5c4a1b9d7c23cd5c08ea50677d8e89080365cb00",
"version" : "0.4.0"
"revision" : "a35257b7e9ce44e92636447003a8eeefb77b145c",
"version" : "0.5.1"
}
},
{
"identity" : "swift-snapshot-testing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
"state" : {
"revision" : "625ccca8570773dd84a34ee51a81aa2bc5a4f97a",
"version" : "1.16.0"
"revision" : "c097f955b4e724690f0fc8ffb7a6d4b881c9c4e3",
"version" : "1.17.2"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Sources/CasePaths/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/// \UserAction.Cases.settings // CasePath<UserAction, SettingsAction>
/// ```
@attached(extension, conformances: CasePathable, CasePathIterable)
@attached(member, names: named(AllCasePaths), named(allCasePaths))
@attached(member, names: named(AllCasePaths), named(allCasePaths), named(_$Element))
public macro CasePathable() =
#externalMacro(
module: "CasePathsMacros", type: "CasePathableMacro"
Expand Down
15 changes: 13 additions & 2 deletions Sources/CasePathsMacros/CasePathableMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extension CasePathableMacro: MemberMacro {

let subscriptReturn = allCases.isEmpty ? #"\.never"# : #"return \.never"#

return [
var decls: [DeclSyntax] = [
"""
public struct AllCasePaths: CasePaths.CasePathReflectable, Sendable, Sequence {
public subscript(root: \(enumName)) -> CasePaths.PartialCaseKeyPath<\(enumName)> {
Expand All @@ -115,6 +115,15 @@ extension CasePathableMacro: MemberMacro {
public static var allCasePaths: AllCasePaths { AllCasePaths() }
"""
]

let hasElementGeneric = enumDecl.genericParameterClause?.parameters
.contains { $0.name.text == "Element" }
?? false
if hasElementGeneric {
decls.append("public typealias _$Element = Element")
}

return decls
}

static func generateCases(
Expand Down Expand Up @@ -170,7 +179,9 @@ extension CasePathableMacro: MemberMacro {
) -> [DeclSyntax] {
decl.elements.map {
let caseName = $0.name.trimmed
let associatedValueName = $0.trimmedTypeDescription
let associatedValueName = $0.trimmedTypeDescription == "Element"
? "_$Element"
: $0.trimmedTypeDescription
let hasPayload = $0.parameterClause.map { !$0.parameters.isEmpty } ?? false
let embedNames: String
let bindingNames: String
Expand Down
51 changes: 50 additions & 1 deletion Tests/CasePathsMacrosTests/CasePathableMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import XCTest
final class CasePathableMacroTests: XCTestCase {
override func invokeTest() {
withMacroTesting(
// isRecording: true,
//record: .failed,
macros: [CasePathableMacro.self]
) {
super.invokeTest()
Expand Down Expand Up @@ -1215,4 +1215,53 @@ final class CasePathableMacroTests: XCTestCase {
"""#
}
}

func testElementGeneric() {
assertMacro {
"""
@CasePathable enum Action<Element> {
case element(Element)
}
"""
} expansion: {
#"""
enum Action<Element> {
case element(Element)
public struct AllCasePaths: CasePaths.CasePathReflectable, Sendable, Sequence {
public subscript(root: Action) -> CasePaths.PartialCaseKeyPath<Action> {
if root.is(\.element) {
return \.element
}
return \.never
}
public var element: CasePaths.AnyCasePath<Action, _$Element> {
CasePaths.AnyCasePath<Action, _$Element>(
embed: {
Action.element($0)
},
extract: {
guard case let .element(v0) = $0 else {
return nil
}
return v0
}
)
}
public func makeIterator() -> IndexingIterator<[CasePaths.PartialCaseKeyPath<Action>]> {
var allCasePaths: [CasePaths.PartialCaseKeyPath<Action>] = []
allCasePaths.append(\.element)
return allCasePaths.makeIterator()
}
}
public static var allCasePaths: AllCasePaths { AllCasePaths() }
public typealias _$Element = Element
}
extension Action: CasePaths.CasePathable, CasePaths.CasePathIterable {
}
"""#
}
}
}
4 changes: 4 additions & 0 deletions Tests/CasePathsTests/MacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ private enum Comments {
enum Action {
case alert(Never)
}

@CasePathable enum EnumWithElementGeneric<Element> {
case element(Element)
}

0 comments on commit 0a0403b

Please sign in to comment.