jslike 1.8.3 → 1.8.5

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.
@@ -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
- // Bind parameters
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
- env.define(prop.value.left.name, finalValue, isConst);
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
- env.define(element.left.name, finalValue, isConst);
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,
@@ -2719,7 +2768,7 @@ export class Interpreter {
2719
2768
  // Add methods to prototype
2720
2769
  for (const [name, method] of Object.entries(methods)) {
2721
2770
  classConstructor.prototype[name] = function(...args) {
2722
- const result = interpreter.callMethodFunction(method, this, args, env);
2771
+ const result = interpreter.callMethodFunction(method, this, args, env, superClass);
2723
2772
  // Unwrap explicit return marker
2724
2773
  if (result && result.__explicitReturn) {
2725
2774
  return result.value;
@@ -2792,6 +2841,9 @@ export class Interpreter {
2792
2841
  for (const field of classConstructor.__instanceFields || []) {
2793
2842
  const fieldEnv = new Environment(env);
2794
2843
  fieldEnv.define('this', instance);
2844
+ if (classConstructor.__superClass) {
2845
+ fieldEnv.define('super', this.createSuperBinding(classConstructor.__superClass, instance, false));
2846
+ }
2795
2847
  const name = this.getClassFieldName(field, fieldEnv);
2796
2848
  instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
2797
2849
  }
@@ -2807,6 +2859,38 @@ export class Interpreter {
2807
2859
  return field.key.value;
2808
2860
  }
2809
2861
 
2862
+ createSuperBinding(superClass, thisContext, allowConstructor = false, afterSuper = null) {
2863
+ const superConstructor = (...superArgs) => {
2864
+ if (!allowConstructor) {
2865
+ throw new ReferenceError("'super' keyword is unexpected here");
2866
+ }
2867
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
2868
+ if (afterSuper) {
2869
+ afterSuper();
2870
+ }
2871
+ return result && result.__explicitReturn ? result.value : undefined;
2872
+ };
2873
+
2874
+ superConstructor.__isSuperConstructor = true;
2875
+ superConstructor.__superClass = superClass;
2876
+
2877
+ return new Proxy(superConstructor, {
2878
+ get(target, prop, receiver) {
2879
+ if (prop in target) {
2880
+ return Reflect.get(target, prop, receiver);
2881
+ }
2882
+
2883
+ const prototype = superClass?.prototype;
2884
+ if (!prototype) {
2885
+ return undefined;
2886
+ }
2887
+
2888
+ const value = Reflect.get(prototype, prop, thisContext);
2889
+ return typeof value === 'function' ? value.bind(thisContext) : value;
2890
+ }
2891
+ });
2892
+ }
2893
+
2810
2894
  createMethodFunction(funcNode, env, className) {
2811
2895
  const func = {
2812
2896
  __isFunction: true,
@@ -2826,57 +2910,11 @@ export class Interpreter {
2826
2910
 
2827
2911
  // Bind 'super' if superClass exists
2828
2912
  if (superClass) {
2829
- // Create a super function that calls the parent constructor
2830
- const superFunc = (...superArgs) => {
2831
- const result = this.initializeSuperClass(superClass, thisContext, superArgs);
2832
- if (afterSuper) {
2833
- afterSuper();
2834
- }
2835
- return result && result.__explicitReturn ? result.value : undefined;
2836
- };
2837
- // Store both the function and mark it as super
2838
- superFunc.__isSuperConstructor = true;
2839
- superFunc.__superClass = superClass;
2840
- funcEnv.define('super', superFunc);
2841
- }
2842
-
2843
- // Bind parameters
2844
- for (let i = 0; i < methodFunc.__params.length; i++) {
2845
- const originalParam = methodFunc.__params[i];
2846
- const param = originalParam.type === 'TSParameterProperty'
2847
- ? originalParam.parameter
2848
- : originalParam;
2849
-
2850
- if (param.type === 'Identifier') {
2851
- // Simple parameter: function(x)
2852
- funcEnv.define(param.name, args[i]);
2853
- } else if (param.type === 'AssignmentPattern') {
2854
- // Default parameter: function(x = defaultValue)
2855
- const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
2856
- funcEnv.define(param.left.name, value);
2857
- } else if (param.type === 'RestElement') {
2858
- // Rest parameter: function(...rest)
2859
- funcEnv.define(param.argument.name, args.slice(i));
2860
- break; // Rest element must be last
2861
- } else if (param.type === 'ObjectPattern') {
2862
- // Destructuring parameter: function({a, b})
2863
- this.bindObjectPattern(param, args[i], funcEnv);
2864
- } else if (param.type === 'ArrayPattern') {
2865
- // Array destructuring parameter: function([a, b])
2866
- this.bindArrayPattern(param, args[i], funcEnv);
2867
- } else {
2868
- // Fallback for simple parameter names
2869
- funcEnv.define(param.name, args[i]);
2870
- }
2871
-
2872
- if (originalParam.type === 'TSParameterProperty') {
2873
- const propertyName = getPatternName(originalParam.parameter);
2874
- if (propertyName) {
2875
- thisContext[propertyName] = funcEnv.get(propertyName);
2876
- }
2877
- }
2913
+ funcEnv.define('super', this.createSuperBinding(superClass, thisContext, true, afterSuper));
2878
2914
  }
2879
2915
 
2916
+ this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
2917
+
2880
2918
  const result = this.evaluate(methodFunc.__body, funcEnv);
2881
2919
 
2882
2920
  if (result instanceof ReturnValue) {
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
- for (let i = 0; i < metadata.params.length; i++) {
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
- env.define(prop.value.left.name, finalValue, isConst);
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
- env.define(element.left.name, finalValue, isConst);
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,
@@ -13611,7 +13658,7 @@ var Interpreter = class _Interpreter {
13611
13658
  }
13612
13659
  for (const [name, method] of Object.entries(methods)) {
13613
13660
  classConstructor.prototype[name] = function(...args) {
13614
- const result = interpreter.callMethodFunction(method, this, args, env);
13661
+ const result = interpreter.callMethodFunction(method, this, args, env, superClass);
13615
13662
  if (result && result.__explicitReturn) {
13616
13663
  return result.value;
13617
13664
  }
@@ -13670,6 +13717,9 @@ var Interpreter = class _Interpreter {
13670
13717
  for (const field of classConstructor.__instanceFields || []) {
13671
13718
  const fieldEnv = new Environment(env);
13672
13719
  fieldEnv.define("this", instance);
13720
+ if (classConstructor.__superClass) {
13721
+ fieldEnv.define("super", this.createSuperBinding(classConstructor.__superClass, instance, false));
13722
+ }
13673
13723
  const name = this.getClassFieldName(field, fieldEnv);
13674
13724
  instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : void 0;
13675
13725
  }
@@ -13683,6 +13733,33 @@ var Interpreter = class _Interpreter {
13683
13733
  }
13684
13734
  return field.key.value;
13685
13735
  }
13736
+ createSuperBinding(superClass, thisContext, allowConstructor = false, afterSuper = null) {
13737
+ const superConstructor = (...superArgs) => {
13738
+ if (!allowConstructor) {
13739
+ throw new ReferenceError("'super' keyword is unexpected here");
13740
+ }
13741
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
13742
+ if (afterSuper) {
13743
+ afterSuper();
13744
+ }
13745
+ return result && result.__explicitReturn ? result.value : void 0;
13746
+ };
13747
+ superConstructor.__isSuperConstructor = true;
13748
+ superConstructor.__superClass = superClass;
13749
+ return new Proxy(superConstructor, {
13750
+ get(target, prop, receiver) {
13751
+ if (prop in target) {
13752
+ return Reflect.get(target, prop, receiver);
13753
+ }
13754
+ const prototype = superClass == null ? void 0 : superClass.prototype;
13755
+ if (!prototype) {
13756
+ return void 0;
13757
+ }
13758
+ const value = Reflect.get(prototype, prop, thisContext);
13759
+ return typeof value === "function" ? value.bind(thisContext) : value;
13760
+ }
13761
+ });
13762
+ }
13686
13763
  createMethodFunction(funcNode, env, className) {
13687
13764
  const func = {
13688
13765
  __isFunction: true,
@@ -13697,42 +13774,9 @@ var Interpreter = class _Interpreter {
13697
13774
  const funcEnv = new Environment(methodFunc.__env || env);
13698
13775
  funcEnv.define("this", thisContext);
13699
13776
  if (superClass) {
13700
- const superFunc = (...superArgs) => {
13701
- const result2 = this.initializeSuperClass(superClass, thisContext, superArgs);
13702
- if (afterSuper) {
13703
- afterSuper();
13704
- }
13705
- return result2 && result2.__explicitReturn ? result2.value : void 0;
13706
- };
13707
- superFunc.__isSuperConstructor = true;
13708
- superFunc.__superClass = superClass;
13709
- funcEnv.define("super", superFunc);
13710
- }
13711
- for (let i = 0; i < methodFunc.__params.length; i++) {
13712
- const originalParam = methodFunc.__params[i];
13713
- const param = originalParam.type === "TSParameterProperty" ? originalParam.parameter : originalParam;
13714
- if (param.type === "Identifier") {
13715
- funcEnv.define(param.name, args[i]);
13716
- } else if (param.type === "AssignmentPattern") {
13717
- const value = args[i] !== void 0 ? args[i] : this.evaluate(param.right, funcEnv);
13718
- funcEnv.define(param.left.name, value);
13719
- } else if (param.type === "RestElement") {
13720
- funcEnv.define(param.argument.name, args.slice(i));
13721
- break;
13722
- } else if (param.type === "ObjectPattern") {
13723
- this.bindObjectPattern(param, args[i], funcEnv);
13724
- } else if (param.type === "ArrayPattern") {
13725
- this.bindArrayPattern(param, args[i], funcEnv);
13726
- } else {
13727
- funcEnv.define(param.name, args[i]);
13728
- }
13729
- if (originalParam.type === "TSParameterProperty") {
13730
- const propertyName = getPatternName(originalParam.parameter);
13731
- if (propertyName) {
13732
- thisContext[propertyName] = funcEnv.get(propertyName);
13733
- }
13734
- }
13777
+ funcEnv.define("super", this.createSuperBinding(superClass, thisContext, true, afterSuper));
13735
13778
  }
13779
+ this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
13736
13780
  const result = this.evaluate(methodFunc.__body, funcEnv);
13737
13781
  if (result instanceof ReturnValue) {
13738
13782
  return { __explicitReturn: true, value: result.value };
package/dist/index.d.cts CHANGED
@@ -12250,6 +12250,10 @@ function getPatternName(pattern) {
12250
12250
  return pattern.name;
12251
12251
  }
12252
12252
 
12253
+ function unwrapTSParameterProperty(param) {
12254
+ return param?.type === 'TSParameterProperty' ? param.parameter : param;
12255
+ }
12256
+
12253
12257
  function collectRuntimeIdentifierReferences(node) {
12254
12258
  const references = new Set();
12255
12259
  const skipKeys = new Set([
@@ -13871,34 +13875,7 @@ class Interpreter {
13871
13875
  funcEnv.define('this', thisContext);
13872
13876
  }
13873
13877
 
13874
- // Bind parameters
13875
- for (let i = 0; i < metadata.params.length; i++) {
13876
- const param = metadata.params[i].type === 'TSParameterProperty'
13877
- ? metadata.params[i].parameter
13878
- : metadata.params[i];
13879
-
13880
- if (param.type === 'Identifier') {
13881
- // Simple parameter: function(x)
13882
- funcEnv.define(param.name, args[i]);
13883
- } else if (param.type === 'AssignmentPattern') {
13884
- // Default parameter: function(x = defaultValue)
13885
- const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
13886
- funcEnv.define(param.left.name, value);
13887
- } else if (param.type === 'RestElement') {
13888
- // Rest parameter: function(...rest)
13889
- funcEnv.define(param.argument.name, args.slice(i));
13890
- break; // Rest element must be last
13891
- } else if (param.type === 'ObjectPattern') {
13892
- // Destructuring parameter: function({a, b})
13893
- this.bindObjectPattern(param, args[i], funcEnv);
13894
- } else if (param.type === 'ArrayPattern') {
13895
- // Array destructuring parameter: function([a, b])
13896
- this.bindArrayPattern(param, args[i], funcEnv);
13897
- } else {
13898
- // Fallback for simple parameter names
13899
- funcEnv.define(param.name, args[i]);
13900
- }
13901
- }
13878
+ this.bindFunctionParameters(metadata.params, args, funcEnv);
13902
13879
 
13903
13880
  // Execute function body
13904
13881
  // If async, use async evaluation and return a promise
@@ -14255,7 +14232,7 @@ class Interpreter {
14255
14232
  const finalValue = propValue !== undefined
14256
14233
  ? propValue
14257
14234
  : this.evaluate(prop.value.right, env);
14258
- env.define(prop.value.left.name, finalValue, isConst);
14235
+ this.bindPattern(prop.value.left, finalValue, env, isConst);
14259
14236
  } else if (prop.value.type === 'ObjectPattern') {
14260
14237
  this.bindObjectPattern(prop.value, propValue, env, isConst);
14261
14238
  } else if (prop.value.type === 'ArrayPattern') {
@@ -14286,7 +14263,7 @@ class Interpreter {
14286
14263
  const finalValue = value[i] !== undefined
14287
14264
  ? value[i]
14288
14265
  : this.evaluate(element.right, env);
14289
- env.define(element.left.name, finalValue, isConst);
14266
+ this.bindPattern(element.left, finalValue, env, isConst);
14290
14267
  } else if (element.type === 'ObjectPattern') {
14291
14268
  this.bindObjectPattern(element, value[i], env, isConst);
14292
14269
  } else if (element.type === 'ArrayPattern') {
@@ -14295,6 +14272,78 @@ class Interpreter {
14295
14272
  }
14296
14273
  }
14297
14274
 
14275
+ bindPattern(pattern, value, env, isConst = false) {
14276
+ if (pattern.type === 'Identifier') {
14277
+ env.define(pattern.name, value, isConst);
14278
+ } else if (pattern.type === 'ObjectPattern') {
14279
+ this.bindObjectPattern(pattern, value, env, isConst);
14280
+ } else if (pattern.type === 'ArrayPattern') {
14281
+ this.bindArrayPattern(pattern, value, env, isConst);
14282
+ } else if (pattern.type === 'AssignmentPattern') {
14283
+ const finalValue = value !== undefined ? value : this.evaluate(pattern.right, env);
14284
+ this.bindPattern(pattern.left, finalValue, env, isConst);
14285
+ } else if (pattern.type === 'RestElement') {
14286
+ this.bindPattern(pattern.argument, value, env, isConst);
14287
+ }
14288
+ }
14289
+
14290
+ bindFunctionParameters(params, args, env, thisContext = null) {
14291
+ for (let i = 0; i < params.length; i++) {
14292
+ const originalParam = params[i];
14293
+ const param = unwrapTSParameterProperty(originalParam);
14294
+
14295
+ this.bindFunctionParameter(param, args[i], args.slice(i), env);
14296
+
14297
+ if (originalParam.type === 'TSParameterProperty' && thisContext) {
14298
+ const propertyName = getPatternName(originalParam.parameter);
14299
+ if (propertyName) {
14300
+ thisContext[propertyName] = env.get(propertyName);
14301
+ }
14302
+ }
14303
+
14304
+ if (param.type === 'RestElement') {
14305
+ break;
14306
+ }
14307
+ }
14308
+ }
14309
+
14310
+ bindFunctionParameter(param, arg, restArgs, env) {
14311
+ if (param.type === 'Identifier') {
14312
+ this.bindPattern(param, arg, env);
14313
+ return;
14314
+ }
14315
+
14316
+ if (param.type === 'AssignmentPattern') {
14317
+ const value = arg !== undefined ? arg : this.evaluate(param.right, env);
14318
+ this.bindPattern(param.left, value, env);
14319
+ return;
14320
+ }
14321
+
14322
+ if (param.type === 'RestElement') {
14323
+ const target = param.argument;
14324
+ if (target.type === 'Identifier') {
14325
+ env.define(target.name, restArgs);
14326
+ } else if (target.type === 'ArrayPattern') {
14327
+ this.bindArrayPattern(target, restArgs, env);
14328
+ } else if (target.type === 'ObjectPattern') {
14329
+ this.bindObjectPattern(target, restArgs, env);
14330
+ }
14331
+ return;
14332
+ }
14333
+
14334
+ if (param.type === 'ObjectPattern') {
14335
+ this.bindPattern(param, arg, env);
14336
+ return;
14337
+ }
14338
+
14339
+ if (param.type === 'ArrayPattern') {
14340
+ this.bindPattern(param, arg, env);
14341
+ return;
14342
+ }
14343
+
14344
+ env.define(param.name, arg);
14345
+ }
14346
+
14298
14347
  evaluateFunctionDeclaration(node, env) {
14299
14348
  const funcMetadata = {
14300
14349
  __isFunction: true,
@@ -14912,7 +14961,7 @@ class Interpreter {
14912
14961
  // Add methods to prototype
14913
14962
  for (const [name, method] of Object.entries(methods)) {
14914
14963
  classConstructor.prototype[name] = function(...args) {
14915
- const result = interpreter.callMethodFunction(method, this, args, env);
14964
+ const result = interpreter.callMethodFunction(method, this, args, env, superClass);
14916
14965
  // Unwrap explicit return marker
14917
14966
  if (result && result.__explicitReturn) {
14918
14967
  return result.value;
@@ -14985,6 +15034,9 @@ class Interpreter {
14985
15034
  for (const field of classConstructor.__instanceFields || []) {
14986
15035
  const fieldEnv = new Environment(env);
14987
15036
  fieldEnv.define('this', instance);
15037
+ if (classConstructor.__superClass) {
15038
+ fieldEnv.define('super', this.createSuperBinding(classConstructor.__superClass, instance, false));
15039
+ }
14988
15040
  const name = this.getClassFieldName(field, fieldEnv);
14989
15041
  instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
14990
15042
  }
@@ -15000,6 +15052,38 @@ class Interpreter {
15000
15052
  return field.key.value;
15001
15053
  }
15002
15054
 
15055
+ createSuperBinding(superClass, thisContext, allowConstructor = false, afterSuper = null) {
15056
+ const superConstructor = (...superArgs) => {
15057
+ if (!allowConstructor) {
15058
+ throw new ReferenceError("'super' keyword is unexpected here");
15059
+ }
15060
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15061
+ if (afterSuper) {
15062
+ afterSuper();
15063
+ }
15064
+ return result && result.__explicitReturn ? result.value : undefined;
15065
+ };
15066
+
15067
+ superConstructor.__isSuperConstructor = true;
15068
+ superConstructor.__superClass = superClass;
15069
+
15070
+ return new Proxy(superConstructor, {
15071
+ get(target, prop, receiver) {
15072
+ if (prop in target) {
15073
+ return Reflect.get(target, prop, receiver);
15074
+ }
15075
+
15076
+ const prototype = superClass?.prototype;
15077
+ if (!prototype) {
15078
+ return undefined;
15079
+ }
15080
+
15081
+ const value = Reflect.get(prototype, prop, thisContext);
15082
+ return typeof value === 'function' ? value.bind(thisContext) : value;
15083
+ }
15084
+ });
15085
+ }
15086
+
15003
15087
  createMethodFunction(funcNode, env, className) {
15004
15088
  const func = {
15005
15089
  __isFunction: true,
@@ -15019,57 +15103,11 @@ class Interpreter {
15019
15103
 
15020
15104
  // Bind 'super' if superClass exists
15021
15105
  if (superClass) {
15022
- // Create a super function that calls the parent constructor
15023
- const superFunc = (...superArgs) => {
15024
- const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15025
- if (afterSuper) {
15026
- afterSuper();
15027
- }
15028
- return result && result.__explicitReturn ? result.value : undefined;
15029
- };
15030
- // Store both the function and mark it as super
15031
- superFunc.__isSuperConstructor = true;
15032
- superFunc.__superClass = superClass;
15033
- funcEnv.define('super', superFunc);
15034
- }
15035
-
15036
- // Bind parameters
15037
- for (let i = 0; i < methodFunc.__params.length; i++) {
15038
- const originalParam = methodFunc.__params[i];
15039
- const param = originalParam.type === 'TSParameterProperty'
15040
- ? originalParam.parameter
15041
- : originalParam;
15042
-
15043
- if (param.type === 'Identifier') {
15044
- // Simple parameter: function(x)
15045
- funcEnv.define(param.name, args[i]);
15046
- } else if (param.type === 'AssignmentPattern') {
15047
- // Default parameter: function(x = defaultValue)
15048
- const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
15049
- funcEnv.define(param.left.name, value);
15050
- } else if (param.type === 'RestElement') {
15051
- // Rest parameter: function(...rest)
15052
- funcEnv.define(param.argument.name, args.slice(i));
15053
- break; // Rest element must be last
15054
- } else if (param.type === 'ObjectPattern') {
15055
- // Destructuring parameter: function({a, b})
15056
- this.bindObjectPattern(param, args[i], funcEnv);
15057
- } else if (param.type === 'ArrayPattern') {
15058
- // Array destructuring parameter: function([a, b])
15059
- this.bindArrayPattern(param, args[i], funcEnv);
15060
- } else {
15061
- // Fallback for simple parameter names
15062
- funcEnv.define(param.name, args[i]);
15063
- }
15064
-
15065
- if (originalParam.type === 'TSParameterProperty') {
15066
- const propertyName = getPatternName(originalParam.parameter);
15067
- if (propertyName) {
15068
- thisContext[propertyName] = funcEnv.get(propertyName);
15069
- }
15070
- }
15106
+ funcEnv.define('super', this.createSuperBinding(superClass, thisContext, true, afterSuper));
15071
15107
  }
15072
15108
 
15109
+ this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
15110
+
15073
15111
  const result = this.evaluate(methodFunc.__body, funcEnv);
15074
15112
 
15075
15113
  if (result instanceof ReturnValue) {
package/dist/index.d.ts CHANGED
@@ -12250,6 +12250,10 @@ function getPatternName(pattern) {
12250
12250
  return pattern.name;
12251
12251
  }
12252
12252
 
12253
+ function unwrapTSParameterProperty(param) {
12254
+ return param?.type === 'TSParameterProperty' ? param.parameter : param;
12255
+ }
12256
+
12253
12257
  function collectRuntimeIdentifierReferences(node) {
12254
12258
  const references = new Set();
12255
12259
  const skipKeys = new Set([
@@ -13871,34 +13875,7 @@ class Interpreter {
13871
13875
  funcEnv.define('this', thisContext);
13872
13876
  }
13873
13877
 
13874
- // Bind parameters
13875
- for (let i = 0; i < metadata.params.length; i++) {
13876
- const param = metadata.params[i].type === 'TSParameterProperty'
13877
- ? metadata.params[i].parameter
13878
- : metadata.params[i];
13879
-
13880
- if (param.type === 'Identifier') {
13881
- // Simple parameter: function(x)
13882
- funcEnv.define(param.name, args[i]);
13883
- } else if (param.type === 'AssignmentPattern') {
13884
- // Default parameter: function(x = defaultValue)
13885
- const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
13886
- funcEnv.define(param.left.name, value);
13887
- } else if (param.type === 'RestElement') {
13888
- // Rest parameter: function(...rest)
13889
- funcEnv.define(param.argument.name, args.slice(i));
13890
- break; // Rest element must be last
13891
- } else if (param.type === 'ObjectPattern') {
13892
- // Destructuring parameter: function({a, b})
13893
- this.bindObjectPattern(param, args[i], funcEnv);
13894
- } else if (param.type === 'ArrayPattern') {
13895
- // Array destructuring parameter: function([a, b])
13896
- this.bindArrayPattern(param, args[i], funcEnv);
13897
- } else {
13898
- // Fallback for simple parameter names
13899
- funcEnv.define(param.name, args[i]);
13900
- }
13901
- }
13878
+ this.bindFunctionParameters(metadata.params, args, funcEnv);
13902
13879
 
13903
13880
  // Execute function body
13904
13881
  // If async, use async evaluation and return a promise
@@ -14255,7 +14232,7 @@ class Interpreter {
14255
14232
  const finalValue = propValue !== undefined
14256
14233
  ? propValue
14257
14234
  : this.evaluate(prop.value.right, env);
14258
- env.define(prop.value.left.name, finalValue, isConst);
14235
+ this.bindPattern(prop.value.left, finalValue, env, isConst);
14259
14236
  } else if (prop.value.type === 'ObjectPattern') {
14260
14237
  this.bindObjectPattern(prop.value, propValue, env, isConst);
14261
14238
  } else if (prop.value.type === 'ArrayPattern') {
@@ -14286,7 +14263,7 @@ class Interpreter {
14286
14263
  const finalValue = value[i] !== undefined
14287
14264
  ? value[i]
14288
14265
  : this.evaluate(element.right, env);
14289
- env.define(element.left.name, finalValue, isConst);
14266
+ this.bindPattern(element.left, finalValue, env, isConst);
14290
14267
  } else if (element.type === 'ObjectPattern') {
14291
14268
  this.bindObjectPattern(element, value[i], env, isConst);
14292
14269
  } else if (element.type === 'ArrayPattern') {
@@ -14295,6 +14272,78 @@ class Interpreter {
14295
14272
  }
14296
14273
  }
14297
14274
 
14275
+ bindPattern(pattern, value, env, isConst = false) {
14276
+ if (pattern.type === 'Identifier') {
14277
+ env.define(pattern.name, value, isConst);
14278
+ } else if (pattern.type === 'ObjectPattern') {
14279
+ this.bindObjectPattern(pattern, value, env, isConst);
14280
+ } else if (pattern.type === 'ArrayPattern') {
14281
+ this.bindArrayPattern(pattern, value, env, isConst);
14282
+ } else if (pattern.type === 'AssignmentPattern') {
14283
+ const finalValue = value !== undefined ? value : this.evaluate(pattern.right, env);
14284
+ this.bindPattern(pattern.left, finalValue, env, isConst);
14285
+ } else if (pattern.type === 'RestElement') {
14286
+ this.bindPattern(pattern.argument, value, env, isConst);
14287
+ }
14288
+ }
14289
+
14290
+ bindFunctionParameters(params, args, env, thisContext = null) {
14291
+ for (let i = 0; i < params.length; i++) {
14292
+ const originalParam = params[i];
14293
+ const param = unwrapTSParameterProperty(originalParam);
14294
+
14295
+ this.bindFunctionParameter(param, args[i], args.slice(i), env);
14296
+
14297
+ if (originalParam.type === 'TSParameterProperty' && thisContext) {
14298
+ const propertyName = getPatternName(originalParam.parameter);
14299
+ if (propertyName) {
14300
+ thisContext[propertyName] = env.get(propertyName);
14301
+ }
14302
+ }
14303
+
14304
+ if (param.type === 'RestElement') {
14305
+ break;
14306
+ }
14307
+ }
14308
+ }
14309
+
14310
+ bindFunctionParameter(param, arg, restArgs, env) {
14311
+ if (param.type === 'Identifier') {
14312
+ this.bindPattern(param, arg, env);
14313
+ return;
14314
+ }
14315
+
14316
+ if (param.type === 'AssignmentPattern') {
14317
+ const value = arg !== undefined ? arg : this.evaluate(param.right, env);
14318
+ this.bindPattern(param.left, value, env);
14319
+ return;
14320
+ }
14321
+
14322
+ if (param.type === 'RestElement') {
14323
+ const target = param.argument;
14324
+ if (target.type === 'Identifier') {
14325
+ env.define(target.name, restArgs);
14326
+ } else if (target.type === 'ArrayPattern') {
14327
+ this.bindArrayPattern(target, restArgs, env);
14328
+ } else if (target.type === 'ObjectPattern') {
14329
+ this.bindObjectPattern(target, restArgs, env);
14330
+ }
14331
+ return;
14332
+ }
14333
+
14334
+ if (param.type === 'ObjectPattern') {
14335
+ this.bindPattern(param, arg, env);
14336
+ return;
14337
+ }
14338
+
14339
+ if (param.type === 'ArrayPattern') {
14340
+ this.bindPattern(param, arg, env);
14341
+ return;
14342
+ }
14343
+
14344
+ env.define(param.name, arg);
14345
+ }
14346
+
14298
14347
  evaluateFunctionDeclaration(node, env) {
14299
14348
  const funcMetadata = {
14300
14349
  __isFunction: true,
@@ -14912,7 +14961,7 @@ class Interpreter {
14912
14961
  // Add methods to prototype
14913
14962
  for (const [name, method] of Object.entries(methods)) {
14914
14963
  classConstructor.prototype[name] = function(...args) {
14915
- const result = interpreter.callMethodFunction(method, this, args, env);
14964
+ const result = interpreter.callMethodFunction(method, this, args, env, superClass);
14916
14965
  // Unwrap explicit return marker
14917
14966
  if (result && result.__explicitReturn) {
14918
14967
  return result.value;
@@ -14985,6 +15034,9 @@ class Interpreter {
14985
15034
  for (const field of classConstructor.__instanceFields || []) {
14986
15035
  const fieldEnv = new Environment(env);
14987
15036
  fieldEnv.define('this', instance);
15037
+ if (classConstructor.__superClass) {
15038
+ fieldEnv.define('super', this.createSuperBinding(classConstructor.__superClass, instance, false));
15039
+ }
14988
15040
  const name = this.getClassFieldName(field, fieldEnv);
14989
15041
  instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
14990
15042
  }
@@ -15000,6 +15052,38 @@ class Interpreter {
15000
15052
  return field.key.value;
15001
15053
  }
15002
15054
 
15055
+ createSuperBinding(superClass, thisContext, allowConstructor = false, afterSuper = null) {
15056
+ const superConstructor = (...superArgs) => {
15057
+ if (!allowConstructor) {
15058
+ throw new ReferenceError("'super' keyword is unexpected here");
15059
+ }
15060
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15061
+ if (afterSuper) {
15062
+ afterSuper();
15063
+ }
15064
+ return result && result.__explicitReturn ? result.value : undefined;
15065
+ };
15066
+
15067
+ superConstructor.__isSuperConstructor = true;
15068
+ superConstructor.__superClass = superClass;
15069
+
15070
+ return new Proxy(superConstructor, {
15071
+ get(target, prop, receiver) {
15072
+ if (prop in target) {
15073
+ return Reflect.get(target, prop, receiver);
15074
+ }
15075
+
15076
+ const prototype = superClass?.prototype;
15077
+ if (!prototype) {
15078
+ return undefined;
15079
+ }
15080
+
15081
+ const value = Reflect.get(prototype, prop, thisContext);
15082
+ return typeof value === 'function' ? value.bind(thisContext) : value;
15083
+ }
15084
+ });
15085
+ }
15086
+
15003
15087
  createMethodFunction(funcNode, env, className) {
15004
15088
  const func = {
15005
15089
  __isFunction: true,
@@ -15019,57 +15103,11 @@ class Interpreter {
15019
15103
 
15020
15104
  // Bind 'super' if superClass exists
15021
15105
  if (superClass) {
15022
- // Create a super function that calls the parent constructor
15023
- const superFunc = (...superArgs) => {
15024
- const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15025
- if (afterSuper) {
15026
- afterSuper();
15027
- }
15028
- return result && result.__explicitReturn ? result.value : undefined;
15029
- };
15030
- // Store both the function and mark it as super
15031
- superFunc.__isSuperConstructor = true;
15032
- superFunc.__superClass = superClass;
15033
- funcEnv.define('super', superFunc);
15034
- }
15035
-
15036
- // Bind parameters
15037
- for (let i = 0; i < methodFunc.__params.length; i++) {
15038
- const originalParam = methodFunc.__params[i];
15039
- const param = originalParam.type === 'TSParameterProperty'
15040
- ? originalParam.parameter
15041
- : originalParam;
15042
-
15043
- if (param.type === 'Identifier') {
15044
- // Simple parameter: function(x)
15045
- funcEnv.define(param.name, args[i]);
15046
- } else if (param.type === 'AssignmentPattern') {
15047
- // Default parameter: function(x = defaultValue)
15048
- const value = args[i] !== undefined ? args[i] : this.evaluate(param.right, funcEnv);
15049
- funcEnv.define(param.left.name, value);
15050
- } else if (param.type === 'RestElement') {
15051
- // Rest parameter: function(...rest)
15052
- funcEnv.define(param.argument.name, args.slice(i));
15053
- break; // Rest element must be last
15054
- } else if (param.type === 'ObjectPattern') {
15055
- // Destructuring parameter: function({a, b})
15056
- this.bindObjectPattern(param, args[i], funcEnv);
15057
- } else if (param.type === 'ArrayPattern') {
15058
- // Array destructuring parameter: function([a, b])
15059
- this.bindArrayPattern(param, args[i], funcEnv);
15060
- } else {
15061
- // Fallback for simple parameter names
15062
- funcEnv.define(param.name, args[i]);
15063
- }
15064
-
15065
- if (originalParam.type === 'TSParameterProperty') {
15066
- const propertyName = getPatternName(originalParam.parameter);
15067
- if (propertyName) {
15068
- thisContext[propertyName] = funcEnv.get(propertyName);
15069
- }
15070
- }
15106
+ funcEnv.define('super', this.createSuperBinding(superClass, thisContext, true, afterSuper));
15071
15107
  }
15072
15108
 
15109
+ this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
15110
+
15073
15111
  const result = this.evaluate(methodFunc.__body, funcEnv);
15074
15112
 
15075
15113
  if (result instanceof ReturnValue) {
package/dist/index.js CHANGED
@@ -11514,6 +11514,9 @@ function getPatternName(pattern) {
11514
11514
  if (pattern.type === "TSParameterProperty") return getPatternName(pattern.parameter);
11515
11515
  return pattern.name;
11516
11516
  }
11517
+ function unwrapTSParameterProperty(param) {
11518
+ return (param == null ? void 0 : param.type) === "TSParameterProperty" ? param.parameter : param;
11519
+ }
11517
11520
  function collectRuntimeIdentifierReferences(node) {
11518
11521
  const references = /* @__PURE__ */ new Set();
11519
11522
  const skipKeys = /* @__PURE__ */ new Set([
@@ -12816,24 +12819,7 @@ var Interpreter = class _Interpreter {
12816
12819
  } else if (thisContext !== void 0) {
12817
12820
  funcEnv.define("this", thisContext);
12818
12821
  }
12819
- for (let i = 0; i < metadata.params.length; i++) {
12820
- const param = metadata.params[i].type === "TSParameterProperty" ? metadata.params[i].parameter : metadata.params[i];
12821
- if (param.type === "Identifier") {
12822
- funcEnv.define(param.name, args[i]);
12823
- } else if (param.type === "AssignmentPattern") {
12824
- const value = args[i] !== void 0 ? args[i] : this.evaluate(param.right, funcEnv);
12825
- funcEnv.define(param.left.name, value);
12826
- } else if (param.type === "RestElement") {
12827
- funcEnv.define(param.argument.name, args.slice(i));
12828
- break;
12829
- } else if (param.type === "ObjectPattern") {
12830
- this.bindObjectPattern(param, args[i], funcEnv);
12831
- } else if (param.type === "ArrayPattern") {
12832
- this.bindArrayPattern(param, args[i], funcEnv);
12833
- } else {
12834
- funcEnv.define(param.name, args[i]);
12835
- }
12836
- }
12822
+ this.bindFunctionParameters(metadata.params, args, funcEnv);
12837
12823
  if (metadata.async) {
12838
12824
  if (this.executionController) {
12839
12825
  this.executionController._pushCall(funcName);
@@ -13098,7 +13084,7 @@ var Interpreter = class _Interpreter {
13098
13084
  env.define(prop.value.name, propValue, isConst);
13099
13085
  } else if (prop.value.type === "AssignmentPattern") {
13100
13086
  const finalValue = propValue !== void 0 ? propValue : this.evaluate(prop.value.right, env);
13101
- env.define(prop.value.left.name, finalValue, isConst);
13087
+ this.bindPattern(prop.value.left, finalValue, env, isConst);
13102
13088
  } else if (prop.value.type === "ObjectPattern") {
13103
13089
  this.bindObjectPattern(prop.value, propValue, env, isConst);
13104
13090
  } else if (prop.value.type === "ArrayPattern") {
@@ -13122,7 +13108,7 @@ var Interpreter = class _Interpreter {
13122
13108
  env.define(element.name, value[i], isConst);
13123
13109
  } else if (element.type === "AssignmentPattern") {
13124
13110
  const finalValue = value[i] !== void 0 ? value[i] : this.evaluate(element.right, env);
13125
- env.define(element.left.name, finalValue, isConst);
13111
+ this.bindPattern(element.left, finalValue, env, isConst);
13126
13112
  } else if (element.type === "ObjectPattern") {
13127
13113
  this.bindObjectPattern(element, value[i], env, isConst);
13128
13114
  } else if (element.type === "ArrayPattern") {
@@ -13130,6 +13116,67 @@ var Interpreter = class _Interpreter {
13130
13116
  }
13131
13117
  }
13132
13118
  }
13119
+ bindPattern(pattern, value, env, isConst = false) {
13120
+ if (pattern.type === "Identifier") {
13121
+ env.define(pattern.name, value, isConst);
13122
+ } else if (pattern.type === "ObjectPattern") {
13123
+ this.bindObjectPattern(pattern, value, env, isConst);
13124
+ } else if (pattern.type === "ArrayPattern") {
13125
+ this.bindArrayPattern(pattern, value, env, isConst);
13126
+ } else if (pattern.type === "AssignmentPattern") {
13127
+ const finalValue = value !== void 0 ? value : this.evaluate(pattern.right, env);
13128
+ this.bindPattern(pattern.left, finalValue, env, isConst);
13129
+ } else if (pattern.type === "RestElement") {
13130
+ this.bindPattern(pattern.argument, value, env, isConst);
13131
+ }
13132
+ }
13133
+ bindFunctionParameters(params, args, env, thisContext = null) {
13134
+ for (let i = 0; i < params.length; i++) {
13135
+ const originalParam = params[i];
13136
+ const param = unwrapTSParameterProperty(originalParam);
13137
+ this.bindFunctionParameter(param, args[i], args.slice(i), env);
13138
+ if (originalParam.type === "TSParameterProperty" && thisContext) {
13139
+ const propertyName = getPatternName(originalParam.parameter);
13140
+ if (propertyName) {
13141
+ thisContext[propertyName] = env.get(propertyName);
13142
+ }
13143
+ }
13144
+ if (param.type === "RestElement") {
13145
+ break;
13146
+ }
13147
+ }
13148
+ }
13149
+ bindFunctionParameter(param, arg, restArgs, env) {
13150
+ if (param.type === "Identifier") {
13151
+ this.bindPattern(param, arg, env);
13152
+ return;
13153
+ }
13154
+ if (param.type === "AssignmentPattern") {
13155
+ const value = arg !== void 0 ? arg : this.evaluate(param.right, env);
13156
+ this.bindPattern(param.left, value, env);
13157
+ return;
13158
+ }
13159
+ if (param.type === "RestElement") {
13160
+ const target = param.argument;
13161
+ if (target.type === "Identifier") {
13162
+ env.define(target.name, restArgs);
13163
+ } else if (target.type === "ArrayPattern") {
13164
+ this.bindArrayPattern(target, restArgs, env);
13165
+ } else if (target.type === "ObjectPattern") {
13166
+ this.bindObjectPattern(target, restArgs, env);
13167
+ }
13168
+ return;
13169
+ }
13170
+ if (param.type === "ObjectPattern") {
13171
+ this.bindPattern(param, arg, env);
13172
+ return;
13173
+ }
13174
+ if (param.type === "ArrayPattern") {
13175
+ this.bindPattern(param, arg, env);
13176
+ return;
13177
+ }
13178
+ env.define(param.name, arg);
13179
+ }
13133
13180
  evaluateFunctionDeclaration(node, env) {
13134
13181
  const funcMetadata = {
13135
13182
  __isFunction: true,
@@ -13577,7 +13624,7 @@ var Interpreter = class _Interpreter {
13577
13624
  }
13578
13625
  for (const [name, method] of Object.entries(methods)) {
13579
13626
  classConstructor.prototype[name] = function(...args) {
13580
- const result = interpreter.callMethodFunction(method, this, args, env);
13627
+ const result = interpreter.callMethodFunction(method, this, args, env, superClass);
13581
13628
  if (result && result.__explicitReturn) {
13582
13629
  return result.value;
13583
13630
  }
@@ -13636,6 +13683,9 @@ var Interpreter = class _Interpreter {
13636
13683
  for (const field of classConstructor.__instanceFields || []) {
13637
13684
  const fieldEnv = new Environment(env);
13638
13685
  fieldEnv.define("this", instance);
13686
+ if (classConstructor.__superClass) {
13687
+ fieldEnv.define("super", this.createSuperBinding(classConstructor.__superClass, instance, false));
13688
+ }
13639
13689
  const name = this.getClassFieldName(field, fieldEnv);
13640
13690
  instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : void 0;
13641
13691
  }
@@ -13649,6 +13699,33 @@ var Interpreter = class _Interpreter {
13649
13699
  }
13650
13700
  return field.key.value;
13651
13701
  }
13702
+ createSuperBinding(superClass, thisContext, allowConstructor = false, afterSuper = null) {
13703
+ const superConstructor = (...superArgs) => {
13704
+ if (!allowConstructor) {
13705
+ throw new ReferenceError("'super' keyword is unexpected here");
13706
+ }
13707
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
13708
+ if (afterSuper) {
13709
+ afterSuper();
13710
+ }
13711
+ return result && result.__explicitReturn ? result.value : void 0;
13712
+ };
13713
+ superConstructor.__isSuperConstructor = true;
13714
+ superConstructor.__superClass = superClass;
13715
+ return new Proxy(superConstructor, {
13716
+ get(target, prop, receiver) {
13717
+ if (prop in target) {
13718
+ return Reflect.get(target, prop, receiver);
13719
+ }
13720
+ const prototype = superClass == null ? void 0 : superClass.prototype;
13721
+ if (!prototype) {
13722
+ return void 0;
13723
+ }
13724
+ const value = Reflect.get(prototype, prop, thisContext);
13725
+ return typeof value === "function" ? value.bind(thisContext) : value;
13726
+ }
13727
+ });
13728
+ }
13652
13729
  createMethodFunction(funcNode, env, className) {
13653
13730
  const func = {
13654
13731
  __isFunction: true,
@@ -13663,42 +13740,9 @@ var Interpreter = class _Interpreter {
13663
13740
  const funcEnv = new Environment(methodFunc.__env || env);
13664
13741
  funcEnv.define("this", thisContext);
13665
13742
  if (superClass) {
13666
- const superFunc = (...superArgs) => {
13667
- const result2 = this.initializeSuperClass(superClass, thisContext, superArgs);
13668
- if (afterSuper) {
13669
- afterSuper();
13670
- }
13671
- return result2 && result2.__explicitReturn ? result2.value : void 0;
13672
- };
13673
- superFunc.__isSuperConstructor = true;
13674
- superFunc.__superClass = superClass;
13675
- funcEnv.define("super", superFunc);
13676
- }
13677
- for (let i = 0; i < methodFunc.__params.length; i++) {
13678
- const originalParam = methodFunc.__params[i];
13679
- const param = originalParam.type === "TSParameterProperty" ? originalParam.parameter : originalParam;
13680
- if (param.type === "Identifier") {
13681
- funcEnv.define(param.name, args[i]);
13682
- } else if (param.type === "AssignmentPattern") {
13683
- const value = args[i] !== void 0 ? args[i] : this.evaluate(param.right, funcEnv);
13684
- funcEnv.define(param.left.name, value);
13685
- } else if (param.type === "RestElement") {
13686
- funcEnv.define(param.argument.name, args.slice(i));
13687
- break;
13688
- } else if (param.type === "ObjectPattern") {
13689
- this.bindObjectPattern(param, args[i], funcEnv);
13690
- } else if (param.type === "ArrayPattern") {
13691
- this.bindArrayPattern(param, args[i], funcEnv);
13692
- } else {
13693
- funcEnv.define(param.name, args[i]);
13694
- }
13695
- if (originalParam.type === "TSParameterProperty") {
13696
- const propertyName = getPatternName(originalParam.parameter);
13697
- if (propertyName) {
13698
- thisContext[propertyName] = funcEnv.get(propertyName);
13699
- }
13700
- }
13743
+ funcEnv.define("super", this.createSuperBinding(superClass, thisContext, true, afterSuper));
13701
13744
  }
13745
+ this.bindFunctionParameters(methodFunc.__params, args, funcEnv, thisContext);
13702
13746
  const result = this.evaluate(methodFunc.__body, funcEnv);
13703
13747
  if (result instanceof ReturnValue) {
13704
13748
  return { __explicitReturn: true, value: result.value };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jslike",
3
- "version": "1.8.3",
3
+ "version": "1.8.5",
4
4
  "description": "Production-ready JavaScript interpreter with full ES6+ support using Acorn parser",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",