@mirascript/mirascript 0.1.42 → 0.1.44
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/{chunk-6NQMCZBG.js → chunk-CQ42UDMB.js} +148 -134
- package/dist/chunk-CQ42UDMB.js.map +6 -0
- package/dist/{chunk-GBWG7BQZ.js → chunk-VSUYGID4.js} +18 -12
- package/dist/chunk-VSUYGID4.js.map +6 -0
- package/dist/compiler/emit/constants.d.ts +3 -0
- package/dist/compiler/emit/constants.d.ts.map +1 -1
- package/dist/compiler/emit/index.d.ts +4 -1
- package/dist/compiler/emit/index.d.ts.map +1 -1
- package/dist/compiler/emit/sourcemap.d.ts +2 -1
- package/dist/compiler/emit/sourcemap.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/index.js +2 -2
- package/dist/subtle.js +2 -2
- package/dist/vm/lib/global/debug.d.ts +11 -35
- package/dist/vm/lib/global/debug.d.ts.map +1 -1
- package/dist/vm/lib/global/json.d.ts.map +1 -1
- package/dist/vm/lib/helpers.d.ts +1 -1
- package/dist/vm/lib/helpers.d.ts.map +1 -1
- package/dist/vm/lib/loader.d.ts.map +1 -1
- package/dist/vm/operations/helpers.d.ts.map +1 -1
- package/dist/vm/types/context.d.ts.map +1 -1
- package/dist/vm/types/function.d.ts +11 -7
- package/dist/vm/types/function.d.ts.map +1 -1
- package/dist/vm/types/wrapper.d.ts +0 -2
- package/dist/vm/types/wrapper.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/compiler/emit/constants.ts +3 -0
- package/src/compiler/emit/index.ts +12 -5
- package/src/compiler/emit/sourcemap.ts +4 -3
- package/src/vm/lib/global/debug.ts +77 -61
- package/src/vm/lib/global/json.ts +0 -2
- package/src/vm/lib/helpers.ts +13 -12
- package/src/vm/lib/loader.ts +4 -14
- package/src/vm/operations/helpers.ts +2 -3
- package/src/vm/types/context.ts +1 -0
- package/src/vm/types/function.ts +48 -24
- package/src/vm/types/wrapper.ts +0 -4
- package/dist/chunk-6NQMCZBG.js.map +0 -6
- package/dist/chunk-GBWG7BQZ.js.map +0 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { SourceMapGenerator } from 'source-map-js';
|
|
1
2
|
import type { IRange } from '../diagnostic.js';
|
|
2
3
|
import type { ScriptInput, TranspileOptions } from '../types.js';
|
|
3
|
-
import {
|
|
4
|
-
import { SCRIPT_PREFIX } from './constants.js';
|
|
4
|
+
import type { ScriptPrefix } from './constants.js';
|
|
5
5
|
import { toJsLiteral } from './consts.js';
|
|
6
6
|
|
|
7
7
|
const ORIGIN = `mira://MiraScript/`;
|
|
@@ -38,6 +38,7 @@ let sourceId = 1;
|
|
|
38
38
|
/** 创建源映射 */
|
|
39
39
|
export function createSourceMap(
|
|
40
40
|
source: ScriptInput | undefined,
|
|
41
|
+
scriptPrefix: ScriptPrefix,
|
|
41
42
|
sourcemaps: readonly IRange[],
|
|
42
43
|
codeLines: string[],
|
|
43
44
|
functions: readonly number[],
|
|
@@ -82,7 +83,7 @@ export function createSourceMap(
|
|
|
82
83
|
map.addMapping({
|
|
83
84
|
generated: {
|
|
84
85
|
line: SOURCE_OFFSET,
|
|
85
|
-
column:
|
|
86
|
+
column: scriptPrefix.length - 'CpEnter();'.length,
|
|
86
87
|
},
|
|
87
88
|
original: {
|
|
88
89
|
line: 1,
|
|
@@ -62,18 +62,24 @@ function buildFormatString(
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/**
|
|
66
|
-
const
|
|
65
|
+
/** 默认解析函数 */
|
|
66
|
+
const printParser: PrintOptions['parser'] = function (args) {
|
|
67
67
|
const [format, values] = buildFormatString(this, args);
|
|
68
68
|
const templates: string[] = [];
|
|
69
69
|
const formats: SerializeFormat[] = [];
|
|
70
70
|
let valIndex = 0;
|
|
71
71
|
if (format.includes('%')) {
|
|
72
72
|
const parts = format.split(/(%[%\w])/g);
|
|
73
|
+
let prevIsTemplate = true;
|
|
73
74
|
for (let i = 0; i < parts.length; i++) {
|
|
74
75
|
if (i % 2 === 0) {
|
|
75
76
|
// Regular string part
|
|
76
|
-
templates.
|
|
77
|
+
if (prevIsTemplate && templates.length) {
|
|
78
|
+
templates[templates.length - 1] += parts[i]!;
|
|
79
|
+
} else {
|
|
80
|
+
templates.push(parts[i]!);
|
|
81
|
+
}
|
|
82
|
+
prevIsTemplate = true;
|
|
77
83
|
continue;
|
|
78
84
|
}
|
|
79
85
|
// Specifier part
|
|
@@ -85,8 +91,10 @@ const printFormatter: PrintOptions['formatter'] = function (args) {
|
|
|
85
91
|
} else {
|
|
86
92
|
templates[templates.length - 1] += specifier;
|
|
87
93
|
}
|
|
94
|
+
prevIsTemplate = true;
|
|
88
95
|
continue;
|
|
89
96
|
}
|
|
97
|
+
prevIsTemplate = false;
|
|
90
98
|
formats.push(specifier as SerializeFormat);
|
|
91
99
|
valIndex++;
|
|
92
100
|
}
|
|
@@ -97,6 +105,8 @@ const printFormatter: PrintOptions['formatter'] = function (args) {
|
|
|
97
105
|
if (valIndex < values.length) {
|
|
98
106
|
if (templates.length) {
|
|
99
107
|
templates[templates.length - 1] += ' ';
|
|
108
|
+
} else {
|
|
109
|
+
templates.push('');
|
|
100
110
|
}
|
|
101
111
|
for (let i = valIndex; i < values.length; i++) {
|
|
102
112
|
formats.push('');
|
|
@@ -111,69 +121,82 @@ const printFormatter: PrintOptions['formatter'] = function (args) {
|
|
|
111
121
|
};
|
|
112
122
|
};
|
|
113
123
|
|
|
114
|
-
/**
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
124
|
+
/** 默认格式化函数 */
|
|
125
|
+
const printFormatter: PrintOptions['formatter'] = function ({
|
|
126
|
+
templates,
|
|
127
|
+
formats,
|
|
128
|
+
values,
|
|
129
|
+
}): unknown[] | PromiseLike<unknown[]> {
|
|
130
|
+
let format = '';
|
|
131
|
+
const formattedValues: unknown[] = [];
|
|
132
|
+
let needAwait = false;
|
|
133
|
+
for (let i = 0; i < templates.length; i++) {
|
|
134
|
+
format += templates[i]!.replaceAll('%', '%%');
|
|
135
|
+
if (i < values.length) {
|
|
136
|
+
const f = formats[i] ?? '';
|
|
137
|
+
const v = values[i]!;
|
|
138
|
+
const serialized = serializeValue(this, v, f);
|
|
139
|
+
if (serialized == null) {
|
|
140
|
+
format += f || (typeof v == 'string' ? '%s' : '%o');
|
|
141
|
+
formattedValues.push(v);
|
|
142
|
+
} else if (typeof serialized == 'string') {
|
|
143
|
+
format += '%s';
|
|
144
|
+
formattedValues.push(serialized);
|
|
145
|
+
} else {
|
|
146
|
+
needAwait = true;
|
|
147
|
+
format += '%s';
|
|
148
|
+
formattedValues.push(serialized);
|
|
137
149
|
}
|
|
138
150
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
151
|
+
}
|
|
152
|
+
if (!needAwait) {
|
|
153
|
+
return [format, ...formattedValues];
|
|
154
|
+
} else {
|
|
155
|
+
return Promise.all(formattedValues).then((resolvedValues) => {
|
|
156
|
+
return [format, ...resolvedValues];
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** 默认的输出选项 */
|
|
162
|
+
const createPrintOptions = (consoleMethod: (...args: unknown[]) => void): PrintOptions => {
|
|
163
|
+
return {
|
|
164
|
+
prefix: ['MiraScript'],
|
|
165
|
+
serializer: defaultSerializer,
|
|
166
|
+
parser: printParser,
|
|
167
|
+
formatter: printFormatter,
|
|
168
|
+
logger: consoleMethod,
|
|
146
169
|
};
|
|
147
170
|
};
|
|
148
171
|
|
|
149
172
|
/** 打印输出选项 */
|
|
150
|
-
|
|
173
|
+
type PrintOptions = {
|
|
151
174
|
/** 输出时的固定前缀 */
|
|
152
|
-
prefix: readonly [prefix
|
|
175
|
+
prefix: readonly [prefix?: string, ...additional: readonly string[]];
|
|
153
176
|
/**
|
|
154
177
|
* 序列化函数
|
|
155
178
|
* @param arg 要序列化的值
|
|
156
179
|
* @param format 序列化格式
|
|
157
|
-
* @returns 序列化后的字符串,或 null
|
|
180
|
+
* @returns 序列化后的字符串,或 null 表示直接将原值传递给 {@link printer}
|
|
158
181
|
*/
|
|
159
182
|
serializer: (this: PrintOptions, arg: VmAny, format: SerializeFormat) => string | null | PromiseLike<string>;
|
|
160
|
-
/**
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const printOptions: PrintOptions = {
|
|
167
|
-
prefix: ['MiraScript'] as readonly [prefix: string, ...additional: readonly string[]],
|
|
168
|
-
serializer: defaultSerializer,
|
|
169
|
-
formatter: printFormatter,
|
|
170
|
-
printer: () => undefined,
|
|
183
|
+
/** 解析函数,解析输入并使用 {@link serializer} 序列化值,供 {@link formatter} 使用 */
|
|
184
|
+
parser: (this: PrintOptions, args: readonly VmAny[]) => FormatResult;
|
|
185
|
+
/** 格式化函数,进一步处理解析结果,供 {@link logger} 使用 */
|
|
186
|
+
formatter: (this: PrintOptions, format: FormatResult) => unknown[] | PromiseLike<unknown[]>;
|
|
187
|
+
/** 打印函数,打印格式化结果 */
|
|
188
|
+
logger: (this: PrintOptions, ...args: unknown[]) => void;
|
|
171
189
|
};
|
|
172
190
|
|
|
191
|
+
/** 进行输出 */
|
|
192
|
+
function doPrint(opt: PrintOptions, args: readonly VmAny[]): void {
|
|
193
|
+
const formatResult = opt.parser(args);
|
|
194
|
+
void Promise.resolve(opt.formatter(formatResult)).then((printed) => opt.logger(...printed));
|
|
195
|
+
}
|
|
196
|
+
|
|
173
197
|
export const debug_print = VmLib(
|
|
174
198
|
(...args) => {
|
|
175
|
-
|
|
176
|
-
debug_print.printer(formatResult);
|
|
199
|
+
doPrint(debug_print, args);
|
|
177
200
|
},
|
|
178
201
|
{
|
|
179
202
|
summary: '打印调试信息到控制台',
|
|
@@ -182,17 +205,13 @@ export const debug_print = VmLib(
|
|
|
182
205
|
returnsType: 'nil',
|
|
183
206
|
examples: ['debug_print("value:", 42);'],
|
|
184
207
|
},
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// eslint-disable-next-line no-console
|
|
188
|
-
printer: createPrinter(console.log),
|
|
189
|
-
},
|
|
208
|
+
// eslint-disable-next-line no-console
|
|
209
|
+
createPrintOptions(console.log.bind(console)),
|
|
190
210
|
);
|
|
191
211
|
|
|
192
212
|
export const panic = VmLib(
|
|
193
213
|
(message: VmAny) => {
|
|
194
|
-
|
|
195
|
-
panic.printer(formatResult);
|
|
214
|
+
doPrint(panic, message === undefined ? [] : [message]);
|
|
196
215
|
const mgsStr = toString(message, null);
|
|
197
216
|
const error = !mgsStr ? 'panic' : 'panic: ' + mgsStr;
|
|
198
217
|
throw new VmError(error, undefined);
|
|
@@ -204,11 +223,8 @@ export const panic = VmLib(
|
|
|
204
223
|
returnsType: 'never',
|
|
205
224
|
examples: ['panic("boom");'],
|
|
206
225
|
},
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// eslint-disable-next-line no-console
|
|
210
|
-
printer: createPrinter(console.error),
|
|
211
|
-
},
|
|
226
|
+
// eslint-disable-next-line no-console
|
|
227
|
+
createPrintOptions(console.error.bind(console)),
|
|
212
228
|
);
|
|
213
229
|
|
|
214
230
|
if (typeof location != 'undefined') {
|
|
@@ -21,7 +21,6 @@ export const to_json = VmLib(
|
|
|
21
21
|
paramsType: { data: 'any' },
|
|
22
22
|
returnsType: 'string',
|
|
23
23
|
examples: ['to_json([1, 2, 3]) // "[1,2,3]"'],
|
|
24
|
-
injectCp: true,
|
|
25
24
|
},
|
|
26
25
|
);
|
|
27
26
|
|
|
@@ -41,6 +40,5 @@ export const from_json = VmLib(
|
|
|
41
40
|
paramsType: { json: 'string', fallback: 'any' },
|
|
42
41
|
returnsType: 'any',
|
|
43
42
|
examples: [`from_json('{"a":1}') // (a: 1)`],
|
|
44
|
-
injectCp: true,
|
|
45
43
|
},
|
|
46
44
|
);
|
package/src/vm/lib/helpers.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Writable } from 'type-fest';
|
|
2
1
|
import { VM_ARRAY_MAX_LENGTH } from '../../helpers/constants.js';
|
|
3
2
|
import { isNaN, NotNumber, entries, fromEntries, isSafeInteger, isFinite } from '../../helpers/utils.js';
|
|
4
3
|
import { toBoolean, toNumber, toString } from '../../helpers/convert/index.js';
|
|
@@ -274,7 +273,7 @@ export function map(
|
|
|
274
273
|
/** 库函数选项 */
|
|
275
274
|
export type VmLibOption = Pick<
|
|
276
275
|
VmFunctionOption,
|
|
277
|
-
'summary' | 'params' | 'paramsType' | 'returns' | 'returnsType' | 'examples' | '
|
|
276
|
+
'summary' | 'params' | 'paramsType' | 'returns' | 'returnsType' | 'examples' | 'deprecated'
|
|
278
277
|
>;
|
|
279
278
|
/** 库函数 */
|
|
280
279
|
export type VmLib<T extends VmFunctionLike | VmConst = VmFunctionLike> = (T extends VmFunctionLike ? T : { value: T }) &
|
|
@@ -287,15 +286,17 @@ export function VmLib<
|
|
|
287
286
|
>(value: T, option: VmLibOption, properties?: P): VmLib<T> & P {
|
|
288
287
|
if (isVmFunction(value)) throw new TypeError('Cannot create VmLib from a VmFunction');
|
|
289
288
|
|
|
290
|
-
|
|
289
|
+
// 后续在 wrapEntry 中会处理函数的包装
|
|
290
|
+
const ret = (typeof value == 'function' ? value : { __proto__: null, value: value }) as VmLib<T> & P;
|
|
291
|
+
Object.defineProperties(ret, {
|
|
292
|
+
summary: { enumerable: true, value: option.summary },
|
|
293
|
+
params: { enumerable: true, value: option.params },
|
|
294
|
+
paramsType: { enumerable: true, value: option.paramsType },
|
|
295
|
+
returns: { enumerable: true, value: option.returns },
|
|
296
|
+
returnsType: { enumerable: true, value: option.returnsType },
|
|
297
|
+
examples: { enumerable: true, value: option.examples },
|
|
298
|
+
deprecated: { enumerable: true, value: option.deprecated ?? undefined },
|
|
299
|
+
});
|
|
291
300
|
Object.assign(ret, properties);
|
|
292
|
-
ret
|
|
293
|
-
ret.paramsType = option.paramsType;
|
|
294
|
-
ret.returns = option.returns;
|
|
295
|
-
ret.returnsType = option.returnsType;
|
|
296
|
-
ret.summary = option.summary;
|
|
297
|
-
ret.examples = option.examples;
|
|
298
|
-
ret.injectCp = option.injectCp ?? false;
|
|
299
|
-
ret.deprecated = option.deprecated ?? undefined;
|
|
300
|
-
return ret as VmLib<T> & P;
|
|
301
|
+
return ret;
|
|
301
302
|
}
|
package/src/vm/lib/loader.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from '../types/index.js';
|
|
9
9
|
import { create, defineProperty, entries } from '../../helpers/utils.js';
|
|
10
10
|
|
|
11
|
-
import type { VmLib
|
|
11
|
+
import type { VmLib } from './helpers.js';
|
|
12
12
|
|
|
13
13
|
/** 内置模块 */
|
|
14
14
|
class VmBuiltinModule<const T extends Record<string, VmImmutable> = Record<string, VmImmutable>> extends VmModule<T> {
|
|
@@ -46,20 +46,10 @@ export function wrapEntry<const T extends RawValue>(
|
|
|
46
46
|
}
|
|
47
47
|
if (value.name !== name) {
|
|
48
48
|
// 如果函数名和导出名不一致,则重命名
|
|
49
|
-
defineProperty(value, 'name', {
|
|
50
|
-
value: name,
|
|
51
|
-
configurable: true,
|
|
52
|
-
});
|
|
49
|
+
defineProperty(value, 'name', { value: name });
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
isLib: true,
|
|
57
|
-
injectCp: true,
|
|
58
|
-
fullName: `${module}.${name}`,
|
|
59
|
-
...(value as VmLibOption),
|
|
60
|
-
}) as ToWrappedValue<T>,
|
|
61
|
-
value.summary || undefined,
|
|
62
|
-
];
|
|
51
|
+
defineProperty(value, 'fullName', { enumerable: true, value: `${module}.${name}` });
|
|
52
|
+
return [VmFunction(value, value) as ToWrappedValue<T>, value.summary || undefined];
|
|
63
53
|
}
|
|
64
54
|
|
|
65
55
|
/** 创建模块 */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { create,
|
|
1
|
+
import { create, isFinite } from '../../helpers/utils.js';
|
|
2
2
|
import { VM_ARRAY_MAX_LENGTH, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
|
|
3
3
|
import { isVmConst } from '../../helpers/types.js';
|
|
4
4
|
import type { VmFunctionLike } from '../types/function.js';
|
|
@@ -25,8 +25,7 @@ export function $ElOpt(key: string, value: VmAny): VmConst {
|
|
|
25
25
|
|
|
26
26
|
/** 构造函数和函数表达式 */
|
|
27
27
|
export function $Fn<T extends VmFunctionLike>(name: string | null | undefined, fn: T): VmFunction<T> {
|
|
28
|
-
|
|
29
|
-
return VmFunction(fn, { isLib: false, injectCp: false });
|
|
28
|
+
return VmFunction(fn, { isLib: false, injectCp: false, name: name || VM_FUNCTION_ANONYMOUS_NAME });
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/** 读取闭包上值 */
|
package/src/vm/types/context.ts
CHANGED
package/src/vm/types/function.ts
CHANGED
|
@@ -2,9 +2,10 @@ import type { Writable } from 'type-fest';
|
|
|
2
2
|
import type { DiagnosticCode } from '@mirascript/constants';
|
|
3
3
|
import { defineProperty } from '../../helpers/utils.js';
|
|
4
4
|
import { kVmFunction, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
|
|
5
|
-
import type
|
|
5
|
+
import { isVmFunction, type VmAny, type VmValue } from './index.js';
|
|
6
6
|
import { fromVmFunctionProxy } from './boundary.js';
|
|
7
7
|
import { CpEnter, CpExit } from '../checkpoint.js';
|
|
8
|
+
import type { VmLib } from '../lib/helpers.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Mirascript 函数签名
|
|
@@ -18,7 +19,7 @@ export type VmFunctionLike = (...args: ReadonlyArray<VmValue | undefined>) => Vm
|
|
|
18
19
|
export type VmFunction<T extends VmFunctionLike = VmFunctionLike> = T & { readonly [kVmFunction]: VmFunctionInfo };
|
|
19
20
|
|
|
20
21
|
/** Mirascript 函数信息 */
|
|
21
|
-
export
|
|
22
|
+
export type VmFunctionInfo = {
|
|
22
23
|
/** 完整名称 */
|
|
23
24
|
readonly fullName: string;
|
|
24
25
|
/** 是否为库函数 */
|
|
@@ -39,17 +40,27 @@ export interface VmFunctionInfo {
|
|
|
39
40
|
readonly original?: VmFunctionLike;
|
|
40
41
|
/** 标记为弃用 */
|
|
41
42
|
readonly deprecated?: { use?: string; message: DiagnosticCode };
|
|
42
|
-
}
|
|
43
|
+
};
|
|
43
44
|
|
|
44
45
|
/** Mirascript 函数创建选项 */
|
|
45
|
-
export type VmFunctionOption = Partial<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
export type VmFunctionOption = Partial<Omit<VmFunctionInfo, 'original'>> & {
|
|
47
|
+
/** 函数名称 */
|
|
48
|
+
readonly name?: string | null | undefined;
|
|
49
|
+
/** 是否注入检查点 */
|
|
50
|
+
readonly injectCp?: boolean;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const nameIfNotAnonymous = <T>({ name }: { name: string | undefined }, fallback: T): string | T => {
|
|
54
|
+
if (!name) return fallback;
|
|
55
|
+
if (name === VM_FUNCTION_ANONYMOUS_NAME) return fallback;
|
|
56
|
+
return name;
|
|
57
|
+
};
|
|
50
58
|
|
|
51
59
|
/** 创建 Mirascript 函数 */
|
|
52
|
-
export function VmFunction<T extends VmFunctionLike>(
|
|
60
|
+
export function VmFunction<T extends VmFunctionLike>(
|
|
61
|
+
fn: T,
|
|
62
|
+
option: VmFunctionOption | VmFunction | VmLib<T> = {},
|
|
63
|
+
): VmFunction<T> {
|
|
53
64
|
if (typeof fn != 'function') {
|
|
54
65
|
throw new TypeError('Invalid function');
|
|
55
66
|
}
|
|
@@ -57,19 +68,34 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
|
|
|
57
68
|
const exists = fromVmFunctionProxy(fn);
|
|
58
69
|
// 如果已经是 VmFunction,则直接返回
|
|
59
70
|
if (exists) return exists;
|
|
71
|
+
let opt: VmFunctionOption;
|
|
72
|
+
if (isVmFunction(option)) {
|
|
73
|
+
opt = { ...option[kVmFunction], name: nameIfNotAnonymous(option, null) };
|
|
74
|
+
} else if (typeof option == 'function') {
|
|
75
|
+
opt = {
|
|
76
|
+
...option,
|
|
77
|
+
isLib: true,
|
|
78
|
+
injectCp: false,
|
|
79
|
+
name: nameIfNotAnonymous(option, null),
|
|
80
|
+
};
|
|
81
|
+
} else {
|
|
82
|
+
opt = option;
|
|
83
|
+
}
|
|
60
84
|
|
|
61
|
-
const info: Writable<VmFunctionInfo> = {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
const info: Writable<VmFunctionInfo & { __proto__: null }> = {
|
|
86
|
+
__proto__: null,
|
|
87
|
+
fullName: opt.fullName ?? nameIfNotAnonymous(fn, ''),
|
|
88
|
+
isLib: opt.isLib ?? false,
|
|
89
|
+
summary: opt.summary || undefined,
|
|
90
|
+
params: opt.params,
|
|
91
|
+
paramsType: opt.paramsType,
|
|
92
|
+
returns: opt.returns || undefined,
|
|
93
|
+
returnsType: opt.returnsType || undefined,
|
|
94
|
+
examples: opt.examples?.length ? opt.examples : undefined,
|
|
95
|
+
deprecated: opt.deprecated ?? undefined,
|
|
71
96
|
};
|
|
72
|
-
|
|
97
|
+
const name = opt.name ?? fn.name;
|
|
98
|
+
if (opt.injectCp) {
|
|
73
99
|
const original = fn;
|
|
74
100
|
info.original = original;
|
|
75
101
|
fn = ((...args) => {
|
|
@@ -81,10 +107,8 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
|
|
|
81
107
|
CpExit();
|
|
82
108
|
}
|
|
83
109
|
}) as typeof fn;
|
|
84
|
-
defineProperty(fn, 'name', { value: original.name });
|
|
85
110
|
}
|
|
86
|
-
defineProperty(fn,
|
|
87
|
-
|
|
88
|
-
});
|
|
111
|
+
defineProperty(fn, 'name', { value: name, configurable: true });
|
|
112
|
+
defineProperty(fn, kVmFunction, { value: Object.freeze(info) });
|
|
89
113
|
return fn as VmFunction<T>;
|
|
90
114
|
}
|
package/src/vm/types/wrapper.ts
CHANGED
|
@@ -22,10 +22,6 @@ export abstract class VmWrapper<T extends object> {
|
|
|
22
22
|
describe(key: string): string | undefined {
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
25
|
-
/** Convert the object to JSON */
|
|
26
|
-
toJSON(): undefined {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
25
|
/** 转为字符串 */
|
|
30
26
|
toString(useBraces: boolean): string {
|
|
31
27
|
const { type, tag } = this;
|