jslike 1.7.3 → 1.8.0
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/README.md +4 -1
- package/dist/esm/index.js +16 -5
- package/dist/esm/interpreter/index.js +2 -1
- package/dist/esm/interpreter/interpreter.js +200 -15
- package/dist/esm/parser.js +5040 -1
- package/dist/index.cjs +5177 -18
- package/dist/index.d.cts +5218 -19
- package/dist/index.d.ts +5218 -19
- package/dist/index.js +5177 -18
- package/dist/validator/index.cjs +5018 -3
- package/dist/validator/index.js +5018 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -473,7 +473,10 @@ Execute JavaScript code and return the result.
|
|
|
473
473
|
const result = await execute(code, env, {
|
|
474
474
|
moduleResolver, // For import statements
|
|
475
475
|
executionController, // For pause/resume/abort
|
|
476
|
-
abortSignal
|
|
476
|
+
abortSignal, // For cancellation
|
|
477
|
+
sourcePath, // Optional importer path for resolving top-level imports
|
|
478
|
+
typescript, // Parse TypeScript syntax
|
|
479
|
+
tsx // Parse TypeScript + JSX syntax
|
|
477
480
|
});
|
|
478
481
|
```
|
|
479
482
|
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Use bundled Acorn parser for zero runtime dependencies
|
|
2
|
-
import { parse as acornParse } from './parser.js';
|
|
2
|
+
import { parse as acornParse, tsParse, tsxParse } from './parser.js';
|
|
3
3
|
import { Interpreter } from './interpreter/interpreter.js';
|
|
4
4
|
import { Environment, ReturnValue } from './runtime/environment.js';
|
|
5
5
|
import { createGlobalEnvironment } from './runtime/builtins.js';
|
|
@@ -9,7 +9,7 @@ function containsModuleSyntax(code) {
|
|
|
9
9
|
// Trigger module mode for:
|
|
10
10
|
// 1. import/export statements
|
|
11
11
|
// 2. Top-level await (await not inside a function)
|
|
12
|
-
if (
|
|
12
|
+
if (/(^|[;{\n])\s*(import|export)\s+/m.test(code)) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -23,6 +23,13 @@ function containsModuleSyntax(code) {
|
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function isTypeScriptPath(sourcePath) {
|
|
27
|
+
return typeof sourcePath === 'string' && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isTSXPath(sourcePath) {
|
|
31
|
+
return typeof sourcePath === 'string' && /\.tsx$/i.test(sourcePath);
|
|
32
|
+
}
|
|
26
33
|
|
|
27
34
|
export function parse(code, options = {}) {
|
|
28
35
|
// Determine sourceType: use 'module' ONLY if explicitly requested or if code has imports/exports
|
|
@@ -32,10 +39,13 @@ export function parse(code, options = {}) {
|
|
|
32
39
|
sourceType = 'module';
|
|
33
40
|
}
|
|
34
41
|
|
|
42
|
+
const shouldParseTypeScript = options.typescript || options.tsx || isTypeScriptPath(options.sourcePath);
|
|
43
|
+
const parser = options.tsx || isTSXPath(options.sourcePath) ? tsxParse : shouldParseTypeScript ? tsParse : acornParse;
|
|
44
|
+
|
|
35
45
|
// Parse with Acorn
|
|
36
46
|
try {
|
|
37
|
-
return
|
|
38
|
-
ecmaVersion: 2022, // Support ES2022 features (including top-level await)
|
|
47
|
+
return parser(code, {
|
|
48
|
+
ecmaVersion: shouldParseTypeScript ? 'latest' : 2022, // Support ES2022 features (including top-level await)
|
|
39
49
|
sourceType: sourceType,
|
|
40
50
|
locations: true, // Track source locations for better error messages
|
|
41
51
|
allowReturnOutsideFunction: true, // Allow top-level return statements
|
|
@@ -119,7 +129,8 @@ export async function execute(code, env = null, options = {}) {
|
|
|
119
129
|
const interpreter = new Interpreter(env, {
|
|
120
130
|
moduleResolver: options.moduleResolver,
|
|
121
131
|
abortSignal: options.abortSignal,
|
|
122
|
-
executionController: controller
|
|
132
|
+
executionController: controller,
|
|
133
|
+
currentModulePath: options.sourcePath
|
|
123
134
|
});
|
|
124
135
|
|
|
125
136
|
// Use async evaluation if:
|
|
@@ -103,7 +103,8 @@ export class WangInterpreter {
|
|
|
103
103
|
const options = {
|
|
104
104
|
moduleResolver: this.moduleResolver,
|
|
105
105
|
executionController: userOptions.executionController,
|
|
106
|
-
abortSignal: userOptions.abortSignal // Pass abort signal to interpreter for cancellation support
|
|
106
|
+
abortSignal: userOptions.abortSignal, // Pass abort signal to interpreter for cancellation support
|
|
107
|
+
sourcePath: userOptions.sourcePath ?? this.options.sourcePath
|
|
107
108
|
// sourceType will be auto-detected from code
|
|
108
109
|
};
|
|
109
110
|
|
|
@@ -1,13 +1,70 @@
|
|
|
1
1
|
import { Environment, ReturnValue, BreakSignal, ContinueSignal, ThrowSignal } from '../runtime/environment.js';
|
|
2
|
-
import { parse as acornParse } from '../parser.js';
|
|
2
|
+
import { parse as acornParse, tsParse, tsxParse } from '../parser.js';
|
|
3
3
|
import { createMethodNotFoundError } from '../errors/enhanced-error.js';
|
|
4
4
|
|
|
5
|
+
function isTypeScriptPath(sourcePath) {
|
|
6
|
+
return typeof sourcePath === 'string' && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function isTSXPath(sourcePath) {
|
|
10
|
+
return typeof sourcePath === 'string' && /\.tsx$/i.test(sourcePath);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function parseModuleCode(code, sourcePath) {
|
|
14
|
+
const parser = isTSXPath(sourcePath) ? tsxParse : isTypeScriptPath(sourcePath) ? tsParse : acornParse;
|
|
15
|
+
return parser(code, {
|
|
16
|
+
ecmaVersion: isTypeScriptPath(sourcePath) ? 'latest' : 2020,
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
locations: isTypeScriptPath(sourcePath)
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const TYPE_ONLY_DECLARATIONS = new Set([
|
|
23
|
+
'TSTypeAliasDeclaration',
|
|
24
|
+
'TSInterfaceDeclaration',
|
|
25
|
+
'TSDeclareFunction'
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const TYPE_WRAPPER_EXPRESSIONS = new Set([
|
|
29
|
+
'TSAsExpression',
|
|
30
|
+
'TSTypeAssertion',
|
|
31
|
+
'TSNonNullExpression',
|
|
32
|
+
'TSSatisfiesExpression',
|
|
33
|
+
'TSInstantiationExpression'
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
function isTypeOnlyDeclaration(node) {
|
|
37
|
+
return TYPE_ONLY_DECLARATIONS.has(node?.type) || node?.declare === true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isTypeWrapperExpression(node) {
|
|
41
|
+
return TYPE_WRAPPER_EXPRESSIONS.has(node?.type);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getTypeWrapperInnerExpression(node) {
|
|
45
|
+
return node.expression;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function createUnsupportedTypeScriptRuntimeError(node) {
|
|
49
|
+
return new Error(`Unsupported runtime TypeScript syntax: ${node.type}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getPatternName(pattern) {
|
|
53
|
+
if (!pattern) return undefined;
|
|
54
|
+
if (pattern.type === 'Identifier') return pattern.name;
|
|
55
|
+
if (pattern.type === 'AssignmentPattern') return getPatternName(pattern.left);
|
|
56
|
+
if (pattern.type === 'TSParameterProperty') return getPatternName(pattern.parameter);
|
|
57
|
+
return pattern.name;
|
|
58
|
+
}
|
|
59
|
+
|
|
5
60
|
export class Interpreter {
|
|
6
61
|
constructor(globalEnv, options = {}) {
|
|
7
62
|
this.globalEnv = globalEnv;
|
|
8
63
|
this.moduleResolver = options.moduleResolver;
|
|
9
64
|
this.moduleCache = new Map(); // Cache loaded modules
|
|
65
|
+
this.moduleResolutionCache = options.moduleResolutionCache || new Map();
|
|
10
66
|
this.moduleExports = {}; // Track exports in current module
|
|
67
|
+
this.currentModulePath = options.currentModulePath;
|
|
11
68
|
this.abortSignal = options.abortSignal;
|
|
12
69
|
this.executionController = options.executionController;
|
|
13
70
|
}
|
|
@@ -163,6 +220,27 @@ export class Interpreter {
|
|
|
163
220
|
const checkpointPromise = this._getCheckpointPromise(node, env);
|
|
164
221
|
if (checkpointPromise) await checkpointPromise;
|
|
165
222
|
|
|
223
|
+
if (isTypeOnlyDeclaration(node)) {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (node.type === 'TSExportAssignment' || node.type === 'TSImportEqualsDeclaration') {
|
|
228
|
+
throw createUnsupportedTypeScriptRuntimeError(node);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (node.type === 'TSEnumDeclaration') {
|
|
232
|
+
return this.evaluateTSEnumDeclaration(node, env);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (node.type === 'TSModuleDeclaration') {
|
|
236
|
+
if (node.declare) return undefined;
|
|
237
|
+
throw createUnsupportedTypeScriptRuntimeError(node);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (isTypeWrapperExpression(node)) {
|
|
241
|
+
return await this.evaluateAsync(getTypeWrapperInnerExpression(node), env);
|
|
242
|
+
}
|
|
243
|
+
|
|
166
244
|
// Handle await expressions by actually awaiting the promise
|
|
167
245
|
if (node.type === 'AwaitExpression') {
|
|
168
246
|
const promise = await this.evaluateAsync(node.argument, env);
|
|
@@ -814,6 +892,27 @@ export class Interpreter {
|
|
|
814
892
|
// Check for abort signal before evaluating
|
|
815
893
|
this.checkAbortSignal();
|
|
816
894
|
|
|
895
|
+
if (isTypeOnlyDeclaration(node)) {
|
|
896
|
+
return undefined;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (node.type === 'TSExportAssignment' || node.type === 'TSImportEqualsDeclaration') {
|
|
900
|
+
throw createUnsupportedTypeScriptRuntimeError(node);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
if (node.type === 'TSEnumDeclaration') {
|
|
904
|
+
return this.evaluateTSEnumDeclaration(node, env);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
if (node.type === 'TSModuleDeclaration') {
|
|
908
|
+
if (node.declare) return undefined;
|
|
909
|
+
throw createUnsupportedTypeScriptRuntimeError(node);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (isTypeWrapperExpression(node)) {
|
|
913
|
+
return this.evaluate(getTypeWrapperInnerExpression(node), env);
|
|
914
|
+
}
|
|
915
|
+
|
|
817
916
|
switch (node.type) {
|
|
818
917
|
case 'Program':
|
|
819
918
|
return this.evaluateProgram(node, env);
|
|
@@ -974,6 +1073,9 @@ export class Interpreter {
|
|
|
974
1073
|
case 'Property':
|
|
975
1074
|
return this.evaluateProperty(node, env);
|
|
976
1075
|
|
|
1076
|
+
case 'TSEnumDeclaration':
|
|
1077
|
+
return this.evaluateTSEnumDeclaration(node, env);
|
|
1078
|
+
|
|
977
1079
|
// JSX Support
|
|
978
1080
|
case 'JSXElement':
|
|
979
1081
|
return this.evaluateJSXElement(node, env);
|
|
@@ -1396,7 +1498,9 @@ export class Interpreter {
|
|
|
1396
1498
|
|
|
1397
1499
|
// Bind parameters
|
|
1398
1500
|
for (let i = 0; i < metadata.params.length; i++) {
|
|
1399
|
-
const param = metadata.params[i]
|
|
1501
|
+
const param = metadata.params[i].type === 'TSParameterProperty'
|
|
1502
|
+
? metadata.params[i].parameter
|
|
1503
|
+
: metadata.params[i];
|
|
1400
1504
|
|
|
1401
1505
|
if (param.type === 'Identifier') {
|
|
1402
1506
|
// Simple parameter: function(x)
|
|
@@ -1719,6 +1823,34 @@ export class Interpreter {
|
|
|
1719
1823
|
return undefined;
|
|
1720
1824
|
}
|
|
1721
1825
|
|
|
1826
|
+
evaluateTSEnumDeclaration(node, env) {
|
|
1827
|
+
const enumObject = {};
|
|
1828
|
+
let nextNumericValue = 0;
|
|
1829
|
+
|
|
1830
|
+
for (const member of node.members) {
|
|
1831
|
+
const memberName = member.id.name ?? member.id.value;
|
|
1832
|
+
let value;
|
|
1833
|
+
|
|
1834
|
+
if (member.initializer) {
|
|
1835
|
+
value = this.evaluate(member.initializer, env);
|
|
1836
|
+
} else {
|
|
1837
|
+
value = nextNumericValue;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
enumObject[memberName] = value;
|
|
1841
|
+
|
|
1842
|
+
if (typeof value === 'number') {
|
|
1843
|
+
enumObject[value] = memberName;
|
|
1844
|
+
nextNumericValue = value + 1;
|
|
1845
|
+
} else {
|
|
1846
|
+
nextNumericValue = undefined;
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
env.define(node.id.name, enumObject, false);
|
|
1851
|
+
return undefined;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1722
1854
|
bindObjectPattern(pattern, value, env, isConst = false) {
|
|
1723
1855
|
if (value === null || value === undefined) {
|
|
1724
1856
|
throw new TypeError('Cannot destructure undefined or null');
|
|
@@ -1823,42 +1955,65 @@ export class Interpreter {
|
|
|
1823
1955
|
// Get module path from import source
|
|
1824
1956
|
const modulePath = node.source.value;
|
|
1825
1957
|
|
|
1958
|
+
if (node.importKind === 'type' ||
|
|
1959
|
+
(node.specifiers.length > 0 && node.specifiers.every(specifier => specifier.importKind === 'type'))) {
|
|
1960
|
+
return undefined;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1826
1963
|
// Check if module resolver is configured
|
|
1827
1964
|
if (!this.moduleResolver) {
|
|
1828
1965
|
throw new Error('Module resolver not configured - cannot import modules');
|
|
1829
1966
|
}
|
|
1830
1967
|
|
|
1968
|
+
const fromPath = this.currentModulePath;
|
|
1969
|
+
|
|
1970
|
+
const resolutionCacheKey = `${fromPath || ''}\0${modulePath}`;
|
|
1971
|
+
let resolution;
|
|
1972
|
+
let resolvedPath = this.moduleResolutionCache.get(resolutionCacheKey);
|
|
1973
|
+
if (!resolvedPath && !modulePath.startsWith('.') && this.moduleCache.has(modulePath)) {
|
|
1974
|
+
resolvedPath = modulePath;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1831
1977
|
// Check if module is already cached
|
|
1832
1978
|
let moduleExports;
|
|
1833
|
-
if (this.moduleCache.has(
|
|
1834
|
-
moduleExports = this.moduleCache.get(
|
|
1979
|
+
if (resolvedPath && this.moduleCache.has(resolvedPath)) {
|
|
1980
|
+
moduleExports = this.moduleCache.get(resolvedPath);
|
|
1835
1981
|
} else {
|
|
1836
|
-
// Resolve and
|
|
1837
|
-
|
|
1982
|
+
// Resolve first so relative imports can use importer context and cache by resolved path.
|
|
1983
|
+
resolution = await this.moduleResolver.resolve(modulePath, fromPath);
|
|
1838
1984
|
if (!resolution) {
|
|
1839
1985
|
throw new Error(`Cannot find module '${modulePath}'`);
|
|
1840
1986
|
}
|
|
1841
1987
|
|
|
1988
|
+
resolvedPath = typeof resolution === 'string'
|
|
1989
|
+
? modulePath
|
|
1990
|
+
: resolution.path || modulePath;
|
|
1991
|
+
this.moduleResolutionCache.set(resolutionCacheKey, resolvedPath);
|
|
1992
|
+
if (this.moduleCache.has(resolvedPath)) {
|
|
1993
|
+
moduleExports = this.moduleCache.get(resolvedPath);
|
|
1994
|
+
return this.bindImportSpecifiers(node, env, modulePath, moduleExports);
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1842
1997
|
// Handle native module exports (for libraries like React)
|
|
1843
1998
|
// If resolution has 'exports' property, use it directly without parsing
|
|
1844
1999
|
if (resolution.exports) {
|
|
1845
2000
|
moduleExports = resolution.exports;
|
|
1846
|
-
this.moduleCache.set(
|
|
2001
|
+
this.moduleCache.set(resolvedPath, moduleExports);
|
|
1847
2002
|
} else {
|
|
1848
2003
|
// Handle both old (string) and new (ModuleResolution) formats
|
|
1849
2004
|
const moduleCode = typeof resolution === 'string' ? resolution : resolution.code;
|
|
1850
2005
|
|
|
1851
2006
|
// Parse and execute module in its own environment
|
|
1852
|
-
const moduleAst =
|
|
1853
|
-
ecmaVersion: 2020,
|
|
1854
|
-
sourceType: 'module',
|
|
1855
|
-
locations: false
|
|
1856
|
-
});
|
|
2007
|
+
const moduleAst = parseModuleCode(moduleCode, resolvedPath);
|
|
1857
2008
|
const moduleEnv = new Environment(this.globalEnv);
|
|
1858
2009
|
|
|
1859
2010
|
// Create a new interpreter for the module with shared module cache
|
|
1860
2011
|
const moduleInterpreter = new Interpreter(this.globalEnv, {
|
|
1861
|
-
moduleResolver: this.moduleResolver
|
|
2012
|
+
moduleResolver: this.moduleResolver,
|
|
2013
|
+
moduleResolutionCache: this.moduleResolutionCache,
|
|
2014
|
+
currentModulePath: resolvedPath,
|
|
2015
|
+
abortSignal: this.abortSignal,
|
|
2016
|
+
executionController: this.executionController
|
|
1862
2017
|
});
|
|
1863
2018
|
moduleInterpreter.moduleCache = this.moduleCache; // Share cache
|
|
1864
2019
|
|
|
@@ -1867,12 +2022,21 @@ export class Interpreter {
|
|
|
1867
2022
|
|
|
1868
2023
|
// Cache the module exports
|
|
1869
2024
|
moduleExports = moduleInterpreter.moduleExports;
|
|
1870
|
-
this.moduleCache.set(
|
|
2025
|
+
this.moduleCache.set(resolvedPath, moduleExports);
|
|
1871
2026
|
}
|
|
1872
2027
|
}
|
|
1873
2028
|
|
|
2029
|
+
this.bindImportSpecifiers(node, env, modulePath, moduleExports);
|
|
2030
|
+
return undefined;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
bindImportSpecifiers(node, env, modulePath, moduleExports) {
|
|
1874
2034
|
// Import specified bindings into current environment
|
|
1875
2035
|
for (const specifier of node.specifiers) {
|
|
2036
|
+
if (specifier.importKind === 'type') {
|
|
2037
|
+
continue;
|
|
2038
|
+
}
|
|
2039
|
+
|
|
1876
2040
|
if (specifier.type === 'ImportSpecifier') {
|
|
1877
2041
|
// Named import: import { foo, bar } from "module"
|
|
1878
2042
|
const importedName = specifier.imported.name;
|
|
@@ -1903,6 +2067,10 @@ export class Interpreter {
|
|
|
1903
2067
|
}
|
|
1904
2068
|
|
|
1905
2069
|
evaluateExportNamedDeclaration(node, env) {
|
|
2070
|
+
if (node.exportKind === 'type' || isTypeOnlyDeclaration(node.declaration)) {
|
|
2071
|
+
return undefined;
|
|
2072
|
+
}
|
|
2073
|
+
|
|
1906
2074
|
// Handle export with declaration: export function foo() {} or export const x = 42
|
|
1907
2075
|
if (node.declaration) {
|
|
1908
2076
|
const result = this.evaluate(node.declaration, env);
|
|
@@ -1922,6 +2090,9 @@ export class Interpreter {
|
|
|
1922
2090
|
// export class Foo {}
|
|
1923
2091
|
const name = node.declaration.id.name;
|
|
1924
2092
|
this.moduleExports[name] = env.get(name);
|
|
2093
|
+
} else if (node.declaration.type === 'TSEnumDeclaration') {
|
|
2094
|
+
const name = node.declaration.id.name;
|
|
2095
|
+
this.moduleExports[name] = env.get(name);
|
|
1925
2096
|
}
|
|
1926
2097
|
|
|
1927
2098
|
return result;
|
|
@@ -1930,6 +2101,10 @@ export class Interpreter {
|
|
|
1930
2101
|
// Handle export list: export { foo, bar }
|
|
1931
2102
|
if (node.specifiers && node.specifiers.length > 0) {
|
|
1932
2103
|
for (const specifier of node.specifiers) {
|
|
2104
|
+
if (specifier.exportKind === 'type') {
|
|
2105
|
+
continue;
|
|
2106
|
+
}
|
|
2107
|
+
|
|
1933
2108
|
const exportedName = specifier.exported.name;
|
|
1934
2109
|
const localName = specifier.local.name;
|
|
1935
2110
|
this.moduleExports[exportedName] = env.get(localName);
|
|
@@ -2406,7 +2581,10 @@ export class Interpreter {
|
|
|
2406
2581
|
|
|
2407
2582
|
// Bind parameters
|
|
2408
2583
|
for (let i = 0; i < methodFunc.__params.length; i++) {
|
|
2409
|
-
const
|
|
2584
|
+
const originalParam = methodFunc.__params[i];
|
|
2585
|
+
const param = originalParam.type === 'TSParameterProperty'
|
|
2586
|
+
? originalParam.parameter
|
|
2587
|
+
: originalParam;
|
|
2410
2588
|
|
|
2411
2589
|
if (param.type === 'Identifier') {
|
|
2412
2590
|
// Simple parameter: function(x)
|
|
@@ -2429,6 +2607,13 @@ export class Interpreter {
|
|
|
2429
2607
|
// Fallback for simple parameter names
|
|
2430
2608
|
funcEnv.define(param.name, args[i]);
|
|
2431
2609
|
}
|
|
2610
|
+
|
|
2611
|
+
if (originalParam.type === 'TSParameterProperty') {
|
|
2612
|
+
const propertyName = getPatternName(originalParam.parameter);
|
|
2613
|
+
if (propertyName) {
|
|
2614
|
+
thisContext[propertyName] = funcEnv.get(propertyName);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2432
2617
|
}
|
|
2433
2618
|
|
|
2434
2619
|
const result = this.evaluate(methodFunc.__body, funcEnv);
|