Fixed ExpressionResolver leaks

This commit is contained in:
pkurchatov
2023-09-11 00:32:40 +03:00
parent 600fc270be
commit ad7d88ae45
4 changed files with 53 additions and 25 deletions
+47 -18
View File
@@ -14,7 +14,6 @@ import AppKit
public struct DivBlockModelingContext {
public let cardId: DivCardID
var cardLogId: String?
public internal(set) var parentPath: UIElementPath
var parentDivStatePath: DivStatePath?
let stateManager: DivStateManager
public let blockStateStorage: DivBlockStateStorage
@@ -27,7 +26,6 @@ public struct DivBlockModelingContext {
let flagsInfo: DivFlagsInfo
let extensionHandlers: [String: DivExtensionHandler]
let stateInterceptors: [String: DivStateInterceptor]
private let variables: DivVariables
let layoutDirection: UserInterfaceLayoutDirection
let debugParams: DebugParams
let scheduler: Scheduling
@@ -39,23 +37,24 @@ public struct DivBlockModelingContext {
let tooltipViewFactory: DivTooltipViewFactory?
private let variablesStorage: DivVariablesStorage
private let variableTracker: DivVariableTracker?
public private (set) var expressionResolver: ExpressionResolver
public internal(set) var parentPath: UIElementPath {
didSet {
expressionResolver = makeExpressionResolver(
cardId: cardId,
parentPath: parentPath,
variablesStorage: variablesStorage,
persistentValuesStorage: persistentValuesStorage,
errorsStorage: errorsStorage,
variableTracker: variableTracker
)
}
}
var overridenWidth: DivOverridenSize?
var overridenHeight: DivOverridenSize?
public var expressionResolver: ExpressionResolver {
ExpressionResolver(
variables: variables,
persistentValuesStorage: persistentValuesStorage,
errorTracker: { [weak errorsStorage] error in
errorsStorage?.add(DivExpressionError(error, path: parentPath))
},
variableTracker: { [weak variableTracker] variables in
variableTracker?.onVariablesUsed(cardId: cardId, variables: variables)
}
)
}
public init(
cardId: DivCardID,
cardLogId: String? = nil,
@@ -86,7 +85,8 @@ public struct DivBlockModelingContext {
) {
self.cardId = cardId
self.cardLogId = cardLogId
self.parentPath = parentPath ?? UIElementPath(cardId.rawValue)
let parentPath = parentPath ?? UIElementPath(cardId.rawValue)
self.parentPath = parentPath
self.parentDivStatePath = parentDivStatePath
self.stateManager = stateManager
self.blockStateStorage = blockStateStorage
@@ -97,7 +97,6 @@ public struct DivBlockModelingContext {
self.divCustomBlockFactory = divCustomBlockFactory ?? EmptyDivCustomBlockFactory()
self.flagsInfo = flagsInfo
self.fontProvider = fontProvider ?? DefaultFontProvider()
self.variables = variablesStorage.makeVariables(for: cardId)
self.playerFactory = playerFactory
self.debugParams = debugParams
self.scheduler = scheduler ?? TimerScheduler()
@@ -106,7 +105,8 @@ public struct DivBlockModelingContext {
self.errorsStorage = errorsStorage ?? DivErrorsStorage(errors: [])
self.layoutDirection = layoutDirection
self.variableTracker = variableTracker
self.persistentValuesStorage = persistentValuesStorage ?? DivPersistentValuesStorage()
let persistentValuesStorage = persistentValuesStorage ?? DivPersistentValuesStorage()
self.persistentValuesStorage = persistentValuesStorage
self.tooltipViewFactory = tooltipViewFactory
self.variablesStorage = variablesStorage
@@ -131,6 +131,15 @@ public struct DivBlockModelingContext {
stateInterceptorsDictionary[id] = $0
}
self.stateInterceptors = stateInterceptorsDictionary
expressionResolver = makeExpressionResolver(
cardId: cardId,
parentPath: parentPath,
variablesStorage: variablesStorage,
persistentValuesStorage: persistentValuesStorage,
errorsStorage: errorsStorage,
variableTracker: variableTracker
)
}
public func getExtensionHandlers(for div: DivBase) -> [DivExtensionHandler] {
@@ -208,3 +217,23 @@ public struct DivBlockModelingContext {
return Binding(name: variableName.rawValue, value: valueProp)
}
}
private func makeExpressionResolver(
cardId: DivCardID,
parentPath: UIElementPath,
variablesStorage: DivVariablesStorage,
persistentValuesStorage: DivPersistentValuesStorage,
errorsStorage: DivErrorsStorage?,
variableTracker: DivVariableTracker?
) -> ExpressionResolver {
ExpressionResolver(
variables: variablesStorage.makeVariables(for: cardId),
persistentValuesStorage: persistentValuesStorage,
errorTracker: { [weak errorsStorage] error in
errorsStorage?.add(DivExpressionError(error, path: parentPath))
},
variableTracker: { [weak variableTracker] variables in
variableTracker?.onVariablesUsed(cardId: cardId, variables: variables)
}
)
}
@@ -23,12 +23,12 @@ public final class ExpressionResolver {
variableTracker: @escaping VariableTracker = { _ in }
) {
self.variables = variables
self.persistentValuesStorage = persistentValuesStorage
self.errorTracker = {
DivKitLogger.error($0.description)
errorTracker?($0)
}
self.variableTracker = variableTracker
self.persistentValuesStorage = persistentValuesStorage
}
public func resolveString(expression: String) -> String {
@@ -115,7 +115,7 @@ enum ValueFunctions: String, CaseIterable {
extension ExpressionResolver {
fileprivate func getValueFunction<T>() -> GetOrDefault<T> {
{ name, fallbackValue in
{ [unowned self] name, fallbackValue in
self.variableTracker([DivVariableName(rawValue: name)])
guard let value = self.getValue(name) else {
return fallbackValue
@@ -131,7 +131,7 @@ extension ExpressionResolver {
fileprivate func getValueFunctionWithTransform<T, U>(
transform: @escaping (U) throws -> T
) -> GetOrDefaultWithTransform<U, T> {
{ name, fallbackValue in
{ [unowned self] name, fallbackValue in
self.variableTracker([DivVariableName(rawValue: name)])
guard let value = self.getValue(name) else {
return try transform(fallbackValue)
@@ -145,7 +145,7 @@ extension ExpressionResolver {
}
fileprivate func getStoredValueFunction<T>() -> GetOrDefault<T> {
{ name, fallbackValue in
{ [unowned self] name, fallbackValue in
guard let value: T = self.getStoredValue(name) else {
return fallbackValue
}
@@ -156,7 +156,7 @@ extension ExpressionResolver {
fileprivate func getStoredValueFunctionWithTransform<T, U>(
transform: @escaping (U) throws -> T
) -> GetOrDefaultWithTransform<U, T> {
{ name, fallbackValue in
{ [unowned self] name, fallbackValue in
guard let value: T = self.getStoredValue(name) else {
return try transform(fallbackValue)
}
@@ -7,8 +7,7 @@ import BasePublic
final class ShimmerStyleTests: XCTestCase {
private let expressionResolver = ExpressionResolver(
variables: [:],
persistentValuesStorage: DivPersistentValuesStorage(),
errorTracker: nil
persistentValuesStorage: DivPersistentValuesStorage()
)
func test_WhenDecodingEmptyShimmerStyle_DecodesWithDefaultValues() throws {