add signatures for methods.

commit_hash:9110f32bc056826a0d8207eaf0670a6d4c0849b2
This commit is contained in:
tayrinn
2024-11-25 17:46:47 +03:00
parent f6208c4b29
commit ebe00c6293
8 changed files with 568 additions and 34 deletions
+3
View File
@@ -17968,6 +17968,9 @@
"test_data/expression_test_data/methods.json":"divkit/public/test_data/expression_test_data/methods.json",
"test_data/expression_test_data/methods_array.json":"divkit/public/test_data/expression_test_data/methods_array.json",
"test_data/expression_test_data/methods_dict.json":"divkit/public/test_data/expression_test_data/methods_dict.json",
"test_data/expression_test_data/methods_signatures.json":"divkit/public/test_data/expression_test_data/methods_signatures.json",
"test_data/expression_test_data/methods_signatures_array.json":"divkit/public/test_data/expression_test_data/methods_signatures_array.json",
"test_data/expression_test_data/methods_signatures_dict.json":"divkit/public/test_data/expression_test_data/methods_signatures_dict.json",
"test_data/expression_test_data/operations_comparison_boolean.json":"divkit/public/test_data/expression_test_data/operations_comparison_boolean.json",
"test_data/expression_test_data/operations_comparison_datetime.json":"divkit/public/test_data/expression_test_data/operations_comparison_datetime.json",
"test_data/expression_test_data/operations_comparison_integer.json":"divkit/public/test_data/expression_test_data/operations_comparison_integer.json",
@@ -283,7 +283,10 @@ object BuiltinFunctionProvider : FunctionProvider {
return registry.getMethod(name, args)
}
internal fun ensureFunctionRegistered(name: String, args: List<FunctionArgument>, resultType: EvaluableType) {
registry.ensureRegistered(name, args, resultType)
internal fun ensureFunctionRegistered(name: String,
args: List<FunctionArgument>,
resultType: EvaluableType,
isMethod: Boolean,) {
registry.ensureRegistered(name, args, resultType, isMethod)
}
}
@@ -43,10 +43,17 @@ internal class FunctionRegistry : FunctionProvider {
override fun getMethod(name: String, args: List<EvaluableType>): Function = get(name, args, true)
fun ensureRegistered(name: String, args: List<FunctionArgument>, resultType: EvaluableType) {
val overloadedFunctions = knownFunctions.getOrElse(name) {
throw EvaluableException("Unknown function name: '$name'.")
fun ensureRegistered(name: String, args: List<FunctionArgument>, resultType: EvaluableType, isMethod: Boolean,) {
val overloadedFunctions = if (isMethod) {
knownMethods.getOrElse(name) {
throw EvaluableException("Unknown method name: '$name'.")
}
} else {
knownFunctions.getOrElse(name) {
throw EvaluableException("Unknown function name: '$name'.")
}
}
if (overloadedFunctions.none { it.declaredArgs == args }) {
throw EvaluableException("Function with declared args is not registered.")
}
@@ -28,7 +28,8 @@ class SignaturesMultiplatformTest(caseOrError: TestCaseOrError<SignatureTestCase
functionProvider.ensureFunctionRegistered(
signature.functionName,
signature.arguments,
signature.resultType
signature.resultType,
signature.isMethod
)
} catch (e: EvaluableException) {
throw RuntimeException("Test for signature \"$signature\" failed.", e)
@@ -40,6 +41,7 @@ class SignaturesMultiplatformTest(caseOrError: TestCaseOrError<SignatureTestCase
val functionName: String,
val arguments: List<FunctionArgument>,
val resultType: EvaluableType,
val isMethod: Boolean,
) {
override fun toString(): String {
return name
@@ -50,10 +52,10 @@ class SignaturesMultiplatformTest(caseOrError: TestCaseOrError<SignatureTestCase
private const val SIGNATURES_FILE_PATH = "expression_test_data"
private const val SIGNATURE_FIELD = "signatures"
private const val SIGNATURE_NAME_FIELD = "name"
private const val SIGNATURE_FUNCTION_NAME = "function_name"
private const val SIGNATURE_ARGUMENTS_FIELD = "arguments"
private const val SIGNATURE_RESULT_TYPE_FIELD = "result_type"
private const val SIGNATURE_IS_METHOD_FIELD = "is_method"
private const val ARGUMENT_TYPE_FIELD = "type"
private const val ARGUMENT_VARARG_FIELD = "vararg"
@@ -73,34 +75,32 @@ class SignaturesMultiplatformTest(caseOrError: TestCaseOrError<SignatureTestCase
}
private fun parseSignature(file: File, json: JSONObject): TestCaseOrError<SignatureTestCase> {
val name = try {
json.getString(SIGNATURE_NAME_FIELD)
} catch (e: JSONException) {
return TestCaseOrError(TestCaseParsingError("???", file.name, json, e))
val functionName = json.getString(SIGNATURE_FUNCTION_NAME)
val arguments = json.optJSONArray(SIGNATURE_ARGUMENTS_FIELD)?.let { array ->
val result = mutableListOf<FunctionArgument>()
for (i in 0 until array.length()) {
val argument = array.getJSONObject(i)
val type = EvaluableType.valueOf(
argument.getString(ARGUMENT_TYPE_FIELD).uppercase()
)
val vararg = argument.optBoolean(ARGUMENT_VARARG_FIELD)
result.add(FunctionArgument(type, vararg))
}
result
}
try {
return TestCaseOrError(SignatureTestCase(
name,
json.getString(SIGNATURE_FUNCTION_NAME),
json.optJSONArray(SIGNATURE_ARGUMENTS_FIELD)?.let { array ->
val result = mutableListOf<FunctionArgument>()
for (i in 0 until array.length()) {
val argument = array.getJSONObject(i)
val type = EvaluableType.valueOf(
argument.getString(ARGUMENT_TYPE_FIELD).uppercase()
)
val vararg = argument.optBoolean(ARGUMENT_VARARG_FIELD)
result.add(FunctionArgument(type, vararg))
}
result
} ?: emptyList(),
EvaluableType.valueOf(json.getString(SIGNATURE_RESULT_TYPE_FIELD).uppercase()),
))
val resultType = try {
EvaluableType.valueOf(json.getString(SIGNATURE_RESULT_TYPE_FIELD).uppercase())
} catch (e: JSONException) {
return TestCaseOrError(TestCaseParsingError(name, file.name, json, e))
return TestCaseOrError(TestCaseParsingError(functionName, file.name, json, e))
}
val isMethod = json.optBoolean(SIGNATURE_IS_METHOD_FIELD)
return TestCaseOrError(SignatureTestCase(
"$functionName(${arguments ?: ""}) $resultType",
functionName,
arguments ?: emptyList(),
resultType,
isMethod)
)
}
}
}
@@ -1,4 +1,4 @@
import { type Func, funcs } from '../../src/expressions/funcs/funcs';
import { type Func, funcs, methods } from '../../src/expressions/funcs/funcs';
import { register } from '../../src/expressions/funcs';
const path = require('path');
@@ -14,7 +14,7 @@ function runCase(item: any) {
const expectedArgs: any[] = item.arguments || [];
let func: Func | null = null;
const list = funcs.get(item.function_name);
const list = (item.is_method ? methods : funcs).get(item.function_name);
if (list) {
for (let i = 0; i < list.length; ++i) {
const candidate = list[i];
@@ -0,0 +1,123 @@
{
"signatures": [
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from string.",
"arguments": [
{
"type": "string",
"doc": "String."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string representation from number.",
"arguments": [
{
"type": "number",
"doc": "Number."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from boolean.",
"arguments": [
{
"type": "boolean",
"doc": "Boolean."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from color.",
"arguments": [
{
"type": "color",
"doc": "Color."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from url.",
"arguments": [
{
"type": "url",
"doc": "Url."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from array.",
"arguments": [
{
"type": "array",
"doc": "Array."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "toString",
"is_method": true,
"doc": "Returns a string value from dict.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
}
]
}
@@ -0,0 +1,180 @@
{
"signatures": [
{
"function_name": "getArray",
"is_method": true,
"doc": "Returns an array value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "array",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getBoolean",
"is_method": true,
"doc": "Returns a boolean value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "boolean",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getColor",
"is_method": true,
"doc": "Returns a color value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "color",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getDict",
"is_method": true,
"doc": "Returns a dict value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "dict",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getInteger",
"is_method": true,
"doc": "Returns an integer value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "integer",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getNumber",
"is_method": true,
"doc": "Returns a number value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "number",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getString",
"is_method": true,
"doc": "Returns a string value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "string",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "getUrl",
"is_method": true,
"doc": "Returns a url value from array by position.",
"arguments": [
{
"type": "array",
"doc": "Array."
},
{
"type": "integer",
"doc": "Position in array."
}
],
"result_type": "url",
"platforms": [
"ios",
"web"
]
},
{
"function_name": "isEmpty",
"is_method": true,
"doc": "The method returns boolean true if array is empty else false.",
"arguments": [
{
"type": "array",
"doc": "Array."
}
],
"result_type": "boolean",
"platforms": [
"ios",
"web"
]
}
]
}
@@ -0,0 +1,218 @@
{
"signatures": [
{
"function_name": "getArray",
"is_method": true,
"doc": "Returns an array value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "array",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getBoolean",
"is_method": true,
"doc": "Returns a boolean value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "boolean",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getColor",
"is_method": true,
"doc": "Returns a color value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "color",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getDict",
"is_method": true,
"doc": "Returns a dict value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "dict",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getInteger",
"is_method": true,
"doc": "Returns an integer value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "integer",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getNumber",
"is_method": true,
"doc": "Returns a number value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "number",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getString",
"is_method": true,
"doc": "Returns a string value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "string",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "getUrl",
"is_method": true,
"doc": "Returns a url value from dict by key.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"vararg": true,
"doc": "Path in dictionary."
}
],
"result_type": "url",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "containsKey",
"is_method": true,
"doc": "Returns true if the given key is present in the dictionary.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
},
{
"type": "string",
"doc": "Key in dictionary."
}
],
"result_type": "boolean",
"platforms": [
"android",
"ios",
"web"
]
},
{
"function_name": "isEmpty",
"is_method": true,
"doc": "The method returns boolean true if dict is empty else false.",
"arguments": [
{
"type": "dict",
"doc": "Dict."
}
],
"result_type": "boolean",
"platforms": [
"android",
"ios",
"web"
]
}
]
}