mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
Support local functions
commit_hash:7751f6b71a5611165e3a0c9b01614fd0618e44bc
This commit is contained in:
+7
-1
@@ -734,6 +734,7 @@
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Function.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/Function.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/FunctionArgument.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/FunctionArgument.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/FunctionProvider.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/FunctionProvider.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/LocalFunctionProvider.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/LocalFunctionProvider.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/StoredValueProvider.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/StoredValueProvider.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/VariableProvider.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/VariableProvider.kt",
|
||||
"client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/WarningSender.kt":"divkit/public/client/android/div-evaluable/src/main/java/com/yandex/div/evaluable/WarningSender.kt",
|
||||
@@ -1078,23 +1079,27 @@
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionResolverImpl.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntime.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/ExpressionsRuntimeProvider.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/FunctionProviderDecorator.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/FunctionProviderDecorator.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/ChildPathUnitCache.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/ChildPathUnitCache.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/DivRuntimeVisitor.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/DivRuntimeVisitor.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/LocalFunction.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/LocalFunction.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/RuntimeStore.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/RuntimeStore.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/RuntimeTree.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/RuntimeTree.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/local/utils.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/local/utils.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValueDeclarationException.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValueDeclarationException.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesActionHandler.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/storedvalues/StoredValuesController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/triggers/ConditionPart.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/ConditionPart.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/triggers/TriggersController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/ConstantsProvider.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/ConstantsProvider.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariableController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariablesParser.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/DivVariablesParser.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/GlobalVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/GlobalVariableController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/LocalVariableController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/MultiVariableSource.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/MultiVariableSource.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/Observers.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/Observers.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/SingleVariableSource.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/SingleVariableSource.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/TwoWayVariableBinder.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/TwoWayVariableBinder.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableAndConstantController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableAndConstantController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableController.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableControllerImpl.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableDeclarationNotifier.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/expression/variables/VariableDeclarationNotifier.kt",
|
||||
@@ -1147,6 +1152,7 @@
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/ExpressionSubscribers.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/ExpressionSubscribers.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/FunctionMapper.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/FunctionMapper.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/ImageRepresentation.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/ImageRepresentation.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/ImageUtils.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/ImageUtils.kt",
|
||||
"client/android/div/src/main/java/com/yandex/div/core/util/Releasables.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/util/Releasables.kt",
|
||||
|
||||
+5
@@ -36,6 +36,11 @@ class IntegerOverflow(
|
||||
cause: Exception? = null
|
||||
) : EvaluableException("Failed to evaluate [$expression]. $REASON_INTEGER_OVERFLOW", cause)
|
||||
|
||||
class MissingLocalFunctionException(
|
||||
name: String,
|
||||
args: List<EvaluableType>,
|
||||
): EvaluableException("Function '$name(${args.toMessageFormat()})' is missing.")
|
||||
|
||||
internal fun throwExceptionOnEvaluationFailed(
|
||||
expression: String,
|
||||
reason: String,
|
||||
|
||||
@@ -20,7 +20,9 @@ abstract class Function {
|
||||
): Any {
|
||||
val result = evaluate(evaluationContext, expressionContext, args)
|
||||
if (EvaluableType.of(result) != resultType) {
|
||||
throw EvaluableException("Function returned ${EvaluableType.of(result)}, but $resultType was expected")
|
||||
throw EvaluableException(
|
||||
"Function $this returned ${EvaluableType.of(result)}, but $resultType was expected."
|
||||
)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.yandex.div.evaluable
|
||||
|
||||
class LocalFunctionProvider(private val functions: List<Function>) : FunctionProvider {
|
||||
|
||||
override fun get(name: String, args: List<EvaluableType>): Function {
|
||||
findFunction(name) { matchesArguments(args) }?.let { return it }
|
||||
findFunction(name) { matchesArgumentsWithCast(args) }?.let { return it }
|
||||
throw MissingLocalFunctionException(name, args)
|
||||
}
|
||||
|
||||
override fun getMethod(name: String, args: List<EvaluableType>): Function {
|
||||
findFunction(name) { matchesArguments(args) }?.let { return it }
|
||||
findFunction(name) { matchesArgumentsWithCast(args) }?.let { return it }
|
||||
throw MissingLocalFunctionException(name, args)
|
||||
}
|
||||
|
||||
private fun findFunction(name: String, matcher: Function.() -> Function.MatchResult): Function? {
|
||||
val localFunctions = functions.filter { it.name == name && it.matcher() == Function.MatchResult.Ok }
|
||||
return when (localFunctions.size) {
|
||||
0 -> null
|
||||
1 -> return localFunctions[0]
|
||||
else -> throw EvaluableException("Function ${localFunctions[0]} declared multiple times.")
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -2,9 +2,9 @@ package com.yandex.div.core.expression
|
||||
|
||||
import com.yandex.div.core.Disposable
|
||||
import com.yandex.div.core.ObserverList
|
||||
import com.yandex.div.core.expression.variables.LocalVariableController
|
||||
import com.yandex.div.core.expression.variables.ConstantsProvider
|
||||
import com.yandex.div.core.expression.variables.VariableAndConstantController
|
||||
import com.yandex.div.core.expression.variables.VariableController
|
||||
import com.yandex.div.core.expression.variables.VariableSource
|
||||
import com.yandex.div.core.view2.errors.ErrorCollector
|
||||
import com.yandex.div.evaluable.Evaluable
|
||||
import com.yandex.div.evaluable.EvaluableException
|
||||
@@ -40,7 +40,11 @@ internal class ExpressionResolverImpl(
|
||||
var suppressMissingVariableException: Boolean = false
|
||||
|
||||
init {
|
||||
onCreateCallback.onCreate(this, variableController)
|
||||
onCreateCallback.onCreate(
|
||||
this,
|
||||
variableController,
|
||||
evaluator.evaluationContext.functionProvider as FunctionProviderDecorator
|
||||
)
|
||||
}
|
||||
|
||||
override fun <R, T : Any> get(
|
||||
@@ -226,13 +230,13 @@ internal class ExpressionResolverImpl(
|
||||
}
|
||||
}
|
||||
|
||||
operator fun plus(variableSource: VariableSource): ExpressionResolverImpl {
|
||||
val localVariableController = LocalVariableController(variableController, variableSource)
|
||||
operator fun plus(constants: ConstantsProvider): ExpressionResolverImpl {
|
||||
val variableAndConstantController = VariableAndConstantController(variableController, constants)
|
||||
return ExpressionResolverImpl(
|
||||
variableController = localVariableController,
|
||||
variableController = variableAndConstantController,
|
||||
evaluator = Evaluator(
|
||||
evaluationContext = EvaluationContext(
|
||||
variableProvider = localVariableController,
|
||||
variableProvider = variableAndConstantController,
|
||||
storedValueProvider = evaluator.evaluationContext.storedValueProvider,
|
||||
functionProvider = evaluator.evaluationContext.functionProvider,
|
||||
warningSender = evaluator.evaluationContext.warningSender
|
||||
@@ -256,6 +260,10 @@ internal class ExpressionResolverImpl(
|
||||
* as a new ExpressionRuntime we are using OnCreateCallback.
|
||||
*/
|
||||
internal fun interface OnCreateCallback {
|
||||
fun onCreate(resolver: ExpressionResolverImpl, variableController: VariableController)
|
||||
fun onCreate(
|
||||
resolver: ExpressionResolverImpl,
|
||||
variableController: VariableController,
|
||||
functionProvider: FunctionProviderDecorator
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ internal class ExpressionsRuntime(
|
||||
val expressionResolver: ExpressionResolver,
|
||||
val variableController: VariableController,
|
||||
val triggersController: TriggersController? = null,
|
||||
val functionProvider: FunctionProviderDecorator,
|
||||
val runtimeStore: RuntimeStore,
|
||||
) {
|
||||
private val expressionResolverImpl get() = expressionResolver as? ExpressionResolverImpl
|
||||
|
||||
+5
-3
@@ -125,12 +125,13 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
addSource(globalVariableController.variableSource)
|
||||
}
|
||||
|
||||
val functionProvider = FunctionProviderDecorator(GeneratedBuiltinFunctionProvider)
|
||||
val evaluationContext = EvaluationContext(
|
||||
variableProvider = variableController,
|
||||
storedValueProvider = { storedValueName ->
|
||||
storedValuesController.getStoredValue(storedValueName, errorCollector)?.getValue()
|
||||
},
|
||||
functionProvider = GeneratedBuiltinFunctionProvider,
|
||||
functionProvider = functionProvider,
|
||||
warningSender = { expressionContext, message ->
|
||||
val rawExpr = expressionContext.evaluable.rawExpr
|
||||
val warning = "Warning occurred while evaluating '$rawExpr': $message"
|
||||
@@ -142,9 +143,9 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
val evaluator = Evaluator(evaluationContext)
|
||||
|
||||
val runtimeStore = RuntimeStore(evaluator, errorCollector, logger, divActionBinder)
|
||||
val callback = ExpressionResolverImpl.OnCreateCallback { resolver, variableController ->
|
||||
val callback = ExpressionResolverImpl.OnCreateCallback { resolver, variableController, functionProvider ->
|
||||
runtimeStore.putRuntime(
|
||||
runtime = ExpressionsRuntime(resolver, variableController, null, runtimeStore)
|
||||
runtime = ExpressionsRuntime(resolver, variableController, null, functionProvider, runtimeStore)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -168,6 +169,7 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
expressionResolver,
|
||||
variableController,
|
||||
triggersController,
|
||||
functionProvider,
|
||||
runtimeStore,
|
||||
).also { runtimeStore.rootRuntime = it }
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.yandex.div.core.expression
|
||||
|
||||
import com.yandex.div.evaluable.EvaluableType
|
||||
import com.yandex.div.evaluable.Function
|
||||
import com.yandex.div.evaluable.FunctionProvider
|
||||
import com.yandex.div.evaluable.LocalFunctionProvider
|
||||
import com.yandex.div.evaluable.MissingLocalFunctionException
|
||||
|
||||
internal class FunctionProviderDecorator(private val provider: FunctionProvider) : FunctionProvider {
|
||||
|
||||
override fun get(name: String, args: List<EvaluableType>) = provider.get(name, args)
|
||||
|
||||
override fun getMethod(name: String, args: List<EvaluableType>) = provider.getMethod(name, args)
|
||||
|
||||
operator fun plus(functions: List<Function>): FunctionProviderDecorator {
|
||||
val localProvider = LocalFunctionProvider(functions)
|
||||
return FunctionProviderDecorator(
|
||||
object : FunctionProvider {
|
||||
|
||||
override fun get(name: String, args: List<EvaluableType>): Function {
|
||||
return try {
|
||||
localProvider.get(name, args)
|
||||
} catch (e: MissingLocalFunctionException) {
|
||||
provider.get(name, args)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMethod(name: String, args: List<EvaluableType>): Function {
|
||||
return try {
|
||||
localProvider.getMethod(name, args)
|
||||
} catch (e: MissingLocalFunctionException) {
|
||||
provider.getMethod(name, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -123,19 +123,20 @@ internal class DivRuntimeVisitor @Inject constructor(
|
||||
path: MutableList<String>,
|
||||
parentRuntime: ExpressionsRuntime?
|
||||
): ExpressionsRuntime? {
|
||||
return if (div.value().variables.isNullOrEmpty() && div.value().variableTriggers.isNullOrEmpty()) {
|
||||
parentRuntime
|
||||
} else {
|
||||
return if (div.needLocalRuntime) {
|
||||
val stringPath = path.joinToString("/")
|
||||
divView.runtimeStore?.getOrCreateRuntime(
|
||||
path = stringPath,
|
||||
variables = div.value().variables?.toVariables(),
|
||||
triggers = div.value().variableTriggers,
|
||||
functions = div.value().functions,
|
||||
parentRuntime = parentRuntime,
|
||||
)?.also { runtime -> runtime.onAttachedToWindow(divView) } ?: run {
|
||||
Assert.fail("ExpressionRuntimeVisitor cannot create runtime for path = $stringPath")
|
||||
null
|
||||
}
|
||||
} else {
|
||||
parentRuntime
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.yandex.div.core.expression.local
|
||||
|
||||
import com.yandex.div.core.expression.variables.ConstantsProvider
|
||||
import com.yandex.div.core.expression.variables.VariableAndConstantController
|
||||
import com.yandex.div.core.expression.variables.VariableController
|
||||
import com.yandex.div.evaluable.Evaluable
|
||||
import com.yandex.div.evaluable.EvaluableType
|
||||
import com.yandex.div.evaluable.EvaluationContext
|
||||
import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div.evaluable.ExpressionContext
|
||||
import com.yandex.div.evaluable.Function
|
||||
import com.yandex.div.evaluable.FunctionArgument
|
||||
|
||||
class LocalFunction(
|
||||
override val name: String,
|
||||
override val declaredArgs: List<FunctionArgument>,
|
||||
override val resultType: EvaluableType,
|
||||
private val argNames: List<String>,
|
||||
body: String,
|
||||
) : Function() {
|
||||
|
||||
override val isPure = false
|
||||
|
||||
private val evaluable = Evaluable.lazy(body)
|
||||
|
||||
override fun evaluate(
|
||||
evaluationContext: EvaluationContext,
|
||||
expressionContext: ExpressionContext,
|
||||
args: List<Any>
|
||||
): Any {
|
||||
val argConstants = mutableMapOf<String, Any>()
|
||||
argNames.forEachIndexed { index, name ->
|
||||
argConstants[name] = args[index]
|
||||
}
|
||||
val variableProvider = VariableAndConstantController(
|
||||
evaluationContext.variableProvider as VariableController,
|
||||
ConstantsProvider(argConstants),
|
||||
)
|
||||
val newContext = EvaluationContext(
|
||||
variableProvider,
|
||||
evaluationContext.storedValueProvider,
|
||||
evaluationContext.functionProvider,
|
||||
evaluationContext.warningSender
|
||||
)
|
||||
return Evaluator(newContext).eval(evaluable)
|
||||
}
|
||||
}
|
||||
+18
-9
@@ -5,6 +5,7 @@ import com.yandex.div.core.expression.ExpressionResolverImpl
|
||||
import com.yandex.div.core.expression.ExpressionsRuntime
|
||||
import com.yandex.div.core.expression.triggers.TriggersController
|
||||
import com.yandex.div.core.expression.variables.VariableControllerImpl
|
||||
import com.yandex.div.core.util.toLocalFunctions
|
||||
import com.yandex.div.core.view2.divs.DivActionBinder
|
||||
import com.yandex.div.core.view2.errors.ErrorCollector
|
||||
import com.yandex.div.data.Variable
|
||||
@@ -13,6 +14,7 @@ import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div.internal.Assert
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.DivBase
|
||||
import com.yandex.div2.DivFunction
|
||||
import com.yandex.div2.DivTrigger
|
||||
|
||||
private const val ERROR_UNKNOWN_RESOLVER =
|
||||
@@ -41,8 +43,8 @@ internal class RuntimeStore(
|
||||
}
|
||||
|
||||
private val onCreateCallback by lazy {
|
||||
ExpressionResolverImpl.OnCreateCallback { resolver, variableController ->
|
||||
ExpressionsRuntime(resolver, variableController, null, this).also {
|
||||
ExpressionResolverImpl.OnCreateCallback { resolver, variableController, functionProvider ->
|
||||
ExpressionsRuntime(resolver, variableController, null, functionProvider, this).also {
|
||||
/**
|
||||
* we cannot provide path here, otherwise descendants of ExpressionResolver will
|
||||
* receive the same callback and override runtime for provided path.
|
||||
@@ -70,10 +72,11 @@ internal class RuntimeStore(
|
||||
path: String,
|
||||
variables: List<Variable>? = null,
|
||||
triggers: List<DivTrigger>? = null,
|
||||
functions: List<DivFunction>? = null,
|
||||
parentResolver: ExpressionResolver? = null,
|
||||
parentRuntime: ExpressionsRuntime? = null,
|
||||
) = tree.getNode(path)?.runtime ?: getRuntimeOrCreateChild(
|
||||
path, variables, triggers,null, parentResolver, parentRuntime
|
||||
path, variables, triggers, functions, null, parentResolver, parentRuntime
|
||||
)
|
||||
|
||||
internal fun getRuntimeWithOrNull(resolver: ExpressionResolver) = resolverToRuntime[resolver]
|
||||
@@ -98,6 +101,7 @@ internal class RuntimeStore(
|
||||
path: String,
|
||||
variables: List<Variable>?,
|
||||
triggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?,
|
||||
resolver: ExpressionResolver,
|
||||
parentResolver: ExpressionResolver?,
|
||||
): ExpressionsRuntime? {
|
||||
@@ -110,7 +114,7 @@ internal class RuntimeStore(
|
||||
}
|
||||
|
||||
if (runtimeForPath != null) tree.removeRuntimeAndCleanup(runtimeForPath, path)
|
||||
return getRuntimeOrCreateChild(path, variables, triggers, existingRuntime, parentResolver)
|
||||
return getRuntimeOrCreateChild(path, variables, triggers, functions, existingRuntime, parentResolver)
|
||||
}
|
||||
|
||||
internal fun cleanup() {
|
||||
@@ -135,14 +139,18 @@ internal class RuntimeStore(
|
||||
path: String,
|
||||
variables: List<Variable>?,
|
||||
variablesTriggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?,
|
||||
): ExpressionsRuntime {
|
||||
val localVariableController = VariableControllerImpl(baseRuntime.variableController)
|
||||
variables?.forEach { localVariableController.declare(it) }
|
||||
|
||||
var functionProvider = baseRuntime.functionProvider
|
||||
functions?.let { functionProvider += it.toLocalFunctions() }
|
||||
|
||||
val evaluationContext = EvaluationContext(
|
||||
variableProvider = localVariableController,
|
||||
storedValueProvider = evaluator.evaluationContext.storedValueProvider,
|
||||
functionProvider = evaluator.evaluationContext.functionProvider,
|
||||
functionProvider = functionProvider,
|
||||
warningSender = evaluator.evaluationContext.warningSender
|
||||
)
|
||||
|
||||
@@ -165,7 +173,7 @@ internal class RuntimeStore(
|
||||
ensureTriggersSynced(variablesTriggers)
|
||||
}
|
||||
|
||||
return ExpressionsRuntime(resolver, localVariableController, triggerController, this).also {
|
||||
return ExpressionsRuntime(resolver, localVariableController, triggerController, functionProvider, this).also {
|
||||
putRuntime(it, path, parentRuntime)
|
||||
}
|
||||
}
|
||||
@@ -174,6 +182,7 @@ internal class RuntimeStore(
|
||||
path: String,
|
||||
variables: List<Variable>?,
|
||||
variablesTriggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?,
|
||||
existingRuntime: ExpressionsRuntime? = null,
|
||||
parentResolver: ExpressionResolver? = null,
|
||||
parentRuntime: ExpressionsRuntime? = null,
|
||||
@@ -189,13 +198,13 @@ internal class RuntimeStore(
|
||||
|
||||
val parentRuntime = parentRuntime ?: parentResolver?.let { getRuntimeWithOrNull(it) }
|
||||
|
||||
return if (variables.isNullOrEmpty() && variablesTriggers.isNullOrEmpty()) {
|
||||
return if (needLocalRuntime(variables, variablesTriggers, functions)) {
|
||||
createChildRuntime(runtime, parentRuntime, path, variables, variablesTriggers, functions)
|
||||
} else {
|
||||
runtime.also {
|
||||
tree.storeRuntime(runtime, parentRuntime, path)
|
||||
runtime.updateSubscriptions()
|
||||
}
|
||||
} else {
|
||||
createChildRuntime(runtime, parentRuntime, path, variables, variablesTriggers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.yandex.div.core.expression.local
|
||||
|
||||
import com.yandex.div.core.expression.ExpressionsRuntime
|
||||
import com.yandex.div.core.expression.variables.LocalVariableController
|
||||
import com.yandex.div.core.expression.variables.VariableAndConstantController
|
||||
|
||||
internal class RuntimeTree {
|
||||
private val runtimesToNodes = mutableMapOf<ExpressionsRuntime, RuntimeNode>()
|
||||
@@ -49,7 +49,7 @@ internal class RuntimeTree {
|
||||
pathToNodes.remove(it.path)
|
||||
|
||||
// we should not cleanup LocalVariableController because it will just cleanup it's delegate
|
||||
if (it.runtime.variableController !is LocalVariableController) it.runtime.cleanup()
|
||||
if (it.runtime.variableController !is VariableAndConstantController) it.runtime.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yandex.div.core.expression.local
|
||||
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div2.Div
|
||||
import com.yandex.div2.DivFunction
|
||||
import com.yandex.div2.DivTrigger
|
||||
|
||||
internal val Div.needLocalRuntime get() =
|
||||
!value().run { variables.isNullOrEmpty() && variableTriggers.isNullOrEmpty() && functions.isNullOrEmpty() }
|
||||
|
||||
internal fun needLocalRuntime(
|
||||
variables: List<Variable>?,
|
||||
variableTriggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?
|
||||
) = !(variables.isNullOrEmpty() && variableTriggers.isNullOrEmpty() && functions.isNullOrEmpty())
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.yandex.div.core.expression.variables
|
||||
|
||||
import com.yandex.div.evaluable.VariableProvider
|
||||
|
||||
internal class ConstantsProvider(private val constants: Map<String, Any>) : VariableProvider {
|
||||
override fun get(name: String) = constants[name]
|
||||
}
|
||||
+5
-4
@@ -4,11 +4,13 @@ import com.yandex.div.core.Disposable
|
||||
import com.yandex.div.core.view2.errors.ErrorCollector
|
||||
import com.yandex.div.data.Variable
|
||||
|
||||
internal class LocalVariableController(
|
||||
internal class VariableAndConstantController(
|
||||
private val delegate: VariableController,
|
||||
private val localVariables: VariableSource
|
||||
private val constants: ConstantsProvider,
|
||||
) : VariableController {
|
||||
|
||||
override fun get(name: String) = constants.get(name) ?: super.get(name)
|
||||
|
||||
override fun subscribeToVariablesChange(
|
||||
names: List<String>,
|
||||
invokeOnSubscription: Boolean,
|
||||
@@ -31,8 +33,7 @@ internal class LocalVariableController(
|
||||
|
||||
override fun addSource(source: VariableSource) = delegate.addSource(source)
|
||||
|
||||
override fun getMutableVariable(name: String) =
|
||||
localVariables.getMutableVariable(name) ?: delegate.getMutableVariable(name)
|
||||
override fun getMutableVariable(name: String) = delegate.getMutableVariable(name)
|
||||
|
||||
override fun declare(variable: Variable) = delegate.declare(variable)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.yandex.div.core.util
|
||||
|
||||
import com.yandex.div.evaluable.EvaluableType
|
||||
import com.yandex.div.evaluable.FunctionArgument
|
||||
import com.yandex.div.core.expression.local.LocalFunction
|
||||
import com.yandex.div2.DivEvaluableType
|
||||
import com.yandex.div2.DivFunction
|
||||
|
||||
internal fun List<DivFunction>.toLocalFunctions(): List<LocalFunction> {
|
||||
return map { divFunction ->
|
||||
val argNames = mutableListOf<String>()
|
||||
val argTypes = mutableListOf<FunctionArgument>()
|
||||
divFunction.arguments.forEach {
|
||||
argNames.add(it.name)
|
||||
argTypes.add(FunctionArgument(it.type.toEvaluableType()))
|
||||
}
|
||||
LocalFunction(
|
||||
divFunction.name,
|
||||
argTypes,
|
||||
divFunction.returnType.toEvaluableType(),
|
||||
argNames,
|
||||
divFunction.body,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DivEvaluableType.toEvaluableType() = when (this) {
|
||||
DivEvaluableType.STRING -> EvaluableType.STRING
|
||||
DivEvaluableType.INTEGER -> EvaluableType.INTEGER
|
||||
DivEvaluableType.NUMBER -> EvaluableType.NUMBER
|
||||
DivEvaluableType.BOOLEAN -> EvaluableType.BOOLEAN
|
||||
DivEvaluableType.DATETIME -> EvaluableType.DATETIME
|
||||
DivEvaluableType.COLOR -> EvaluableType.COLOR
|
||||
DivEvaluableType.URL -> EvaluableType.URL
|
||||
DivEvaluableType.DICT -> EvaluableType.DICT
|
||||
DivEvaluableType.ARRAY -> EvaluableType.ARRAY
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.view.ViewGroup
|
||||
import androidx.annotation.MainThread
|
||||
import com.yandex.div.core.annotations.Mockable
|
||||
import com.yandex.div.core.dagger.DivScope
|
||||
import com.yandex.div.core.expression.local.needLocalRuntime
|
||||
import com.yandex.div.core.expression.suppressExpressionErrors
|
||||
import com.yandex.div.core.extension.DivExtensionController
|
||||
import com.yandex.div.core.state.DivStatePath
|
||||
@@ -250,17 +251,18 @@ internal class DivBinder @Inject constructor(
|
||||
private fun getBindingContext(
|
||||
parentContext: BindingContext, div: Div, path: DivStatePath
|
||||
): BindingContext {
|
||||
return if (div.value().variableTriggers.isNullOrEmpty() && div.value().variables.isNullOrEmpty()) {
|
||||
parentContext
|
||||
} else {
|
||||
return if (div.needLocalRuntime) {
|
||||
parentContext.getFor(
|
||||
parentContext.runtimeStore?.getOrCreateRuntime(
|
||||
path = path.fullPath,
|
||||
parentResolver = parentContext.expressionResolver,
|
||||
variables = div.value().variables?.toVariables(),
|
||||
triggers = div.value().variableTriggers,
|
||||
functions = div.value().functions,
|
||||
)?.expressionResolver ?: parentContext.expressionResolver
|
||||
)
|
||||
} else {
|
||||
parentContext
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -630,12 +630,13 @@ internal fun resolveRuntime(
|
||||
resolver: ExpressionResolver,
|
||||
parentResolver: ExpressionResolver,
|
||||
) = runtimeStore?.resolveRuntimeWith(
|
||||
path = path,
|
||||
variables = div.variables?.toVariables(),
|
||||
triggers = div.variableTriggers,
|
||||
resolver = resolver,
|
||||
parentResolver = parentResolver,
|
||||
)
|
||||
path = path,
|
||||
variables = div.variables?.toVariables(),
|
||||
triggers = div.variableTriggers,
|
||||
functions = div.functions,
|
||||
resolver = resolver,
|
||||
parentResolver = parentResolver,
|
||||
)
|
||||
|
||||
internal fun DivBase.getChildPathUnit(index: Int) = id ?: ChildPathUnitCache.getValue(index)
|
||||
|
||||
|
||||
+6
-11
@@ -2,8 +2,7 @@ package com.yandex.div.internal.core
|
||||
|
||||
import com.yandex.div.core.annotations.InternalApi
|
||||
import com.yandex.div.core.expression.ExpressionResolverImpl
|
||||
import com.yandex.div.core.expression.variables.VariableSource
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div.core.expression.variables.ConstantsProvider
|
||||
import com.yandex.div.internal.util.forEach
|
||||
import com.yandex.div.internal.util.mapIndexedNotNull
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
@@ -61,15 +60,11 @@ private fun DivCollectionItemBuilder.getItemResolver(
|
||||
): ExpressionResolver? {
|
||||
val resolverImpl = resolver as? ExpressionResolverImpl ?: return resolver
|
||||
val validElement = resolverImpl.validateItemBuilderDataElement(dataElement, index) ?: return null
|
||||
val localVariableSource = VariableSource(
|
||||
mapOf(
|
||||
dataElementName to Variable.DictVariable(dataElementName, validElement),
|
||||
INDEX_VARIABLE_NAME to Variable.IntegerVariable(INDEX_VARIABLE_NAME, index.toLong())
|
||||
),
|
||||
{},
|
||||
mutableListOf()
|
||||
)
|
||||
return resolverImpl + localVariableSource
|
||||
val localDataProvider = ConstantsProvider(mapOf(
|
||||
dataElementName to validElement,
|
||||
INDEX_VARIABLE_NAME to index.toLong()
|
||||
))
|
||||
return resolverImpl + localDataProvider
|
||||
}
|
||||
|
||||
private fun Div.copy(id: String? = value().id): Div {
|
||||
|
||||
+14
-8
@@ -11,18 +11,24 @@ import com.yandex.div.evaluable.Function
|
||||
import com.yandex.div.evaluable.FunctionProvider
|
||||
import com.yandex.div.evaluable.function.GeneratedBuiltinFunctionProvider
|
||||
import com.yandex.div.evaluable.types.DateTime
|
||||
import com.yandex.div.internal.parser.*
|
||||
import com.yandex.div.internal.parser.Converter
|
||||
import com.yandex.div.internal.parser.NUMBER_TO_DOUBLE
|
||||
import com.yandex.div.internal.parser.TYPE_HELPER_BOOLEAN
|
||||
import com.yandex.div.internal.parser.TYPE_HELPER_DOUBLE
|
||||
import com.yandex.div.internal.parser.TYPE_HELPER_INT
|
||||
import com.yandex.div.internal.parser.TYPE_HELPER_STRING
|
||||
import com.yandex.div.internal.parser.TypeHelper
|
||||
import com.yandex.div.json.ParsingErrorLogger
|
||||
import com.yandex.div.json.ParsingException
|
||||
import com.yandex.div.json.expressions.Expression
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.mock
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import java.util.*
|
||||
import org.junit.Before
|
||||
import java.util.TimeZone
|
||||
|
||||
/**
|
||||
* Tests for [ExpressionResolverImpl].
|
||||
@@ -70,7 +76,7 @@ class ExpressionResolverImplTest {
|
||||
private val evaluationContext = EvaluationContext(
|
||||
variableProvider = { externalVariables.getMutableVariable(it)?.getValue() },
|
||||
storedValueProvider = mock(),
|
||||
functionProvider = GeneratedBuiltinFunctionProvider,
|
||||
functionProvider = FunctionProviderDecorator(GeneratedBuiltinFunctionProvider),
|
||||
warningSender = { _, _ -> }
|
||||
)
|
||||
|
||||
@@ -78,7 +84,7 @@ class ExpressionResolverImplTest {
|
||||
externalVariables,
|
||||
Evaluator(evaluationContext),
|
||||
mock()
|
||||
) { _, _ -> }
|
||||
) { _, _, _ -> }
|
||||
|
||||
private val withFuncGetCallback = { callback: () -> Unit ->
|
||||
ExpressionResolverImpl(
|
||||
@@ -87,7 +93,7 @@ class ExpressionResolverImplTest {
|
||||
EvaluationContext(
|
||||
variableProvider = evaluationContext.variableProvider,
|
||||
storedValueProvider = evaluationContext.storedValueProvider,
|
||||
functionProvider = object : FunctionProvider {
|
||||
functionProvider = FunctionProviderDecorator(object : FunctionProvider {
|
||||
override fun get(name: String, args: List<EvaluableType>): Function {
|
||||
callback()
|
||||
return evaluationContext.functionProvider.get(name, args)
|
||||
@@ -97,12 +103,12 @@ class ExpressionResolverImplTest {
|
||||
callback()
|
||||
return evaluationContext.functionProvider.getMethod(name, args)
|
||||
}
|
||||
},
|
||||
}),
|
||||
warningSender = evaluationContext.warningSender
|
||||
)
|
||||
),
|
||||
mock()
|
||||
) { _, _ -> }
|
||||
) { _, _, _ -> }
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
+14
-12
@@ -3,6 +3,7 @@ package com.yandex.div.core.expression.local
|
||||
import com.yandex.div.core.Div2Logger
|
||||
import com.yandex.div.core.expression.ExpressionResolverImpl
|
||||
import com.yandex.div.core.expression.ExpressionsRuntime
|
||||
import com.yandex.div.core.expression.FunctionProviderDecorator
|
||||
import com.yandex.div.core.expression.variables.VariableController
|
||||
import com.yandex.div.core.state.DivStatePath
|
||||
import com.yandex.div.core.view2.divs.DivActionBinder
|
||||
@@ -26,7 +27,7 @@ private const val PARENT_VARIABLE = "parent_variable"
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class RuntimeStoreTest {
|
||||
private val evaluationContext = EvaluationContext(mock(), mock(), mock(), mock())
|
||||
private val evaluationContext = EvaluationContext(mock(), mock(), mock<FunctionProviderDecorator>(), mock())
|
||||
private val evaluator = mock<Evaluator> {
|
||||
on { evaluationContext } doReturn evaluationContext
|
||||
}
|
||||
@@ -38,18 +39,19 @@ class RuntimeStoreTest {
|
||||
private val underTest = RuntimeStore(evaluator, errorCollector, div2Logger, divActionBinder)
|
||||
|
||||
private var runtimeFromCallback: ExpressionsRuntime? = null
|
||||
private val callback = ExpressionResolverImpl.OnCreateCallback { resolver, variableController ->
|
||||
private val callback = ExpressionResolverImpl.OnCreateCallback { resolver, variableController, functionProvider ->
|
||||
runtimeFromCallback = ExpressionsRuntime(
|
||||
resolver, variableController, null, underTest
|
||||
resolver, variableController, null, functionProvider, underTest
|
||||
)
|
||||
underTest.putRuntime(runtimeFromCallback!!)
|
||||
}
|
||||
|
||||
private val resolver = ExpressionResolverImpl(mock(), evaluator, errorCollector, callback)
|
||||
private val rootVariableController: VariableController = mock<VariableController>()
|
||||
private val functionProvider = mock<FunctionProviderDecorator>()
|
||||
private val rootResolver = ExpressionResolverImpl(rootVariableController, evaluator, errorCollector, callback)
|
||||
private val rootRuntime: ExpressionsRuntime =
|
||||
ExpressionsRuntime(rootResolver, rootVariableController, null, underTest)
|
||||
ExpressionsRuntime(rootResolver, rootVariableController, null, functionProvider, underTest)
|
||||
|
||||
@Before
|
||||
fun putRootResolver() {
|
||||
@@ -63,8 +65,8 @@ class RuntimeStoreTest {
|
||||
|
||||
@Test
|
||||
fun `setPathToRuntimeWith links path to created runtime`() {
|
||||
val newResolver = ExpressionResolverImpl(mock(), mock(), errorCollector, callback)
|
||||
underTest.resolveRuntimeWith(path.fullPath, null, null, newResolver, newResolver)
|
||||
val newResolver = ExpressionResolverImpl(mock(), evaluator, errorCollector, callback)
|
||||
underTest.resolveRuntimeWith(path.fullPath, null, null, null, newResolver, newResolver)
|
||||
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(newResolver))
|
||||
Assert.assertEquals(
|
||||
@@ -76,7 +78,7 @@ class RuntimeStoreTest {
|
||||
@Test
|
||||
fun `setPathToRuntimeWith creates runtime with new variables if variables provided`() {
|
||||
val variables = listOf(Variable.IntegerVariable(CHILD_VARIABLE, 123))
|
||||
underTest.resolveRuntimeWith(path.fullPath, variables, null, resolver, resolver)
|
||||
underTest.resolveRuntimeWith(path.fullPath, variables, null, null, resolver, resolver)
|
||||
|
||||
val runtime = underTest.getOrCreateRuntime(path.fullPath, null)
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(resolver))
|
||||
@@ -89,7 +91,7 @@ class RuntimeStoreTest {
|
||||
@Test
|
||||
fun `getOrCreateRuntime returns runtime for path if exist`() {
|
||||
val resolver = ExpressionResolverImpl(mock(), evaluator, errorCollector, callback)
|
||||
val runtime = ExpressionsRuntime(resolver, mock(), null, underTest)
|
||||
val runtime = ExpressionsRuntime(resolver, mock(), null, functionProvider, underTest)
|
||||
underTest.putRuntime(runtime, PATH, rootRuntime)
|
||||
|
||||
Assert.assertEquals(runtime, underTest.getOrCreateRuntime(path.fullPath, null, null))
|
||||
@@ -101,7 +103,7 @@ class RuntimeStoreTest {
|
||||
fun `getOrCreateRuntime returns parent runtime for path if no variables provided`() {
|
||||
val resolver = ExpressionResolverImpl(mock(), evaluator, errorCollector, callback)
|
||||
val parentVariableController = mock<VariableController>()
|
||||
val runtime = ExpressionsRuntime(resolver, parentVariableController, null, underTest)
|
||||
val runtime = ExpressionsRuntime(resolver, parentVariableController, null, functionProvider, underTest)
|
||||
underTest.putRuntime(runtime, PARENT_PATH, rootRuntime)
|
||||
|
||||
Assert.assertEquals(runtime, underTest.getOrCreateRuntime(path.fullPath, parentResolver = resolver))
|
||||
@@ -115,7 +117,7 @@ class RuntimeStoreTest {
|
||||
val parentVariableController = mock<VariableController> {
|
||||
on { getMutableVariable(PARENT_VARIABLE) } doReturn Variable.StringVariable(PARENT_VARIABLE, "123")
|
||||
}
|
||||
val runtime = ExpressionsRuntime(resolver, parentVariableController, null, underTest)
|
||||
val runtime = ExpressionsRuntime(resolver, parentVariableController, null, functionProvider, underTest)
|
||||
|
||||
underTest.putRuntime(runtime, PARENT_PATH, rootRuntime)
|
||||
|
||||
@@ -143,7 +145,7 @@ class RuntimeStoreTest {
|
||||
@Test
|
||||
fun `setPathToRuntimeWith links path to runtime`() {
|
||||
val resolver = ExpressionResolverImpl(mock(), evaluator, errorCollector, callback)
|
||||
underTest.resolveRuntimeWith(path.fullPath, null, null, resolver, resolver)
|
||||
underTest.resolveRuntimeWith(path.fullPath, null, null, null, resolver, resolver)
|
||||
|
||||
Assert.assertNotNull(runtimeFromCallback)
|
||||
Assert.assertEquals(
|
||||
@@ -166,7 +168,7 @@ class RuntimeStoreTest {
|
||||
parentVariableController, evaluator, errorCollector, callback
|
||||
)
|
||||
|
||||
underTest.resolveRuntimeWith(path.fullPath, variables, null, resolver, resolver)
|
||||
underTest.resolveRuntimeWith(path.fullPath, variables, null, null, resolver, resolver)
|
||||
val newRuntime = underTest.getOrCreateRuntime(path.fullPath, null, null)
|
||||
|
||||
Assert.assertNotNull(newRuntime)
|
||||
|
||||
+9
-2
@@ -3,6 +3,7 @@ package com.yandex.div.core.expression.variables
|
||||
import com.yandex.div.core.expression.ExpressionResolverImpl
|
||||
import com.yandex.div.core.expression.ExpressionsRuntime
|
||||
import com.yandex.div.core.expression.ExpressionsRuntimeProvider
|
||||
import com.yandex.div.core.expression.FunctionProviderDecorator
|
||||
import com.yandex.div.core.expression.local.RuntimeStore
|
||||
import com.yandex.div.core.state.DivStatePath
|
||||
import com.yandex.div.core.view2.BindingContext
|
||||
@@ -10,6 +11,8 @@ import com.yandex.div.core.view2.Div2View
|
||||
import com.yandex.div.core.view2.errors.ErrorCollector
|
||||
import com.yandex.div.core.view2.errors.ErrorCollectors
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div.evaluable.EvaluationContext
|
||||
import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div2.DivData
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
@@ -41,8 +44,12 @@ class TwoWayVariableBinderTest {
|
||||
}
|
||||
private val path = DivStatePath(0)
|
||||
private val store = RuntimeStore(mock(), mock(), mock(), mock())
|
||||
private val expressionResolver = ExpressionResolverImpl(mock(), mock(), mock(), mock())
|
||||
private val expressionsRuntime = ExpressionsRuntime(expressionResolver, variableController, mock(), store)
|
||||
private val evaluationContext = EvaluationContext(mock(), mock(), mock<FunctionProviderDecorator>(), mock())
|
||||
private val evaluator = mock<Evaluator> {
|
||||
on { evaluationContext } doReturn evaluationContext
|
||||
}
|
||||
private val expressionResolver = ExpressionResolverImpl(mock(), evaluator, mock(), mock())
|
||||
private val expressionsRuntime = ExpressionsRuntime(expressionResolver, variableController, mock(), mock(), store)
|
||||
private val expressionsRuntimeProvider = mock<ExpressionsRuntimeProvider> {
|
||||
on { getOrCreate(any(), any(), any()) } doReturn expressionsRuntime
|
||||
}
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ class LocalVariablesTest {
|
||||
|
||||
private fun setVariable(name: String, value: String, path: String) {
|
||||
val variableController = div2View.expressionsRuntime
|
||||
?.runtimeStore?.getOrCreateRuntime(path, null, null, null)?.variableController
|
||||
?.runtimeStore?.getOrCreateRuntime(path, null, null, null, null)?.variableController
|
||||
val variable = variableController?.getMutableVariable(name) ?: return
|
||||
variable.set(value)
|
||||
}
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
},
|
||||
"$description": "translations.json#/div_base_functions",
|
||||
"platforms": [
|
||||
"android",
|
||||
"ios"
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user