fixed PrototypeStorage copying.

This commit is contained in:
morevsavva
2023-12-15 17:24:26 +03:00
parent b4a6fe21a7
commit dd3d07af79
5 changed files with 44 additions and 16 deletions
@@ -2,14 +2,9 @@ import Foundation
final class PrototypesValueStorage {
private final class Node {
let value: Character?
var children: [Character: Node] = [:]
var data: [String: AnyHashable] = [:]
var isEndOfWord: Bool = false
init(value: Character? = nil) {
self.value = value
}
}
private let root = Node()
@@ -21,7 +16,7 @@ final class PrototypesValueStorage {
if let child = node.children[char] {
node = child
} else {
let newNode = Node(value: char)
let newNode = Node()
node.children[char] = newNode
node = newNode
}
@@ -51,3 +46,22 @@ final class PrototypesValueStorage {
return result
}
}
extension PrototypesValueStorage {
func copy() -> PrototypesValueStorage {
let copiedStorage = PrototypesValueStorage()
copyNode(from: root, to: copiedStorage.root)
return copiedStorage
}
private func copyNode(from sourceNode: Node, to destinationNode: Node) {
destinationNode.data = sourceNode.data
destinationNode.isEndOfWord = sourceNode.isEndOfWord
for (char, childNode) in sourceNode.children {
let newChildNode = Node()
destinationNode.children[char] = newChildNode
copyNode(from: childNode, to: newChildNode)
}
}
}
@@ -184,8 +184,9 @@ public struct DivBlockModelingContext {
variablesStorage: variablesStorage
)
functionsProvider = makeFunctionsProvider(
cardId: cardId,
variablesStorage: variablesStorage,
variableTracker: variableTracker,
variableValueProvider: variableValueProvider,
persistentValuesStorage: persistentValuesStorage
)
expressionResolver = makeExpressionResolver(
@@ -262,9 +263,12 @@ extension DivBlockModelingContext {
let expressionResolver: ExpressionResolver
let parentPath = parentPath ?? self.parentPath
let errorsStorage = errorsStorage ?? self.errorsStorage
let prototypesStorage = self.prototypesStorage
let prototypesStorage: PrototypesValueStorage
if let prototypesData {
prototypesStorage = self.prototypesStorage.copy()
prototypesStorage.insert(prefix: prototypesData.0, data: prototypesData.1)
} else {
prototypesStorage = self.prototypesStorage
}
let variableValueProvider: AnyCalcExpression.ValueProvider
let functionsProvider: FunctionsProvider
@@ -279,8 +283,9 @@ extension DivBlockModelingContext {
prototypesStorage: prototypesStorage
)
functionsProvider = makeFunctionsProvider(
cardId: cardId,
variablesStorage: variablesStorage,
variableTracker: variableTracker,
variableValueProvider: variableValueProvider,
persistentValuesStorage: persistentValuesStorage,
prototypesStorage: prototypesStorage
)
@@ -15,8 +15,9 @@ func makeVariableValueProvider(
}
func makeFunctionsProvider(
cardId: DivCardID,
variablesStorage: DivVariablesStorage,
variableTracker: @escaping ExpressionResolver.VariableTracker,
variableValueProvider: @escaping AnyCalcExpression.ValueProvider,
persistentValuesStorage: DivPersistentValuesStorage,
prototypesStorage: PrototypesValueStorage? = nil
) -> FunctionsProvider {
@@ -26,7 +27,10 @@ func makeFunctionsProvider(
return value
}
variableTracker([DivVariableName(rawValue: $0)])
return variableValueProvider($0)
return variablesStorage.getVariableValue(
cardId: cardId,
name: DivVariableName(rawValue: $0)
)
},
persistentValuesStorage: persistentValuesStorage
)
@@ -12,16 +12,13 @@ final class FunctionProviderTests: XCTestCase {
cardId: cardId,
variables: [DivVariableName(rawValue: "variable"): .string("value1")]
)
let variableValueProvider = makeVariableValueProvider(
cardId: cardId,
variablesStorage: variablesStorage
)
let prototypesData: (String, [String: AnyHashable]) = ("it.", ["variable": "value2"])
let prototypesStorage = PrototypesValueStorage()
prototypesStorage.insert(prefix: prototypesData.0, data: prototypesData.1)
let functionsProvider = makeFunctionsProvider(
cardId: cardId,
variablesStorage: variablesStorage,
variableTracker: { self.trackedResult = Array($0.map(\.rawValue)) },
variableValueProvider: variableValueProvider,
persistentValuesStorage: DivPersistentValuesStorage(),
prototypesStorage: prototypesStorage
)
@@ -33,6 +33,14 @@ final class PrototypesValueStorageTests: XCTestCase {
prototypesValueStorage.insert(prefix: "ab", data: dataAB)
XCTAssertEqual(prototypesValueStorage.findValue(expression: "abc"), "value2")
}
func test_copyingPrototypesStorage() throws {
let storage = PrototypesValueStorage()
let storageCopy = storage.copy()
storageCopy.insert(prefix: "a.", data: ["b": "c"])
XCTAssertNil(storage.findValue(expression: "a.b"))
XCTAssertEqual(storageCopy.findValue(expression: "a.b"), "c")
}
}
let prototypeData: [String: AnyHashable] = [