mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
fixed PrototypeStorage copying.
This commit is contained in:
@@ -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] = [
|
||||
|
||||
Reference in New Issue
Block a user