diff --git a/Sources/Normalization/NormalizedStorageType.swift b/Sources/Normalization/NormalizedStorageType.swift index 63535b3..adfefbb 100644 --- a/Sources/Normalization/NormalizedStorageType.swift +++ b/Sources/Normalization/NormalizedStorageType.swift @@ -5,6 +5,8 @@ public protocol NormalizedStorageType: Equatable, Sendable { Performs any additional operations for updating. */ func finalizeTransaction(transaction: inout ModifyingTransaction) + + var version: UInt64 { get set } static func compare(lhs: Self, rhs: Self) -> Bool } @@ -39,6 +41,8 @@ extension NormalizedStorageType { do { self = transaction.modifying } + + self.version += 1 } diff --git a/Sources/Normalization/VergeNormalization+Macros.swift b/Sources/Normalization/VergeNormalization+Macros.swift index f3c69cf..b3e9d8a 100644 --- a/Sources/Normalization/VergeNormalization+Macros.swift +++ b/Sources/Normalization/VergeNormalization+Macros.swift @@ -1,5 +1,5 @@ -//@attached(member, names: arbitrary) +@attached(member, names: named(version)) //@attached(memberAttribute) @attached(extension, conformances: NormalizedStorageType, Equatable, Sendable, names: named(Context), arbitrary) public macro NormalizedStorage() = #externalMacro(module: "NormalizationMacrosPlugin", type: "NormalizedStorageMacro") diff --git a/Sources/NormalizationMacrosPlugin/NormalizedStorageMacro.swift b/Sources/NormalizationMacrosPlugin/NormalizedStorageMacro.swift index 4420583..bb04228 100644 --- a/Sources/NormalizationMacrosPlugin/NormalizedStorageMacro.swift +++ b/Sources/NormalizationMacrosPlugin/NormalizedStorageMacro.swift @@ -176,84 +176,16 @@ extension NormalizedStorageMacro: MemberAttributeMacro { /// Add member extension NormalizedStorageMacro: MemberMacro { - - final class RenamingVisitor: SyntaxRewriter { - - init() {} - - override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { - return "_$\(node.identifier)" - } - - override func visit(_ node: VariableDeclSyntax) -> DeclSyntax { - - // TODO: make variable private - return super.visit(node) - } - } - - final class StoredPropertyCollector: SyntaxVisitor { - - var storedProperties: [VariableDeclSyntax] = [] - - var onFoundMultipleBindings: () -> Void = {} - - override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind { - - if node.bindingSpecifier == "let" { - storedProperties.append(node) - return super.visit(node) - } - - if node.bindings.count > 1 { - // let a,b,c = 0 - // it's stored - onFoundMultipleBindings() - return super.visit(node) - } - - if node.bindings.first?.accessorBlock == nil { - storedProperties.append(node) - return super.visit(node) - } - - // computed property - - return .visitChildren - } - - } - - static func makeVariableFromConstant(_ node: VariableDeclSyntax) -> VariableDeclSyntax { - var modified = node - modified.bindingSpecifier = "var" - return modified - } - + public static func expansion( of node: SwiftSyntax.AttributeSyntax, providingMembersOf declaration: some SwiftSyntax.DeclGroupSyntax, in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [SwiftSyntax.DeclSyntax] { - - let v = StoredPropertyCollector(viewMode: .fixedUp) - v.onFoundMultipleBindings = { - context.addDiagnostics(from: MacroError(message: "Cannot use multiple bindings"), node: node) - } - v.walk(declaration.memberBlock) - - let storageMembers = v.storedProperties - .map(makeVariableFromConstant) - .map { - - let rename = RenamingVisitor() - let renamed = rename.visit($0) - - return renamed - } - - return storageMembers + return [ + "public var version: UInt64 = 0" + ] } diff --git a/Tests/NormalizationMacrosTests/Tests.swift b/Tests/NormalizationMacrosTests/Tests.swift index b62ae77..e633bfb 100644 --- a/Tests/NormalizationMacrosTests/Tests.swift +++ b/Tests/NormalizationMacrosTests/Tests.swift @@ -54,6 +54,7 @@ final class DatabaseMacroTests: XCTestCase { } extension MyDatabase: NormalizedStorageType { + public var version: UInt64 { 0 } } extension MyDatabase: Sendable { @@ -98,6 +99,7 @@ final class DatabaseMacroTests: XCTestCase { } extension MyDatabase: NormalizedStorageType { + public var version: UInt64 { 0 } } extension MyDatabase: Sendable { diff --git a/Tests/NormalizationTests/Source.swift b/Tests/NormalizationTests/Source.swift index 74789ef..1d6e8dc 100644 --- a/Tests/NormalizationTests/Source.swift +++ b/Tests/NormalizationTests/Source.swift @@ -24,7 +24,8 @@ final class Tests: XCTestCase { func testCommit() { var state = MyStorage() - + let currentVersion = state.version + var transaction = state.beginBatchUpdates() let book = Book(rawID: "some", authorID: Author.anonymous.typedID) @@ -36,6 +37,7 @@ final class Tests: XCTestCase { let b = state.book XCTAssertEqual(a, b) + XCTAssertNotEqual(currentVersion, state.version) }