Skip to content

Commit

Permalink
Got the version working in ForkedModel.
Browse files Browse the repository at this point in the history
  • Loading branch information
drewmccormack committed Dec 25, 2024
1 parent 39e06c6 commit 06d05c5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Sources/ForkedModel/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ForkedMerge

public typealias Mergeable = Forked.Mergeable

@attached(`extension`, names: arbitrary, conformances: Mergeable, VersionedModel)
@attached(`extension`, conformances: Mergeable, VersionedModel, names: arbitrary)
@attached(member, names: arbitrary)
public macro ForkedModel(version: Int? = nil) = #externalMacro(module: "ForkedModelMacros", type: "ForkedModelMacro")

Expand Down
50 changes: 24 additions & 26 deletions Sources/ForkedModelMacros/ForkedModelMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,7 @@ public struct ForkedModelMacro: ExtensionMacro, MemberMacro {
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
// Extract version if provided
var version: Int? = nil
if let argumentList = node.arguments?.as(LabeledExprListSyntax.self) {
for argument in argumentList {
if argument.label?.text == versionLabel,
let integerExpr = argument.expression.as(IntegerLiteralExprSyntax.self) {
version = Int(integerExpr.literal.text)
}
}
}

// If version is provided, add modelVersion property and currentModelVersion
if let version {
if let version = extractVersion(from: node) {
// Check if struct conforms to VersionedModel
if let structDecl = declaration.as(StructDeclSyntax.self) {
let conformsToVersionedModel = structDecl.inheritanceClause?.inheritedTypes.contains {
Expand Down Expand Up @@ -143,7 +131,12 @@ public struct ForkedModelMacro: ExtensionMacro, MemberMacro {

// If version is provided, also generate VersionedModel extension
if let version = extractVersion(from: node) {
return [mergeableExtension] // VersionedModel conformance is handled by the member macro
let versionedModelExtension = try ExtensionDeclSyntax(
"""
extension \(type.trimmed): Forked.VersionedModel {}
"""
)
return [mergeableExtension, versionedModelExtension]
}

return [mergeableExtension]
Expand Down Expand Up @@ -256,21 +249,26 @@ public struct ForkedModelMacro: ExtensionMacro, MemberMacro {
providingConformancesOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
// Extract version if provided
var version: Int? = nil
if let argumentList = node.arguments?.as(LabeledExprListSyntax.self) {
for argument in argumentList {
if argument.label?.text == versionLabel,
let integerExpr = argument.expression.as(IntegerLiteralExprSyntax.self) {
version = Int(integerExpr.literal.text)
}
}
if extractVersion(from: node) != nil {
// Create a proper TypeSyntax for VersionedModel
return [(TypeSyntax("Forked.VersionedModel"), nil)]
}
return []
}

private static func extractVersion(from node: AttributeSyntax) -> Int? {
guard let argumentList = node.arguments?.as(LabeledExprListSyntax.self) else {
return nil
}

if version != nil {
return [("VersionedModel", nil)]
for argument in argumentList {
if argument.label?.text == versionLabel,
let integerExpr = argument.expression.as(IntegerLiteralExprSyntax.self) {
return Int(integerExpr.literal.text)
}
}
return []

return nil
}
}

9 changes: 5 additions & 4 deletions Tests/ForkedTests/ForkedModelMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -564,24 +564,25 @@ final class ForkedModelMacrosSuite: XCTestCase {
expandedSource:
"""
struct User {
var name: String = ""
public static let currentModelVersion: Int = 1
public var modelVersion: Int? = Self.currentModelVersion
var name: String = ""
}
extension User: Forked.Mergeable {
public func merged(withSubordinate other: Self, commonAncestor: Self) throws -> Self {
var merged = self
if self.name == commonAncestor.name {
merged.name = other.name
merged.name = other.name
} else {
merged.name = self.name
merged.name = self.name
}
return merged
}
}
extension User: VersionedModel {
extension User: Forked.VersionedModel {
}
""",
macros: Self.testMacros
Expand Down

0 comments on commit 06d05c5

Please sign in to comment.