jslike 1.8.2 → 1.8.4
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/esm/interpreter/interpreter.js +161 -92
- package/dist/index.cjs +137 -61
- package/dist/index.d.cts +161 -92
- package/dist/index.d.ts +161 -92
- package/dist/index.js +137 -61
- package/package.json +1 -1
|
@@ -57,6 +57,10 @@ function getPatternName(pattern) {
|
|
|
57
57
|
return pattern.name;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
function unwrapTSParameterProperty(param) {
|
|
61
|
+
return param?.type === 'TSParameterProperty' ? param.parameter : param;
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
function collectRuntimeIdentifierReferences(node) {
|
|
61
65
|
const references = new Set();
|
|
62
66
|
const skipKeys = new Set([
|
|
@@ -1678,34 +1682,7 @@ export class Interpreter {
|
|
|
1678
1682
|
funcEnv.define('this', thisContext);
|
|
1679
1683
|
}
|
|
1680
1684
|
|
|
1681
|
-
|
|
1682
|
-
for (let i = 0; i < metadata.params.length; i++) {
|
|
1683
|
-
const param = metadata.params[i].type === 'TSParameterProperty'
|
|
1684
|
-
? metadata.params[i].parameter
|
|
1685
|
-
: metadata.params[i];
|
|
1686
|
-
|
|
1687
|
-
if (param.type === 'Identifier') {
|
|
1688
|
-
// Simple parameter: function(x)
|
|
1689
|
-
funcEnv.define(param.name, args[i]);
|
|
1690
|
-
} else if (param.type === 'AssignmentPattern') {
|
|
1691
|
-
// Default parameter: function(x = defaultValue)
|
|
1692
|
-
const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
|
|
1693
|
-
funcEnv.define(param.left.name, value);
|
|
1694
|
-
} else if (param.type === 'RestElement') {
|
|
1695
|
-
// Rest parameter: function(...rest)
|
|
1696
|
-
funcEnv.define(param.argument.name, args.slice(i));
|
|
1697
|
-
break; // Rest element must be last
|
|
1698
|
-
} else if (param.type === 'ObjectPattern') {
|
|
1699
|
-
// Destructuring parameter: function({a, b})
|
|
1700
|
-
this.bindObjectPattern(param, args[i], funcEnv);
|
|
1701
|
-
} else if (param.type === 'ArrayPattern') {
|
|
1702
|
-
// Array destructuring parameter: function([a, b])
|
|
1703
|
-
this.bindArrayPattern(param, args[i], funcEnv);
|
|
1704
|
-
} else {
|
|
1705
|
-
// Fallback for simple parameter names
|
|
1706
|
-
funcEnv.define(param.name, args[i]);
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1685
|
+
this.bindFunctionParameters(metadata.params, args, funcEnv);
|
|
1709
1686
|
|
|
1710
1687
|
// Execute function body
|
|
1711
1688
|
// If async, use async evaluation and return a promise
|
|
@@ -2062,7 +2039,7 @@ export class Interpreter {
|
|
|
2062
2039
|
const finalValue = propValue !== undefined
|
|
2063
2040
|
? propValue
|
|
2064
2041
|
: this.evaluate(prop.value.right, env);
|
|
2065
|
-
|
|
2042
|
+
this.bindPattern(prop.value.left, finalValue, env, isConst);
|
|
2066
2043
|
} else if (prop.value.type === 'ObjectPattern') {
|
|
2067
2044
|
this.bindObjectPattern(prop.value, propValue, env, isConst);
|
|
2068
2045
|
} else if (prop.value.type === 'ArrayPattern') {
|
|
@@ -2093,7 +2070,7 @@ export class Interpreter {
|
|
|
2093
2070
|
const finalValue = value[i] !== undefined
|
|
2094
2071
|
? value[i]
|
|
2095
2072
|
: this.evaluate(element.right, env);
|
|
2096
|
-
|
|
2073
|
+
this.bindPattern(element.left, finalValue, env, isConst);
|
|
2097
2074
|
} else if (element.type === 'ObjectPattern') {
|
|
2098
2075
|
this.bindObjectPattern(element, value[i], env, isConst);
|
|
2099
2076
|
} else if (element.type === 'ArrayPattern') {
|
|
@@ -2102,6 +2079,78 @@ export class Interpreter {
|
|
|
2102
2079
|
}
|
|
2103
2080
|
}
|
|
2104
2081
|
|
|
2082
|
+
bindPattern(pattern, value, env, isConst = false) {
|
|
2083
|
+
if (pattern.type === 'Identifier') {
|
|
2084
|
+
env.define(pattern.name, value, isConst);
|
|
2085
|
+
} else if (pattern.type === 'ObjectPattern') {
|
|
2086
|
+
this.bindObjectPattern(pattern, value, env, isConst);
|
|
2087
|
+
} else if (pattern.type === 'ArrayPattern') {
|
|
2088
|
+
this.bindArrayPattern(pattern, value, env, isConst);
|
|
2089
|
+
} else if (pattern.type === 'AssignmentPattern') {
|
|
2090
|
+
const finalValue = value !== undefined ? value : this.evaluate(pattern.right, env);
|
|
2091
|
+
this.bindPattern(pattern.left, finalValue, env, isConst);
|
|
2092
|
+
} else if (pattern.type === 'RestElement') {
|
|
2093
|
+
this.bindPattern(pattern.argument, value, env, isConst);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
bindFunctionParameters(params, args, env, thisContext = null) {
|
|
2098
|
+
for (let i = 0; i < params.length; i++) {
|
|
2099
|
+
const originalParam = params[i];
|
|
2100
|
+
const param = unwrapTSParameterProperty(originalParam);
|
|
2101
|
+
|
|
2102
|
+
this.bindFunctionParameter(param, args[i], args.slice(i), env);
|
|
2103
|
+
|
|
2104
|
+
if (originalParam.type === 'TSParameterProperty' && thisContext) {
|
|
2105
|
+
const propertyName = getPatternName(originalParam.parameter);
|
|
2106
|
+
if (propertyName) {
|
|
2107
|
+
thisContext[propertyName] = env.get(propertyName);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
if (param.type === 'RestElement') {
|
|
2112
|
+
break;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
bindFunctionParameter(param, arg, restArgs, env) {
|
|
2118
|
+
if (param.type === 'Identifier') {
|
|
2119
|
+
this.bindPattern(param, arg, env);
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
if (param.type === 'AssignmentPattern') {
|
|
2124
|
+
const value = arg !== undefined ? arg : this.evaluate(param.right, env);
|
|
2125
|
+
this.bindPattern(param.left, value, env);
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
if (param.type === 'RestElement') {
|
|
2130
|
+
const target = param.argument;
|
|
2131
|
+
if (target.type === 'Identifier') {
|
|
2132
|
+
env.define(target.name, restArgs);
|
|
2133
|
+
} else if (target.type === 'ArrayPattern') {
|
|
2134
|
+
this.bindArrayPattern(target, restArgs, env);
|
|
2135
|
+
} else if (target.type === 'ObjectPattern') {
|
|
2136
|
+
this.bindObjectPattern(target, restArgs, env);
|
|
2137
|
+
}
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
if (param.type === 'ObjectPattern') {
|
|
2142
|
+
this.bindPattern(param, arg, env);
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
if (param.type === 'ArrayPattern') {
|
|
2147
|
+
this.bindPattern(param, arg, env);
|
|
2148
|
+
return;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
env.define(param.name, arg);
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2105
2154
|
evaluateFunctionDeclaration(node, env) {
|
|
2106
2155
|
const funcMetadata = {
|
|
2107
2156
|
__isFunction: true,
|
|
@@ -2666,6 +2715,7 @@ export class Interpreter {
|
|
|
2666
2715
|
let constructor = null;
|
|
2667
2716
|
const methods = {};
|
|
2668
2717
|
const staticMethods = {};
|
|
2718
|
+
const instanceFields = [];
|
|
2669
2719
|
|
|
2670
2720
|
for (const member of node.body.body) {
|
|
2671
2721
|
if (member.type === 'MethodDefinition') {
|
|
@@ -2679,6 +2729,8 @@ export class Interpreter {
|
|
|
2679
2729
|
} else {
|
|
2680
2730
|
methods[methodName] = methodFunc;
|
|
2681
2731
|
}
|
|
2732
|
+
} else if (member.type === 'PropertyDefinition' && !member.static && !member.declare && !member.abstract) {
|
|
2733
|
+
instanceFields.push(member);
|
|
2682
2734
|
}
|
|
2683
2735
|
}
|
|
2684
2736
|
|
|
@@ -2686,18 +2738,11 @@ export class Interpreter {
|
|
|
2686
2738
|
const classConstructor = function(...args) {
|
|
2687
2739
|
// Create instance
|
|
2688
2740
|
const instance = Object.create(classConstructor.prototype);
|
|
2741
|
+
const result = interpreter.constructClassInto(classConstructor, instance, args, env);
|
|
2689
2742
|
|
|
2690
|
-
//
|
|
2691
|
-
if (
|
|
2692
|
-
|
|
2693
|
-
// Only use the returned object if it's an explicit return of an object (not the instance)
|
|
2694
|
-
if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
|
|
2695
|
-
return result.value;
|
|
2696
|
-
}
|
|
2697
|
-
} else if (superClass) {
|
|
2698
|
-
// If no constructor defined but has superClass, implicitly call super()
|
|
2699
|
-
// Call the superClass constructor properly - it's a classConstructor function
|
|
2700
|
-
superClass.call(instance, ...args);
|
|
2743
|
+
// Only use the returned object if it's an explicit return of an object (not the instance)
|
|
2744
|
+
if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
|
|
2745
|
+
return result.value;
|
|
2701
2746
|
}
|
|
2702
2747
|
|
|
2703
2748
|
return instance;
|
|
@@ -2708,6 +2753,12 @@ export class Interpreter {
|
|
|
2708
2753
|
classConstructor.__constructor = constructor;
|
|
2709
2754
|
}
|
|
2710
2755
|
|
|
2756
|
+
classConstructor.__instanceFields = instanceFields;
|
|
2757
|
+
classConstructor.__superClass = superClass;
|
|
2758
|
+
classConstructor.__constructInto = (instance, args) => {
|
|
2759
|
+
return interpreter.constructClassInto(classConstructor, instance, args, env);
|
|
2760
|
+
};
|
|
2761
|
+
|
|
2711
2762
|
// Set up prototype chain
|
|
2712
2763
|
if (superClass) {
|
|
2713
2764
|
classConstructor.prototype = Object.create(superClass.prototype);
|
|
@@ -2742,6 +2793,69 @@ export class Interpreter {
|
|
|
2742
2793
|
return classConstructor;
|
|
2743
2794
|
}
|
|
2744
2795
|
|
|
2796
|
+
constructClassInto(classConstructor, instance, args, env) {
|
|
2797
|
+
const superClass = classConstructor.__superClass;
|
|
2798
|
+
const constructor = classConstructor.__constructor;
|
|
2799
|
+
let fieldsInitialized = false;
|
|
2800
|
+
|
|
2801
|
+
const initializeOwnFields = () => {
|
|
2802
|
+
if (!fieldsInitialized) {
|
|
2803
|
+
this.initializeClassFields(classConstructor, instance, env);
|
|
2804
|
+
fieldsInitialized = true;
|
|
2805
|
+
}
|
|
2806
|
+
};
|
|
2807
|
+
|
|
2808
|
+
if (!superClass) {
|
|
2809
|
+
initializeOwnFields();
|
|
2810
|
+
if (constructor) {
|
|
2811
|
+
return this.callMethodFunction(constructor, instance, args, env, null);
|
|
2812
|
+
}
|
|
2813
|
+
return undefined;
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
if (constructor) {
|
|
2817
|
+
const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
|
|
2818
|
+
initializeOwnFields();
|
|
2819
|
+
return result;
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
this.initializeSuperClass(superClass, instance, args);
|
|
2823
|
+
initializeOwnFields();
|
|
2824
|
+
return undefined;
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
initializeSuperClass(superClass, instance, args) {
|
|
2828
|
+
if (superClass.__constructInto) {
|
|
2829
|
+
return superClass.__constructInto(instance, args);
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2832
|
+
// For native constructors like Error, use Reflect.construct and copy instance properties.
|
|
2833
|
+
const tempInstance = Reflect.construct(superClass, args, instance.constructor);
|
|
2834
|
+
Object.getOwnPropertyNames(tempInstance).forEach(name => {
|
|
2835
|
+
instance[name] = tempInstance[name];
|
|
2836
|
+
});
|
|
2837
|
+
return undefined;
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
initializeClassFields(classConstructor, instance, env) {
|
|
2841
|
+
for (const field of classConstructor.__instanceFields || []) {
|
|
2842
|
+
const fieldEnv = new Environment(env);
|
|
2843
|
+
fieldEnv.define('this', instance);
|
|
2844
|
+
const name = this.getClassFieldName(field, fieldEnv);
|
|
2845
|
+
instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
getClassFieldName(field, env) {
|
|
2850
|
+
if (field.computed) {
|
|
2851
|
+
return this.evaluate(field.key, env);
|
|
2852
|
+
}
|
|
2853
|
+
if (field.key.type === 'Identifier' || field.key.type === 'PrivateIdentifier') {
|
|
2854
|
+
return field.key.name;
|
|
2855
|
+
}
|
|
2856
|
+
return field.key.value;
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2745
2859
|
createMethodFunction(funcNode, env, className) {
|
|
2746
2860
|
const func = {
|
|
2747
2861
|
__isFunction: true,
|
|
@@ -2753,7 +2867,7 @@ export class Interpreter {
|
|
|
2753
2867
|
return func;
|
|
2754
2868
|
}
|
|
2755
2869
|
|
|
2756
|
-
callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
|
|
2870
|
+
callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
|
|
2757
2871
|
const funcEnv = new Environment(methodFunc.__env || env);
|
|
2758
2872
|
|
|
2759
2873
|
// Bind 'this'
|
|
@@ -2763,21 +2877,11 @@ export class Interpreter {
|
|
|
2763
2877
|
if (superClass) {
|
|
2764
2878
|
// Create a super function that calls the parent constructor
|
|
2765
2879
|
const superFunc = (...superArgs) => {
|
|
2766
|
-
|
|
2767
|
-
if (
|
|
2768
|
-
|
|
2769
|
-
}
|
|
2770
|
-
// Otherwise, call superClass as a regular constructor (for native/external classes)
|
|
2771
|
-
else {
|
|
2772
|
-
// For native constructors like Error, we need to use Reflect.construct
|
|
2773
|
-
// to properly initialize the instance properties
|
|
2774
|
-
const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
|
|
2775
|
-
// Copy properties from the temp instance to our thisContext
|
|
2776
|
-
Object.getOwnPropertyNames(tempInstance).forEach(name => {
|
|
2777
|
-
thisContext[name] = tempInstance[name];
|
|
2778
|
-
});
|
|
2880
|
+
const result = this.initializeSuperClass(superClass, thisContext, superArgs);
|
|
2881
|
+
if (afterSuper) {
|
|
2882
|
+
afterSuper();
|
|
2779
2883
|
}
|
|
2780
|
-
return undefined;
|
|
2884
|
+
return result && result.__explicitReturn ? result.value : undefined;
|
|
2781
2885
|
};
|
|
2782
2886
|
// Store both the function and mark it as super
|
|
2783
2887
|
superFunc.__isSuperConstructor = true;
|
|
@@ -2785,42 +2889,7 @@ export class Interpreter {
|
|
|
2785
2889
|
funcEnv.define('super', superFunc);
|
|
2786
2890
|
}
|
|
2787
2891
|
|
|
2788
|
-
|
|
2789
|
-
for (let i = 0; i < methodFunc.__params.length; i++) {
|
|
2790
|
-
const originalParam = methodFunc.__params[i];
|
|
2791
|
-
const param = originalParam.type === 'TSParameterProperty'
|
|
2792
|
-
? originalParam.parameter
|
|
2793
|
-
: originalParam;
|
|
2794
|
-
|
|
2795
|
-
if (param.type === 'Identifier') {
|
|
2796
|
-
// Simple parameter: function(x)
|
|
2797
|
-
funcEnv.define(param.name, args[i]);
|
|
2798
|
-
} else if (param.type === 'AssignmentPattern') {
|
|
2799
|
-
// Default parameter: function(x = defaultValue)
|
|
2800
|
-
const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
|
|
2801
|
-
funcEnv.define(param.left.name, value);
|
|
2802
|
-
} else if (param.type === 'RestElement') {
|
|
2803
|
-
// Rest parameter: function(...rest)
|
|
2804
|
-
funcEnv.define(param.argument.name, args.slice(i));
|
|
2805
|
-
break; // Rest element must be last
|
|
2806
|
-
} else if (param.type === 'ObjectPattern') {
|
|
2807
|
-
// Destructuring parameter: function({a, b})
|
|
2808
|
-
this.bindObjectPattern(param, args[i], funcEnv);
|
|
2809
|
-
} else if (param.type === 'ArrayPattern') {
|
|
2810
|
-
// Array destructuring parameter: function([a, b])
|
|
2811
|
-
this.bindArrayPattern(param, args[i], funcEnv);
|
|
2812
|
-
} else {
|
|
2813
|
-
// Fallback for simple parameter names
|
|
2814
|
-
funcEnv.define(param.name, args[i]);
|
|
2815
|
-
}
|
|
2816
|
-
|
|
2817
|
-
if (originalParam.type === 'TSParameterProperty') {
|
|
2818
|
-
const propertyName = getPatternName(originalParam.parameter);
|
|
2819
|
-
if (propertyName) {
|
|
2820
|
-
thisContext[propertyName] = funcEnv.get(propertyName);
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2892
|
+
this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
|
|
2824
2893
|
|
|
2825
2894
|
const result = this.evaluate(methodFunc.__body, funcEnv);
|
|
2826
2895
|
|
package/dist/index.cjs
CHANGED
|
@@ -11548,6 +11548,9 @@ function getPatternName(pattern) {
|
|
|
11548
11548
|
if (pattern.type === "TSParameterProperty") return getPatternName(pattern.parameter);
|
|
11549
11549
|
return pattern.name;
|
|
11550
11550
|
}
|
|
11551
|
+
function unwrapTSParameterProperty(param) {
|
|
11552
|
+
return (param == null ? void 0 : param.type) === "TSParameterProperty" ? param.parameter : param;
|
|
11553
|
+
}
|
|
11551
11554
|
function collectRuntimeIdentifierReferences(node) {
|
|
11552
11555
|
const references = /* @__PURE__ */ new Set();
|
|
11553
11556
|
const skipKeys = /* @__PURE__ */ new Set([
|
|
@@ -12850,24 +12853,7 @@ var Interpreter = class _Interpreter {
|
|
|
12850
12853
|
} else if (thisContext !== void 0) {
|
|
12851
12854
|
funcEnv.define("this", thisContext);
|
|
12852
12855
|
}
|
|
12853
|
-
|
|
12854
|
-
const param = metadata.params[i].type === "TSParameterProperty" ? metadata.params[i].parameter : metadata.params[i];
|
|
12855
|
-
if (param.type === "Identifier") {
|
|
12856
|
-
funcEnv.define(param.name, args[i]);
|
|
12857
|
-
} else if (param.type === "AssignmentPattern") {
|
|
12858
|
-
const value = args[i] !== void 0 ? args[i] : this.evaluate(param.right, funcEnv);
|
|
12859
|
-
funcEnv.define(param.left.name, value);
|
|
12860
|
-
} else if (param.type === "RestElement") {
|
|
12861
|
-
funcEnv.define(param.argument.name, args.slice(i));
|
|
12862
|
-
break;
|
|
12863
|
-
} else if (param.type === "ObjectPattern") {
|
|
12864
|
-
this.bindObjectPattern(param, args[i], funcEnv);
|
|
12865
|
-
} else if (param.type === "ArrayPattern") {
|
|
12866
|
-
this.bindArrayPattern(param, args[i], funcEnv);
|
|
12867
|
-
} else {
|
|
12868
|
-
funcEnv.define(param.name, args[i]);
|
|
12869
|
-
}
|
|
12870
|
-
}
|
|
12856
|
+
this.bindFunctionParameters(metadata.params, args, funcEnv);
|
|
12871
12857
|
if (metadata.async) {
|
|
12872
12858
|
if (this.executionController) {
|
|
12873
12859
|
this.executionController._pushCall(funcName);
|
|
@@ -13132,7 +13118,7 @@ var Interpreter = class _Interpreter {
|
|
|
13132
13118
|
env.define(prop.value.name, propValue, isConst);
|
|
13133
13119
|
} else if (prop.value.type === "AssignmentPattern") {
|
|
13134
13120
|
const finalValue = propValue !== void 0 ? propValue : this.evaluate(prop.value.right, env);
|
|
13135
|
-
|
|
13121
|
+
this.bindPattern(prop.value.left, finalValue, env, isConst);
|
|
13136
13122
|
} else if (prop.value.type === "ObjectPattern") {
|
|
13137
13123
|
this.bindObjectPattern(prop.value, propValue, env, isConst);
|
|
13138
13124
|
} else if (prop.value.type === "ArrayPattern") {
|
|
@@ -13156,7 +13142,7 @@ var Interpreter = class _Interpreter {
|
|
|
13156
13142
|
env.define(element.name, value[i], isConst);
|
|
13157
13143
|
} else if (element.type === "AssignmentPattern") {
|
|
13158
13144
|
const finalValue = value[i] !== void 0 ? value[i] : this.evaluate(element.right, env);
|
|
13159
|
-
|
|
13145
|
+
this.bindPattern(element.left, finalValue, env, isConst);
|
|
13160
13146
|
} else if (element.type === "ObjectPattern") {
|
|
13161
13147
|
this.bindObjectPattern(element, value[i], env, isConst);
|
|
13162
13148
|
} else if (element.type === "ArrayPattern") {
|
|
@@ -13164,6 +13150,67 @@ var Interpreter = class _Interpreter {
|
|
|
13164
13150
|
}
|
|
13165
13151
|
}
|
|
13166
13152
|
}
|
|
13153
|
+
bindPattern(pattern, value, env, isConst = false) {
|
|
13154
|
+
if (pattern.type === "Identifier") {
|
|
13155
|
+
env.define(pattern.name, value, isConst);
|
|
13156
|
+
} else if (pattern.type === "ObjectPattern") {
|
|
13157
|
+
this.bindObjectPattern(pattern, value, env, isConst);
|
|
13158
|
+
} else if (pattern.type === "ArrayPattern") {
|
|
13159
|
+
this.bindArrayPattern(pattern, value, env, isConst);
|
|
13160
|
+
} else if (pattern.type === "AssignmentPattern") {
|
|
13161
|
+
const finalValue = value !== void 0 ? value : this.evaluate(pattern.right, env);
|
|
13162
|
+
this.bindPattern(pattern.left, finalValue, env, isConst);
|
|
13163
|
+
} else if (pattern.type === "RestElement") {
|
|
13164
|
+
this.bindPattern(pattern.argument, value, env, isConst);
|
|
13165
|
+
}
|
|
13166
|
+
}
|
|
13167
|
+
bindFunctionParameters(params, args, env, thisContext = null) {
|
|
13168
|
+
for (let i = 0; i < params.length; i++) {
|
|
13169
|
+
const originalParam = params[i];
|
|
13170
|
+
const param = unwrapTSParameterProperty(originalParam);
|
|
13171
|
+
this.bindFunctionParameter(param, args[i], args.slice(i), env);
|
|
13172
|
+
if (originalParam.type === "TSParameterProperty" && thisContext) {
|
|
13173
|
+
const propertyName = getPatternName(originalParam.parameter);
|
|
13174
|
+
if (propertyName) {
|
|
13175
|
+
thisContext[propertyName] = env.get(propertyName);
|
|
13176
|
+
}
|
|
13177
|
+
}
|
|
13178
|
+
if (param.type === "RestElement") {
|
|
13179
|
+
break;
|
|
13180
|
+
}
|
|
13181
|
+
}
|
|
13182
|
+
}
|
|
13183
|
+
bindFunctionParameter(param, arg, restArgs, env) {
|
|
13184
|
+
if (param.type === "Identifier") {
|
|
13185
|
+
this.bindPattern(param, arg, env);
|
|
13186
|
+
return;
|
|
13187
|
+
}
|
|
13188
|
+
if (param.type === "AssignmentPattern") {
|
|
13189
|
+
const value = arg !== void 0 ? arg : this.evaluate(param.right, env);
|
|
13190
|
+
this.bindPattern(param.left, value, env);
|
|
13191
|
+
return;
|
|
13192
|
+
}
|
|
13193
|
+
if (param.type === "RestElement") {
|
|
13194
|
+
const target = param.argument;
|
|
13195
|
+
if (target.type === "Identifier") {
|
|
13196
|
+
env.define(target.name, restArgs);
|
|
13197
|
+
} else if (target.type === "ArrayPattern") {
|
|
13198
|
+
this.bindArrayPattern(target, restArgs, env);
|
|
13199
|
+
} else if (target.type === "ObjectPattern") {
|
|
13200
|
+
this.bindObjectPattern(target, restArgs, env);
|
|
13201
|
+
}
|
|
13202
|
+
return;
|
|
13203
|
+
}
|
|
13204
|
+
if (param.type === "ObjectPattern") {
|
|
13205
|
+
this.bindPattern(param, arg, env);
|
|
13206
|
+
return;
|
|
13207
|
+
}
|
|
13208
|
+
if (param.type === "ArrayPattern") {
|
|
13209
|
+
this.bindPattern(param, arg, env);
|
|
13210
|
+
return;
|
|
13211
|
+
}
|
|
13212
|
+
env.define(param.name, arg);
|
|
13213
|
+
}
|
|
13167
13214
|
evaluateFunctionDeclaration(node, env) {
|
|
13168
13215
|
const funcMetadata = {
|
|
13169
13216
|
__isFunction: true,
|
|
@@ -13573,6 +13620,7 @@ var Interpreter = class _Interpreter {
|
|
|
13573
13620
|
let constructor = null;
|
|
13574
13621
|
const methods = {};
|
|
13575
13622
|
const staticMethods = {};
|
|
13623
|
+
const instanceFields = [];
|
|
13576
13624
|
for (const member of node.body.body) {
|
|
13577
13625
|
if (member.type === "MethodDefinition") {
|
|
13578
13626
|
const methodName = member.key.name || member.key.value;
|
|
@@ -13584,23 +13632,26 @@ var Interpreter = class _Interpreter {
|
|
|
13584
13632
|
} else {
|
|
13585
13633
|
methods[methodName] = methodFunc;
|
|
13586
13634
|
}
|
|
13635
|
+
} else if (member.type === "PropertyDefinition" && !member.static && !member.declare && !member.abstract) {
|
|
13636
|
+
instanceFields.push(member);
|
|
13587
13637
|
}
|
|
13588
13638
|
}
|
|
13589
13639
|
const classConstructor = function(...args) {
|
|
13590
13640
|
const instance = Object.create(classConstructor.prototype);
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
return result.value;
|
|
13595
|
-
}
|
|
13596
|
-
} else if (superClass) {
|
|
13597
|
-
superClass.call(instance, ...args);
|
|
13641
|
+
const result = interpreter.constructClassInto(classConstructor, instance, args, env);
|
|
13642
|
+
if (result && result.__explicitReturn && result.value && typeof result.value === "object" && result.value !== instance) {
|
|
13643
|
+
return result.value;
|
|
13598
13644
|
}
|
|
13599
13645
|
return instance;
|
|
13600
13646
|
};
|
|
13601
13647
|
if (constructor) {
|
|
13602
13648
|
classConstructor.__constructor = constructor;
|
|
13603
13649
|
}
|
|
13650
|
+
classConstructor.__instanceFields = instanceFields;
|
|
13651
|
+
classConstructor.__superClass = superClass;
|
|
13652
|
+
classConstructor.__constructInto = (instance, args) => {
|
|
13653
|
+
return interpreter.constructClassInto(classConstructor, instance, args, env);
|
|
13654
|
+
};
|
|
13604
13655
|
if (superClass) {
|
|
13605
13656
|
classConstructor.prototype = Object.create(superClass.prototype);
|
|
13606
13657
|
classConstructor.prototype.constructor = classConstructor;
|
|
@@ -13626,6 +13677,59 @@ var Interpreter = class _Interpreter {
|
|
|
13626
13677
|
classConstructor.__className = className;
|
|
13627
13678
|
return classConstructor;
|
|
13628
13679
|
}
|
|
13680
|
+
constructClassInto(classConstructor, instance, args, env) {
|
|
13681
|
+
const superClass = classConstructor.__superClass;
|
|
13682
|
+
const constructor = classConstructor.__constructor;
|
|
13683
|
+
let fieldsInitialized = false;
|
|
13684
|
+
const initializeOwnFields = () => {
|
|
13685
|
+
if (!fieldsInitialized) {
|
|
13686
|
+
this.initializeClassFields(classConstructor, instance, env);
|
|
13687
|
+
fieldsInitialized = true;
|
|
13688
|
+
}
|
|
13689
|
+
};
|
|
13690
|
+
if (!superClass) {
|
|
13691
|
+
initializeOwnFields();
|
|
13692
|
+
if (constructor) {
|
|
13693
|
+
return this.callMethodFunction(constructor, instance, args, env, null);
|
|
13694
|
+
}
|
|
13695
|
+
return void 0;
|
|
13696
|
+
}
|
|
13697
|
+
if (constructor) {
|
|
13698
|
+
const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
|
|
13699
|
+
initializeOwnFields();
|
|
13700
|
+
return result;
|
|
13701
|
+
}
|
|
13702
|
+
this.initializeSuperClass(superClass, instance, args);
|
|
13703
|
+
initializeOwnFields();
|
|
13704
|
+
return void 0;
|
|
13705
|
+
}
|
|
13706
|
+
initializeSuperClass(superClass, instance, args) {
|
|
13707
|
+
if (superClass.__constructInto) {
|
|
13708
|
+
return superClass.__constructInto(instance, args);
|
|
13709
|
+
}
|
|
13710
|
+
const tempInstance = Reflect.construct(superClass, args, instance.constructor);
|
|
13711
|
+
Object.getOwnPropertyNames(tempInstance).forEach((name) => {
|
|
13712
|
+
instance[name] = tempInstance[name];
|
|
13713
|
+
});
|
|
13714
|
+
return void 0;
|
|
13715
|
+
}
|
|
13716
|
+
initializeClassFields(classConstructor, instance, env) {
|
|
13717
|
+
for (const field of classConstructor.__instanceFields || []) {
|
|
13718
|
+
const fieldEnv = new Environment(env);
|
|
13719
|
+
fieldEnv.define("this", instance);
|
|
13720
|
+
const name = this.getClassFieldName(field, fieldEnv);
|
|
13721
|
+
instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : void 0;
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
getClassFieldName(field, env) {
|
|
13725
|
+
if (field.computed) {
|
|
13726
|
+
return this.evaluate(field.key, env);
|
|
13727
|
+
}
|
|
13728
|
+
if (field.key.type === "Identifier" || field.key.type === "PrivateIdentifier") {
|
|
13729
|
+
return field.key.name;
|
|
13730
|
+
}
|
|
13731
|
+
return field.key.value;
|
|
13732
|
+
}
|
|
13629
13733
|
createMethodFunction(funcNode, env, className) {
|
|
13630
13734
|
const func = {
|
|
13631
13735
|
__isFunction: true,
|
|
@@ -13636,50 +13740,22 @@ var Interpreter = class _Interpreter {
|
|
|
13636
13740
|
};
|
|
13637
13741
|
return func;
|
|
13638
13742
|
}
|
|
13639
|
-
callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
|
|
13743
|
+
callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
|
|
13640
13744
|
const funcEnv = new Environment(methodFunc.__env || env);
|
|
13641
13745
|
funcEnv.define("this", thisContext);
|
|
13642
13746
|
if (superClass) {
|
|
13643
13747
|
const superFunc = (...superArgs) => {
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
|
|
13648
|
-
Object.getOwnPropertyNames(tempInstance).forEach((name) => {
|
|
13649
|
-
thisContext[name] = tempInstance[name];
|
|
13650
|
-
});
|
|
13748
|
+
const result2 = this.initializeSuperClass(superClass, thisContext, superArgs);
|
|
13749
|
+
if (afterSuper) {
|
|
13750
|
+
afterSuper();
|
|
13651
13751
|
}
|
|
13652
|
-
return void 0;
|
|
13752
|
+
return result2 && result2.__explicitReturn ? result2.value : void 0;
|
|
13653
13753
|
};
|
|
13654
13754
|
superFunc.__isSuperConstructor = true;
|
|
13655
13755
|
superFunc.__superClass = superClass;
|
|
13656
13756
|
funcEnv.define("super", superFunc);
|
|
13657
13757
|
}
|
|
13658
|
-
|
|
13659
|
-
const originalParam = methodFunc.__params[i];
|
|
13660
|
-
const param = originalParam.type === "TSParameterProperty" ? originalParam.parameter : originalParam;
|
|
13661
|
-
if (param.type === "Identifier") {
|
|
13662
|
-
funcEnv.define(param.name, args[i]);
|
|
13663
|
-
} else if (param.type === "AssignmentPattern") {
|
|
13664
|
-
const value = args[i] !== void 0 ? args[i] : this.evaluate(param.right, funcEnv);
|
|
13665
|
-
funcEnv.define(param.left.name, value);
|
|
13666
|
-
} else if (param.type === "RestElement") {
|
|
13667
|
-
funcEnv.define(param.argument.name, args.slice(i));
|
|
13668
|
-
break;
|
|
13669
|
-
} else if (param.type === "ObjectPattern") {
|
|
13670
|
-
this.bindObjectPattern(param, args[i], funcEnv);
|
|
13671
|
-
} else if (param.type === "ArrayPattern") {
|
|
13672
|
-
this.bindArrayPattern(param, args[i], funcEnv);
|
|
13673
|
-
} else {
|
|
13674
|
-
funcEnv.define(param.name, args[i]);
|
|
13675
|
-
}
|
|
13676
|
-
if (originalParam.type === "TSParameterProperty") {
|
|
13677
|
-
const propertyName = getPatternName(originalParam.parameter);
|
|
13678
|
-
if (propertyName) {
|
|
13679
|
-
thisContext[propertyName] = funcEnv.get(propertyName);
|
|
13680
|
-
}
|
|
13681
|
-
}
|
|
13682
|
-
}
|
|
13758
|
+
this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
|
|
13683
13759
|
const result = this.evaluate(methodFunc.__body, funcEnv);
|
|
13684
13760
|
if (result instanceof ReturnValue) {
|
|
13685
13761
|
return { __explicitReturn: true, value: result.value };
|