@cloudpss/expression 0.6.0-alpha.1 → 0.6.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyze.d.ts +6 -3
- package/dist/analyze.d.ts.map +1 -1
- package/dist/analyze.js +67 -33
- package/dist/analyze.js.map +1 -1
- package/dist/definitions/argument.d.ts +2 -10
- package/dist/definitions/argument.d.ts.map +1 -1
- package/dist/definitions/constraint.d.ts +2 -2
- package/dist/definitions/constraint.d.ts.map +1 -1
- package/dist/definitions/constraint.js +1 -1
- package/dist/definitions/constraint.js.map +1 -1
- package/dist/definitions/parameter-decoration.d.ts +3 -3
- package/dist/definitions/parameter-decoration.d.ts.map +1 -1
- package/dist/definitions/parameter-decoration.js +0 -7
- package/dist/definitions/parameter-decoration.js.map +1 -1
- package/dist/definitions/parameter-group.d.ts +0 -4
- package/dist/definitions/parameter-group.d.ts.map +1 -1
- package/dist/definitions/parameter-group.js +5 -17
- package/dist/definitions/parameter-group.js.map +1 -1
- package/dist/definitions/parameter.d.ts +47 -40
- package/dist/definitions/parameter.d.ts.map +1 -1
- package/dist/definitions/parameter.js +9 -21
- package/dist/definitions/parameter.js.map +1 -1
- package/dist/definitions/utils.d.ts +19 -0
- package/dist/definitions/utils.d.ts.map +1 -0
- package/dist/definitions/utils.js +177 -0
- package/dist/definitions/utils.js.map +1 -0
- package/dist/definitions/variable.d.ts +0 -2
- package/dist/definitions/variable.d.ts.map +1 -1
- package/dist/definitions/variable.js +1 -5
- package/dist/definitions/variable.js.map +1 -1
- package/dist/definitions.d.ts +1 -0
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +1 -0
- package/dist/definitions.js.map +1 -1
- package/dist/eval.d.ts +3 -5
- package/dist/eval.d.ts.map +1 -1
- package/dist/eval.js +12 -20
- package/dist/eval.js.map +1 -1
- package/dist/expression.d.ts +10 -4
- package/dist/expression.d.ts.map +1 -1
- package/dist/expression.js +4 -4
- package/dist/expression.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interface.d.ts +30 -0
- package/dist/interface.d.ts.map +1 -0
- package/dist/interface.js +6 -0
- package/dist/interface.js.map +1 -0
- package/dist/main.d.ts +41 -28
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +145 -141
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +3 -2
- package/dist/migrate.d.ts.map +1 -1
- package/dist/migrate.js +25 -3
- package/dist/migrate.js.map +1 -1
- package/dist/migrator/access.d.ts.map +1 -1
- package/dist/migrator/access.js +44 -24
- package/dist/migrator/access.js.map +1 -1
- package/dist/migrator/call.d.ts.map +1 -1
- package/dist/migrator/call.js +254 -217
- package/dist/migrator/call.js.map +1 -1
- package/dist/migrator/concat.d.ts.map +1 -1
- package/dist/migrator/concat.js +15 -2
- package/dist/migrator/concat.js.map +1 -1
- package/dist/migrator/interface.d.ts +3 -1
- package/dist/migrator/interface.d.ts.map +1 -1
- package/dist/migrator/interface.js.map +1 -1
- package/dist/migrator/node.js +1 -1
- package/dist/migrator/node.js.map +1 -1
- package/dist/migrator/operator.d.ts.map +1 -1
- package/dist/migrator/operator.js +43 -29
- package/dist/migrator/operator.js.map +1 -1
- package/dist/migrator/state.d.ts +2 -2
- package/dist/migrator/state.d.ts.map +1 -1
- package/dist/migrator/state.js +1 -2
- package/dist/migrator/state.js.map +1 -1
- package/dist/migrator/symbol.d.ts.map +1 -1
- package/dist/migrator/symbol.js +13 -0
- package/dist/migrator/symbol.js.map +1 -1
- package/dist/migrator/to-type.d.ts.map +1 -1
- package/dist/migrator/to-type.js +20 -3
- package/dist/migrator/to-type.js.map +1 -1
- package/dist/migrator/utils.d.ts +4 -0
- package/dist/migrator/utils.d.ts.map +1 -1
- package/dist/migrator/utils.js +25 -0
- package/dist/migrator/utils.js.map +1 -1
- package/dist/parser.d.ts +2 -2
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +25 -8
- package/dist/parser.js.map +1 -1
- package/dist/re-exports.d.ts +4 -0
- package/dist/re-exports.d.ts.map +1 -0
- package/dist/re-exports.js +3 -0
- package/dist/re-exports.js.map +1 -0
- package/dist/scope.d.ts +13 -16
- package/dist/scope.d.ts.map +1 -1
- package/dist/scope.js +56 -49
- package/dist/scope.js.map +1 -1
- package/dist/type.d.ts +14 -5
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +35 -11
- package/dist/type.js.map +1 -1
- package/package.json +7 -4
- package/src/analyze.ts +77 -37
- package/src/definitions/argument.ts +2 -12
- package/src/definitions/constraint.ts +3 -3
- package/src/definitions/parameter-decoration.ts +3 -9
- package/src/definitions/parameter-group.ts +4 -19
- package/src/definitions/parameter.ts +62 -61
- package/src/definitions/utils.ts +175 -0
- package/src/definitions/variable.ts +1 -6
- package/src/definitions.ts +1 -0
- package/src/eval.ts +13 -26
- package/src/expression.ts +14 -6
- package/src/index.ts +3 -1
- package/src/interface.ts +35 -0
- package/src/main.ts +213 -194
- package/src/migrate.ts +30 -6
- package/src/migrator/access.ts +49 -32
- package/src/migrator/call.ts +246 -203
- package/src/migrator/concat.ts +15 -2
- package/src/migrator/interface.ts +3 -1
- package/src/migrator/node.ts +1 -1
- package/src/migrator/operator.ts +47 -33
- package/src/migrator/state.ts +2 -2
- package/src/migrator/symbol.ts +13 -0
- package/src/migrator/to-type.ts +22 -3
- package/src/migrator/utils.ts +29 -0
- package/src/parser.ts +27 -8
- package/src/re-exports.ts +28 -0
- package/src/scope.ts +75 -61
- package/src/type.ts +32 -11
- package/tests/analyze.ts +40 -6
- package/tests/compile.ts +65 -0
- package/tests/condition.ts +13 -5
- package/tests/definition.ts +205 -18
- package/tests/eval-complex.ts +7 -10
- package/tests/eval.ts +59 -12
- package/tests/import.ts +18 -4
- package/tests/main.ts +9 -0
- package/tests/migrate.ts +202 -0
- package/tests/scope.ts +3 -3
- package/tests/template.ts +36 -0
- package/dist/context.d.ts +0 -41
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -18
- package/dist/context.js.map +0 -1
- package/jest.config.js +0 -3
- package/src/context.ts +0 -54
- package/tests/tsconfig.json +0 -3
- package/tsconfig.json +0 -3
package/dist/type.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { lib } from '@mirascript/mirascript/subtle';
|
|
2
|
+
const { to_string, to_number, to_boolean } = lib;
|
|
2
3
|
const x = 'boolean';
|
|
3
4
|
x;
|
|
4
5
|
/** 类型信息 */
|
|
5
|
-
export
|
|
6
|
-
|
|
6
|
+
export var TypeInfo;
|
|
7
|
+
(function (TypeInfo) {
|
|
8
|
+
/** 解析类型 */
|
|
9
|
+
function parse(type) {
|
|
7
10
|
if (type === 's' || type === 'string')
|
|
8
11
|
return 'string';
|
|
9
12
|
if (type === 'f' || type === 'number')
|
|
@@ -11,8 +14,10 @@ export const TypeInfo = {
|
|
|
11
14
|
if (type === 'b' || type === 'boolean')
|
|
12
15
|
return 'boolean';
|
|
13
16
|
throw new TypeError(`Invalid type '${String(type)}'`);
|
|
14
|
-
}
|
|
15
|
-
|
|
17
|
+
}
|
|
18
|
+
TypeInfo.parse = parse;
|
|
19
|
+
/** 判断类型 */
|
|
20
|
+
function is(value, type) {
|
|
16
21
|
switch (type) {
|
|
17
22
|
case 'b':
|
|
18
23
|
case 'boolean':
|
|
@@ -27,24 +32,43 @@ export const TypeInfo = {
|
|
|
27
32
|
(type);
|
|
28
33
|
return false;
|
|
29
34
|
}
|
|
30
|
-
}
|
|
31
|
-
|
|
35
|
+
}
|
|
36
|
+
TypeInfo.is = is;
|
|
37
|
+
/** 转换类型 */
|
|
38
|
+
function to(value, type) {
|
|
39
|
+
value ??= null;
|
|
32
40
|
if (!type)
|
|
33
41
|
return value;
|
|
34
42
|
switch (type) {
|
|
35
43
|
case 'b':
|
|
36
44
|
case 'boolean':
|
|
37
|
-
return
|
|
45
|
+
return toBoolean(value);
|
|
38
46
|
case 'f':
|
|
39
47
|
case 'number':
|
|
40
|
-
return
|
|
48
|
+
return toNumber(value);
|
|
41
49
|
case 's':
|
|
42
50
|
case 'string':
|
|
43
|
-
return
|
|
51
|
+
return toString(value);
|
|
44
52
|
default:
|
|
45
53
|
(type);
|
|
46
54
|
return value;
|
|
47
55
|
}
|
|
48
|
-
}
|
|
49
|
-
|
|
56
|
+
}
|
|
57
|
+
TypeInfo.to = to;
|
|
58
|
+
/** 转换为字符串 */
|
|
59
|
+
function toString(value) {
|
|
60
|
+
return to_string(value ?? null);
|
|
61
|
+
}
|
|
62
|
+
TypeInfo.toString = toString;
|
|
63
|
+
/** 转换为数字 */
|
|
64
|
+
function toNumber(value) {
|
|
65
|
+
return to_number(value ?? null);
|
|
66
|
+
}
|
|
67
|
+
TypeInfo.toNumber = toNumber;
|
|
68
|
+
/** 转换为布尔值 */
|
|
69
|
+
function toBoolean(value) {
|
|
70
|
+
return to_boolean(value ?? null);
|
|
71
|
+
}
|
|
72
|
+
TypeInfo.toBoolean = toBoolean;
|
|
73
|
+
})(TypeInfo || (TypeInfo = {}));
|
|
50
74
|
//# sourceMappingURL=type.js.map
|
package/dist/type.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.js","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"type.js","sourceRoot":"","sources":["../src/type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAC;AACpD,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC;AAKjD,MAAM,CAAC,GAAa,SAAS,CAAC;AAC9B,CAAoB,CAAC;AAerB,WAAW;AACX,MAAM,KAAW,QAAQ,CA8DxB;AA9DD,WAAiB,QAAQ;IACrB,WAAW;IACX,SAAgB,KAAK,CAAC,IAA2B;QAC7C,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACvD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACvD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACzD,MAAM,IAAI,SAAS,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IALe,cAAK,QAKpB,CAAA;IACD,WAAW;IACX,SAAgB,EAAE,CAAkC,KAA0B,EAAE,IAAO;QACnF,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,GAAG,CAAC;YACT,KAAK,SAAS;gBACV,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC;YACtC,KAAK,GAAG,CAAC;YACT,KAAK,QAAQ;gBACT,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;YACrC,KAAK,GAAG,CAAC;YACT,KAAK,QAAQ;gBACT,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;YACrC;gBACI,CAAC,IAAI,CAAiB,CAAC;gBACvB,OAAO,KAAK,CAAC;QACrB,CAAC;IACL,CAAC;IAfe,WAAE,KAejB,CAAA;IAED,WAAW;IACX,SAAgB,EAAE,CAAkC,KAA0B,EAAE,IAAO;QAGnF,KAAK,KAAK,IAAI,CAAC;QACf,IAAI,CAAC,IAAI;YAAE,OAAO,KAAU,CAAC;QAC7B,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,GAAG,CAAC;YACT,KAAK,SAAS;gBACV,OAAO,SAAS,CAAC,KAAK,CAAM,CAAC;YACjC,KAAK,GAAG,CAAC;YACT,KAAK,QAAQ;gBACT,OAAO,QAAQ,CAAC,KAAK,CAAM,CAAC;YAChC,KAAK,GAAG,CAAC;YACT,KAAK,QAAQ;gBACT,OAAO,QAAQ,CAAC,KAAK,CAAM,CAAC;YAChC;gBACI,CAAC,IAAI,CAAiB,CAAC;gBACvB,OAAO,KAAU,CAAC;QAC1B,CAAC;IACL,CAAC;IAnBe,WAAE,KAmBjB,CAAA;IAED,aAAa;IACb,SAAgB,QAAQ,CAAC,KAA0B;QAC/C,OAAO,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IAFe,iBAAQ,WAEvB,CAAA;IAED,YAAY;IACZ,SAAgB,QAAQ,CAAC,KAA0B;QAC/C,OAAO,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IAFe,iBAAQ,WAEvB,CAAA;IAED,aAAa;IACb,SAAgB,SAAS,CAAC,KAA0B;QAChD,OAAO,UAAU,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IACrC,CAAC;IAFe,kBAAS,YAExB,CAAA;AACL,CAAC,EA9DgB,QAAQ,KAAR,QAAQ,QA8DxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudpss/expression",
|
|
3
|
-
"version": "0.6.0-alpha.
|
|
3
|
+
"version": "0.6.0-alpha.11",
|
|
4
4
|
"author": "CloudPSS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
"./*": "./dist/*.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@mirascript/mirascript": "^0.
|
|
15
|
+
"@mirascript/mirascript": "^0.1.9",
|
|
16
16
|
"klona": "^2.0.6",
|
|
17
17
|
"lru-cache": "^11.2.2",
|
|
18
|
-
"mathjs": "^
|
|
19
|
-
"type-fest": "^5.0
|
|
18
|
+
"mathjs": "^15.1.0",
|
|
19
|
+
"type-fest": "^5.2.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"dedent": "^1.7.0"
|
|
20
23
|
},
|
|
21
24
|
"scripts": {
|
|
22
25
|
"build": "pnpm clean && tsc --build --force",
|
package/src/analyze.ts
CHANGED
|
@@ -1,44 +1,84 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
parseDiagnostics,
|
|
3
|
+
generateBytecodeSync,
|
|
4
|
+
DiagnosticCode,
|
|
5
|
+
DefaultVmContext,
|
|
6
|
+
} from '@mirascript/mirascript/subtle';
|
|
7
|
+
import type { TranspileOptions } from '@mirascript/mirascript';
|
|
8
|
+
import type { EvalExpressionCache } from './parser.js';
|
|
9
|
+
import type { Scope } from './scope.js';
|
|
10
|
+
import type { Evaluator } from './main.js';
|
|
11
|
+
|
|
12
|
+
/** 一个访问链,第一个元素为变量名称 */
|
|
13
|
+
export type AccessChain = readonly [string, ...ReadonlyArray<string | number>];
|
|
14
|
+
|
|
15
|
+
const config: TranspileOptions = Object.freeze({
|
|
16
|
+
input_mode: 'Script',
|
|
17
|
+
diagnostic_position_encoding: 'Utf16',
|
|
18
|
+
diagnostic_error: false,
|
|
19
|
+
diagnostic_warning: false,
|
|
20
|
+
diagnostic_info: false,
|
|
21
|
+
diagnostic_hint: false,
|
|
22
|
+
diagnostic_reference: false,
|
|
23
|
+
diagnostic_tag: true,
|
|
24
|
+
trivia: false,
|
|
25
|
+
} satisfies TranspileOptions);
|
|
3
26
|
|
|
4
27
|
/**
|
|
5
28
|
* 分析依赖
|
|
6
29
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
function analyzeImpl(expression: string): readonly AccessChain[] {
|
|
31
|
+
if (expression.trim() === '') {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
const [code, diagnostics] = generateBytecodeSync(expression, config);
|
|
35
|
+
if (code == null || diagnostics.length === 0) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const parsedDiagnostics = parseDiagnostics(expression, diagnostics);
|
|
39
|
+
const globals = parsedDiagnostics.tags.filter((t) => t.code === DiagnosticCode.GlobalVariable);
|
|
40
|
+
if (globals.length === 0) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const lines = expression.split(/\r?\n/);
|
|
44
|
+
const result = new Set<string>();
|
|
45
|
+
for (const global of globals) {
|
|
46
|
+
// 分析每个全局变量访问
|
|
47
|
+
const line = lines[global.range.startLineNumber - 1];
|
|
48
|
+
if (!line) continue;
|
|
49
|
+
const access = line.slice(global.range.startColumn - 1);
|
|
50
|
+
const chain =
|
|
51
|
+
/^((?:@+|\$+|[a-zA-Z_])[a-zA-Z0-9_]*)(?:\s*!?\.\s*(?:\d+|(?:@+|\$+|[a-zA-Z_])[a-zA-Z0-9_]*))*/.exec(access);
|
|
52
|
+
if (chain == null) continue;
|
|
53
|
+
const globalName = chain[1];
|
|
54
|
+
if (globalName?.length !== global.range.endColumn - global.range.startColumn) continue;
|
|
55
|
+
const chainStr = chain[0].split(/\s*!?\.\s*/).join('.');
|
|
56
|
+
result.add(chainStr);
|
|
57
|
+
}
|
|
58
|
+
const accessChains: AccessChain[] = [];
|
|
59
|
+
for (const chainStr of result) {
|
|
60
|
+
const parts = chainStr.split('.').map((part) => {
|
|
61
|
+
const num = Number.parseInt(part, 10);
|
|
62
|
+
return Number.isNaN(num) ? part : num;
|
|
63
|
+
});
|
|
64
|
+
accessChains.push(parts as unknown as AccessChain);
|
|
65
|
+
}
|
|
66
|
+
return accessChains;
|
|
67
|
+
}
|
|
30
68
|
|
|
31
|
-
|
|
32
|
-
// }
|
|
33
|
-
// return undefined;
|
|
34
|
-
// };
|
|
69
|
+
const kAnalyze = Symbol('cloudpss.expression.analyzeCache');
|
|
35
70
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
71
|
+
/**
|
|
72
|
+
* 分析依赖
|
|
73
|
+
*/
|
|
74
|
+
export function analyze(expression: EvalExpressionCache, evaluator: Evaluator, scope: Scope): readonly AccessChain[] {
|
|
75
|
+
let result = (expression as EvalExpressionCache & { [kAnalyze]?: readonly AccessChain[] })[kAnalyze];
|
|
76
|
+
if (result == null) {
|
|
77
|
+
result = analyzeImpl(expression.source);
|
|
78
|
+
(expression as EvalExpressionCache & { [kAnalyze]?: readonly AccessChain[] })[kAnalyze] = result;
|
|
79
|
+
}
|
|
80
|
+
return result.filter(([global]) => {
|
|
81
|
+
if (scope.has(global)) return true;
|
|
82
|
+
return !(evaluator.imported.has(global) || DefaultVmContext.has(global));
|
|
83
|
+
});
|
|
44
84
|
}
|
|
@@ -6,7 +6,7 @@ import type { Evaluator } from '../main.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* 表示一个具有类似表达式功能的 JS 函数,与某个 {@link ArgumentValue} 相关联,在其之后求值
|
|
8
8
|
*/
|
|
9
|
-
export type
|
|
9
|
+
export type ArgumentFunction<out R, in V extends VmValue = ArgumentValue> = (
|
|
10
10
|
/** 相关联的参数值 */
|
|
11
11
|
value: V,
|
|
12
12
|
/** 当前作用域 */
|
|
@@ -15,21 +15,11 @@ export type ExpressionFunction<R, V extends VmValue = ArgumentValue> = (
|
|
|
15
15
|
evaluator: Evaluator,
|
|
16
16
|
) => R;
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* 表示一个具有类似表达式功能的 JS 函数,与某个 {@link ArgumentValue} 相关联,在其之前求值
|
|
20
|
-
*/
|
|
21
|
-
export type ParameterFunction<R> = (
|
|
22
|
-
/** 当前作用域 */
|
|
23
|
-
scope: Scope,
|
|
24
|
-
/** 当前求值器 */
|
|
25
|
-
evaluator: Evaluator,
|
|
26
|
-
) => R;
|
|
27
|
-
|
|
28
18
|
/** 条件表达式 */
|
|
29
19
|
export type ConditionExpression = boolean | ExpressionSource<boolean>;
|
|
30
20
|
|
|
31
21
|
/** 条件函数 */
|
|
32
|
-
export type ConditionFunction<V extends VmValue = ArgumentValue> =
|
|
22
|
+
export type ConditionFunction<in V extends VmValue = ArgumentValue> = ArgumentFunction<boolean, V>;
|
|
33
23
|
|
|
34
24
|
/** 参数值 */
|
|
35
25
|
export type ArgumentValue = NonNullable<VmConst>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VmRecord, VmValue } from '@mirascript/mirascript';
|
|
2
|
-
import type { ArgumentValue, ConditionExpression, ConditionFunction,
|
|
2
|
+
import type { ArgumentValue, ConditionExpression, ConditionFunction, ArgumentFunction } from './argument.js';
|
|
3
3
|
import type { ExpressionSource } from '../expression.js';
|
|
4
4
|
|
|
5
5
|
export const ConstraintLevel = Object.freeze(['info', 'warning', 'error'] as const);
|
|
@@ -23,7 +23,7 @@ export interface Constraint<V extends VmValue = ArgumentValue> {
|
|
|
23
23
|
/**
|
|
24
24
|
* 不满足条件的提示附加参数
|
|
25
25
|
*/
|
|
26
|
-
messageData?: ExpressionSource<VmRecord> | VmRecord |
|
|
26
|
+
messageData?: ExpressionSource<VmRecord> | VmRecord | ArgumentFunction<VmRecord, V>;
|
|
27
27
|
/**
|
|
28
28
|
* 约束条件
|
|
29
29
|
*/
|
|
@@ -33,7 +33,7 @@ export interface Constraint<V extends VmValue = ArgumentValue> {
|
|
|
33
33
|
/** 检查是否为 Constraint */
|
|
34
34
|
export function isConstraint(value: unknown): value is Constraint {
|
|
35
35
|
if (value == null || typeof value !== 'object') return false;
|
|
36
|
-
if ('key' in value || 'description' in value) return false;
|
|
36
|
+
if ('key' in value || 'name' in value || 'description' in value || 'items' in value) return false;
|
|
37
37
|
|
|
38
38
|
const v = value as Constraint;
|
|
39
39
|
if (typeof v.message != 'string') return false;
|
|
@@ -22,8 +22,10 @@ export interface ParameterDecorationMap {
|
|
|
22
22
|
label: ParameterLabelDecoration;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/** 参数界面装饰 type */
|
|
26
|
+
export type ParameterDecorationType = keyof ParameterDecorationMap;
|
|
25
27
|
/** 参数界面装饰 */
|
|
26
|
-
export type ParameterDecoration = ParameterDecorationMap[
|
|
28
|
+
export type ParameterDecoration = ParameterDecorationMap[ParameterDecorationType];
|
|
27
29
|
|
|
28
30
|
/** 是否为参数界面装饰 */
|
|
29
31
|
export function isParameterDecoration(value: unknown): value is ParameterDecoration {
|
|
@@ -32,11 +34,3 @@ export function isParameterDecoration(value: unknown): value is ParameterDecorat
|
|
|
32
34
|
if ('key' in v || 'name' in v || 'description' in v) return false;
|
|
33
35
|
return typeof v.type == 'string' && v.type.length > 0;
|
|
34
36
|
}
|
|
35
|
-
|
|
36
|
-
/** 创建参数界面装饰 */
|
|
37
|
-
export function ParameterDecoration(): ParameterLabelDecoration {
|
|
38
|
-
return {
|
|
39
|
-
type: 'label',
|
|
40
|
-
label: '',
|
|
41
|
-
};
|
|
42
|
-
}
|
|
@@ -16,18 +16,11 @@ export interface ParameterDecorationGroup extends ParameterGroupBase {
|
|
|
16
16
|
items: ParameterDecoration[];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/** 创建装饰分组 */
|
|
20
|
-
export function ParameterDecorationGroup(): ParameterDecorationGroup {
|
|
21
|
-
return {
|
|
22
|
-
items: [],
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
19
|
/** 判断是否为装饰分组 */
|
|
27
20
|
export function isParameterDecorationGroup(value: unknown): value is ParameterDecorationGroup {
|
|
28
21
|
if (value == null || typeof value !== 'object') return false;
|
|
29
22
|
const v = value as ParameterDecorationGroup;
|
|
30
|
-
if ('key' in v || 'name' in v || 'description' in v) return false;
|
|
23
|
+
if ('key' in v || 'name' in v || 'description' in v || 'value' in v) return false;
|
|
31
24
|
return Array.isArray(v.items);
|
|
32
25
|
}
|
|
33
26
|
|
|
@@ -45,18 +38,10 @@ export interface ParameterGroup extends ParameterGroupBase {
|
|
|
45
38
|
after?: ParameterDecorationGroup;
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
/** 创建参数分组 */
|
|
49
|
-
export function ParameterGroup(): ParameterGroup {
|
|
50
|
-
return {
|
|
51
|
-
name: '',
|
|
52
|
-
description: '',
|
|
53
|
-
items: [],
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
41
|
/** 判断是否为参数分组 */
|
|
58
42
|
export function isParameterGroup(item: unknown): item is ParameterGroup {
|
|
59
43
|
if (item == null || typeof item !== 'object') return false;
|
|
60
|
-
const
|
|
61
|
-
|
|
44
|
+
const v = item as ParameterGroup;
|
|
45
|
+
if ('key' in v || 'value' in v) return false;
|
|
46
|
+
return typeof v.name === 'string' && typeof v.description === 'string' && Array.isArray(v.items);
|
|
62
47
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { VmPrimitive, VmRecord } from '@mirascript/mirascript';
|
|
2
|
-
import type { ExpressionOrValue } from '../expression.js';
|
|
3
|
-
import type { ArgumentMap, ArgumentValue, ConditionExpression
|
|
2
|
+
import type { ExpressionFunction, ExpressionOrValue } from '../expression.js';
|
|
3
|
+
import type { ArgumentMap, ArgumentValue, ConditionExpression } from './argument.js';
|
|
4
4
|
import type { Constraint } from './constraint.js';
|
|
5
5
|
import type { ParameterDecoration } from './parameter-decoration.js';
|
|
6
6
|
import type { ParameterGroup } from './parameter-group.js';
|
|
@@ -65,13 +65,10 @@ export interface IntegerParameter extends NumericParameter<'integer'> {}
|
|
|
65
65
|
/** 可用于选项的值 */
|
|
66
66
|
export type ChoiceArgumentValue = NonNullable<VmPrimitive>;
|
|
67
67
|
|
|
68
|
-
/** 表示一个选项 Key,当其值为数字时,默认值为其在数组中的索引 */
|
|
69
|
-
type ChoiceKey<V extends ChoiceArgumentValue> = V extends number ? number | null : V;
|
|
70
|
-
|
|
71
68
|
/** 表示一个选项 */
|
|
72
|
-
export type Choice<V extends ChoiceArgumentValue> = {
|
|
73
|
-
/**
|
|
74
|
-
key:
|
|
69
|
+
export type Choice<V extends ChoiceArgumentValue = ChoiceArgumentValue> = {
|
|
70
|
+
/** 选中该选项将存储的参数值,默认值为其在数组中的索引 */
|
|
71
|
+
key: V;
|
|
75
72
|
/** 选项名称 */
|
|
76
73
|
name: string;
|
|
77
74
|
/** 选项详细描述 */
|
|
@@ -81,64 +78,56 @@ export type Choice<V extends ChoiceArgumentValue> = {
|
|
|
81
78
|
};
|
|
82
79
|
|
|
83
80
|
/** 是否为选项 */
|
|
84
|
-
export function isChoice<V extends
|
|
81
|
+
export function isChoice<V extends ChoiceArgumentValue = ChoiceArgumentValue>(value: unknown): value is Choice<V> {
|
|
85
82
|
if (value == null || typeof value != 'object') return false;
|
|
86
83
|
const c = value as Choice<V>;
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
export function Choice(key: ChoiceKey<string>): Choice<string>;
|
|
95
|
-
/** 创建选项 */
|
|
96
|
-
export function Choice<V extends NonNullable<VmPrimitive> = number>(key: ChoiceKey<V>): Choice<V>;
|
|
97
|
-
/** 创建选项 */
|
|
98
|
-
export function Choice<V extends NonNullable<VmPrimitive> = number>(key: ChoiceKey<V>): Choice<V> {
|
|
99
|
-
return {
|
|
100
|
-
key: key ?? (null as never),
|
|
101
|
-
name: '',
|
|
102
|
-
description: '',
|
|
103
|
-
};
|
|
84
|
+
return (
|
|
85
|
+
typeof c.name === 'string' &&
|
|
86
|
+
typeof c.description == 'string' &&
|
|
87
|
+
!('items' in c) &&
|
|
88
|
+
!('value' in c) &&
|
|
89
|
+
!('span' in c)
|
|
90
|
+
);
|
|
104
91
|
}
|
|
105
|
-
|
|
106
92
|
/**
|
|
107
93
|
* 表示值为选择项的参数定义
|
|
108
94
|
*/
|
|
109
|
-
export interface ChoiceParameter<V extends ChoiceArgumentValue
|
|
95
|
+
export interface ChoiceParameter<V extends ChoiceArgumentValue = ChoiceArgumentValue>
|
|
96
|
+
extends ParameterBase<'choice', V> {
|
|
110
97
|
/**
|
|
111
98
|
* 可选取值及其对应的说明文本
|
|
112
99
|
*/
|
|
113
|
-
choices: ExpressionOrValue<Array<Choice<V>>> |
|
|
100
|
+
choices: ExpressionOrValue<Array<Choice<V>>> | ExpressionFunction<ReadonlyArray<Choice<V>>>;
|
|
114
101
|
}
|
|
115
102
|
/**
|
|
116
103
|
* 表示值为多选选择项的参数定义
|
|
117
104
|
*/
|
|
118
|
-
export interface MultiSelectParameter<V extends readonly ChoiceArgumentValue[]>
|
|
105
|
+
export interface MultiSelectParameter<V extends readonly ChoiceArgumentValue[] = readonly ChoiceArgumentValue[]>
|
|
119
106
|
extends ParameterBase<'multiSelect', V> {
|
|
120
107
|
/**
|
|
121
108
|
* 可选取值及其对应的说明文本
|
|
122
109
|
*/
|
|
123
|
-
choices: ExpressionOrValue<Array<Choice<V[number]>>> |
|
|
110
|
+
choices: ExpressionOrValue<Array<Choice<V[number]>>> | ExpressionFunction<ReadonlyArray<Choice<V[number]>>>;
|
|
124
111
|
}
|
|
125
112
|
|
|
126
113
|
/**
|
|
127
114
|
* 表示值为布尔量的参数定义
|
|
128
115
|
*/
|
|
129
|
-
export interface LogicalParameter<V extends ChoiceArgumentValue
|
|
116
|
+
export interface LogicalParameter<V extends ChoiceArgumentValue = ChoiceArgumentValue>
|
|
117
|
+
extends ParameterBase<'logical', V> {
|
|
130
118
|
/**
|
|
131
119
|
* 可选取值及其对应的说明文本
|
|
132
120
|
*/
|
|
133
121
|
choices?:
|
|
134
122
|
| ExpressionOrValue<[false: Choice<V>, true: Choice<V>]>
|
|
135
|
-
|
|
|
123
|
+
| ExpressionFunction<readonly [false: Choice<V>, true: Choice<V>]>;
|
|
136
124
|
}
|
|
137
125
|
|
|
138
126
|
/**
|
|
139
127
|
* 表示值为表格的参数定义
|
|
140
128
|
*/
|
|
141
|
-
export interface TableParameter<V extends readonly ArgumentValue[]
|
|
129
|
+
export interface TableParameter<V extends readonly ArgumentValue[] = readonly ArgumentValue[]>
|
|
130
|
+
extends ParameterBase<'table', V> {
|
|
142
131
|
/** 最小行数 */
|
|
143
132
|
minRowCount?: number;
|
|
144
133
|
/** 最大行数 */
|
|
@@ -152,7 +141,15 @@ export interface TableParameter<V extends readonly ArgumentValue[]> extends Para
|
|
|
152
141
|
*
|
|
153
142
|
* 否则,表格参数的值为记录类型数组,每个记录包含各列定义的键值
|
|
154
143
|
*/
|
|
155
|
-
columns: Parameter[] |
|
|
144
|
+
columns: Parameter[] | ExpressionFunction<readonly Parameter[]>;
|
|
145
|
+
/** 添加额外属性以跟踪表格行 */
|
|
146
|
+
trackTag?: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** 生成用于跟踪的额外属性值 */
|
|
150
|
+
export function generateTrackId(): number {
|
|
151
|
+
// 生成 1 ~ 2^31-1 之间的随机整数
|
|
152
|
+
return Math.trunc(1 + Math.random() * 0x7fff_ffff);
|
|
156
153
|
}
|
|
157
154
|
|
|
158
155
|
/**
|
|
@@ -162,7 +159,7 @@ export interface TableParameter<V extends readonly ArgumentValue[]> extends Para
|
|
|
162
159
|
*
|
|
163
160
|
* 字段中可包含占位符,占位符在主轴上尺寸可自定义。
|
|
164
161
|
*/
|
|
165
|
-
export interface RecordParameter<V extends VmRecord> extends ParameterBase<'record', V> {
|
|
162
|
+
export interface RecordParameter<V extends VmRecord = VmRecord> extends ParameterBase<'record', V> {
|
|
166
163
|
/** 主轴的优先方向 */
|
|
167
164
|
direction?: 'row' | 'column';
|
|
168
165
|
/** 包含的元素 */
|
|
@@ -176,7 +173,7 @@ export interface RecordParameter<V extends VmRecord> extends ParameterBase<'reco
|
|
|
176
173
|
*
|
|
177
174
|
* 各分组沿主轴排列时占据位置由 span 定义。
|
|
178
175
|
*/
|
|
179
|
-
export interface GroupedParameter<V extends VmRecord> extends ParameterBase<'grouped', V> {
|
|
176
|
+
export interface GroupedParameter<V extends VmRecord = VmRecord> extends ParameterBase<'grouped', V> {
|
|
180
177
|
/** 主轴的优先方向 */
|
|
181
178
|
direction?: 'row' | 'column';
|
|
182
179
|
/** 包含的元素 */
|
|
@@ -227,23 +224,41 @@ export interface FileParameter extends ParameterBase<'file', string> {
|
|
|
227
224
|
/**
|
|
228
225
|
* 已定义的参数类型
|
|
229
226
|
*/
|
|
230
|
-
export
|
|
227
|
+
export interface ParameterMap {
|
|
228
|
+
/** 实数参数 */
|
|
231
229
|
real: RealParameter;
|
|
230
|
+
/** 整数参数 */
|
|
232
231
|
integer: IntegerParameter;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
232
|
+
/** 选择参数 */
|
|
233
|
+
choice: ChoiceParameter;
|
|
234
|
+
/** 多选参数 */
|
|
235
|
+
multiSelect: MultiSelectParameter;
|
|
236
|
+
/** 布尔参数 */
|
|
237
|
+
logical: LogicalParameter;
|
|
238
|
+
/** 表格参数 */
|
|
239
|
+
table: TableParameter;
|
|
240
|
+
/** 文本参数 */
|
|
237
241
|
text: TextParameter;
|
|
242
|
+
/** 代码参数 */
|
|
238
243
|
code: CodeParameter;
|
|
244
|
+
/** 文件参数 */
|
|
239
245
|
file: FileParameter;
|
|
246
|
+
/** 记录参数 */
|
|
240
247
|
record: RecordParameter<VmRecord>;
|
|
248
|
+
/** 分组记录参数 */
|
|
241
249
|
grouped: GroupedParameter<VmRecord>;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** 已定义的参数类型 type */
|
|
253
|
+
export type ParameterType = keyof ParameterMap;
|
|
254
|
+
|
|
255
|
+
/** 已定义的参数类型 */
|
|
256
|
+
export type Parameter = ParameterMap[ParameterType];
|
|
257
|
+
|
|
258
|
+
/** 已定义的选择参数类型 */
|
|
259
|
+
export type ChoiceParameterType = {
|
|
260
|
+
[K in keyof ParameterMap]: ParameterMap[K] extends { choices?: infer _ } ? ParameterMap[K]['type'] : never;
|
|
261
|
+
}[keyof ParameterMap];
|
|
247
262
|
|
|
248
263
|
/**
|
|
249
264
|
* 是否为参数定义
|
|
@@ -260,17 +275,3 @@ export function isParameter(value: unknown): value is Parameter {
|
|
|
260
275
|
'value' in v
|
|
261
276
|
);
|
|
262
277
|
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* 创建参数定义
|
|
266
|
-
*/
|
|
267
|
-
export function Parameter(): RealParameter {
|
|
268
|
-
return {
|
|
269
|
-
key: '',
|
|
270
|
-
name: '',
|
|
271
|
-
description: '',
|
|
272
|
-
condition: '' as ConditionExpression,
|
|
273
|
-
type: 'real',
|
|
274
|
-
value: 0,
|
|
275
|
-
};
|
|
276
|
-
}
|