jslike 1.8.1 → 1.8.3

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.
@@ -54,22 +54,48 @@ function getAvailableMethods(obj) {
54
54
 
55
55
  const methods = new Set();
56
56
 
57
- // Get own properties
58
- Object.getOwnPropertyNames(obj).forEach(name => {
59
- if (typeof obj[name] === 'function') {
60
- methods.add(name);
57
+ const addSafeMethods = (target, includeConstructor = true) => {
58
+ let names;
59
+ try {
60
+ names = Object.getOwnPropertyNames(target);
61
+ } catch {
62
+ return;
61
63
  }
62
- });
63
64
 
64
- // Get prototype methods
65
- let proto = Object.getPrototypeOf(obj);
66
- while (proto && proto !== Object.prototype) {
67
- Object.getOwnPropertyNames(proto).forEach(name => {
68
- if (typeof proto[name] === 'function' && name !== 'constructor') {
65
+ names.forEach(name => {
66
+ if (!includeConstructor && name === 'constructor') return;
67
+
68
+ let descriptor;
69
+ try {
70
+ descriptor = Object.getOwnPropertyDescriptor(target, name);
71
+ } catch {
72
+ return;
73
+ }
74
+
75
+ if (descriptor && 'value' in descriptor && typeof descriptor.value === 'function') {
69
76
  methods.add(name);
70
77
  }
71
78
  });
72
- proto = Object.getPrototypeOf(proto);
79
+ };
80
+
81
+ // Get own properties
82
+ addSafeMethods(obj);
83
+
84
+ // Get prototype methods
85
+ let proto;
86
+ try {
87
+ proto = Object.getPrototypeOf(obj);
88
+ } catch {
89
+ proto = null;
90
+ }
91
+
92
+ while (proto && proto !== Object.prototype) {
93
+ addSafeMethods(proto, false);
94
+ try {
95
+ proto = Object.getPrototypeOf(proto);
96
+ } catch {
97
+ proto = null;
98
+ }
73
99
  }
74
100
 
75
101
  return Array.from(methods).sort();
@@ -2666,6 +2666,7 @@ export class Interpreter {
2666
2666
  let constructor = null;
2667
2667
  const methods = {};
2668
2668
  const staticMethods = {};
2669
+ const instanceFields = [];
2669
2670
 
2670
2671
  for (const member of node.body.body) {
2671
2672
  if (member.type === 'MethodDefinition') {
@@ -2679,6 +2680,8 @@ export class Interpreter {
2679
2680
  } else {
2680
2681
  methods[methodName] = methodFunc;
2681
2682
  }
2683
+ } else if (member.type === 'PropertyDefinition' && !member.static && !member.declare && !member.abstract) {
2684
+ instanceFields.push(member);
2682
2685
  }
2683
2686
  }
2684
2687
 
@@ -2686,18 +2689,11 @@ export class Interpreter {
2686
2689
  const classConstructor = function(...args) {
2687
2690
  // Create instance
2688
2691
  const instance = Object.create(classConstructor.prototype);
2692
+ const result = interpreter.constructClassInto(classConstructor, instance, args, env);
2689
2693
 
2690
- // Call constructor - super() must be called explicitly inside constructor
2691
- if (constructor) {
2692
- const result = interpreter.callMethodFunction(constructor, instance, args, env, superClass);
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);
2694
+ // Only use the returned object if it's an explicit return of an object (not the instance)
2695
+ if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
2696
+ return result.value;
2701
2697
  }
2702
2698
 
2703
2699
  return instance;
@@ -2708,6 +2704,12 @@ export class Interpreter {
2708
2704
  classConstructor.__constructor = constructor;
2709
2705
  }
2710
2706
 
2707
+ classConstructor.__instanceFields = instanceFields;
2708
+ classConstructor.__superClass = superClass;
2709
+ classConstructor.__constructInto = (instance, args) => {
2710
+ return interpreter.constructClassInto(classConstructor, instance, args, env);
2711
+ };
2712
+
2711
2713
  // Set up prototype chain
2712
2714
  if (superClass) {
2713
2715
  classConstructor.prototype = Object.create(superClass.prototype);
@@ -2742,6 +2744,69 @@ export class Interpreter {
2742
2744
  return classConstructor;
2743
2745
  }
2744
2746
 
2747
+ constructClassInto(classConstructor, instance, args, env) {
2748
+ const superClass = classConstructor.__superClass;
2749
+ const constructor = classConstructor.__constructor;
2750
+ let fieldsInitialized = false;
2751
+
2752
+ const initializeOwnFields = () => {
2753
+ if (!fieldsInitialized) {
2754
+ this.initializeClassFields(classConstructor, instance, env);
2755
+ fieldsInitialized = true;
2756
+ }
2757
+ };
2758
+
2759
+ if (!superClass) {
2760
+ initializeOwnFields();
2761
+ if (constructor) {
2762
+ return this.callMethodFunction(constructor, instance, args, env, null);
2763
+ }
2764
+ return undefined;
2765
+ }
2766
+
2767
+ if (constructor) {
2768
+ const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
2769
+ initializeOwnFields();
2770
+ return result;
2771
+ }
2772
+
2773
+ this.initializeSuperClass(superClass, instance, args);
2774
+ initializeOwnFields();
2775
+ return undefined;
2776
+ }
2777
+
2778
+ initializeSuperClass(superClass, instance, args) {
2779
+ if (superClass.__constructInto) {
2780
+ return superClass.__constructInto(instance, args);
2781
+ }
2782
+
2783
+ // For native constructors like Error, use Reflect.construct and copy instance properties.
2784
+ const tempInstance = Reflect.construct(superClass, args, instance.constructor);
2785
+ Object.getOwnPropertyNames(tempInstance).forEach(name => {
2786
+ instance[name] = tempInstance[name];
2787
+ });
2788
+ return undefined;
2789
+ }
2790
+
2791
+ initializeClassFields(classConstructor, instance, env) {
2792
+ for (const field of classConstructor.__instanceFields || []) {
2793
+ const fieldEnv = new Environment(env);
2794
+ fieldEnv.define('this', instance);
2795
+ const name = this.getClassFieldName(field, fieldEnv);
2796
+ instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
2797
+ }
2798
+ }
2799
+
2800
+ getClassFieldName(field, env) {
2801
+ if (field.computed) {
2802
+ return this.evaluate(field.key, env);
2803
+ }
2804
+ if (field.key.type === 'Identifier' || field.key.type === 'PrivateIdentifier') {
2805
+ return field.key.name;
2806
+ }
2807
+ return field.key.value;
2808
+ }
2809
+
2745
2810
  createMethodFunction(funcNode, env, className) {
2746
2811
  const func = {
2747
2812
  __isFunction: true,
@@ -2753,7 +2818,7 @@ export class Interpreter {
2753
2818
  return func;
2754
2819
  }
2755
2820
 
2756
- callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
2821
+ callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
2757
2822
  const funcEnv = new Environment(methodFunc.__env || env);
2758
2823
 
2759
2824
  // Bind 'this'
@@ -2763,21 +2828,11 @@ export class Interpreter {
2763
2828
  if (superClass) {
2764
2829
  // Create a super function that calls the parent constructor
2765
2830
  const superFunc = (...superArgs) => {
2766
- // Call the parent constructor method if it exists
2767
- if (superClass.__constructor) {
2768
- this.callMethodFunction(superClass.__constructor, thisContext, superArgs, env, null);
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
- });
2831
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
2832
+ if (afterSuper) {
2833
+ afterSuper();
2779
2834
  }
2780
- return undefined;
2835
+ return result && result.__explicitReturn ? result.value : undefined;
2781
2836
  };
2782
2837
  // Store both the function and mark it as super
2783
2838
  superFunc.__isSuperConstructor = true;
package/dist/index.cjs CHANGED
@@ -11425,19 +11425,40 @@ function findSimilar(target, candidates, maxDistance = 3) {
11425
11425
  function getAvailableMethods(obj) {
11426
11426
  if (obj === null || obj === void 0) return [];
11427
11427
  const methods = /* @__PURE__ */ new Set();
11428
- Object.getOwnPropertyNames(obj).forEach((name) => {
11429
- if (typeof obj[name] === "function") {
11430
- methods.add(name);
11428
+ const addSafeMethods = (target, includeConstructor = true) => {
11429
+ let names;
11430
+ try {
11431
+ names = Object.getOwnPropertyNames(target);
11432
+ } catch {
11433
+ return;
11431
11434
  }
11432
- });
11433
- let proto = Object.getPrototypeOf(obj);
11434
- while (proto && proto !== Object.prototype) {
11435
- Object.getOwnPropertyNames(proto).forEach((name) => {
11436
- if (typeof proto[name] === "function" && name !== "constructor") {
11435
+ names.forEach((name) => {
11436
+ if (!includeConstructor && name === "constructor") return;
11437
+ let descriptor;
11438
+ try {
11439
+ descriptor = Object.getOwnPropertyDescriptor(target, name);
11440
+ } catch {
11441
+ return;
11442
+ }
11443
+ if (descriptor && "value" in descriptor && typeof descriptor.value === "function") {
11437
11444
  methods.add(name);
11438
11445
  }
11439
11446
  });
11440
- proto = Object.getPrototypeOf(proto);
11447
+ };
11448
+ addSafeMethods(obj);
11449
+ let proto;
11450
+ try {
11451
+ proto = Object.getPrototypeOf(obj);
11452
+ } catch {
11453
+ proto = null;
11454
+ }
11455
+ while (proto && proto !== Object.prototype) {
11456
+ addSafeMethods(proto, false);
11457
+ try {
11458
+ proto = Object.getPrototypeOf(proto);
11459
+ } catch {
11460
+ proto = null;
11461
+ }
11441
11462
  }
11442
11463
  return Array.from(methods).sort();
11443
11464
  }
@@ -13552,6 +13573,7 @@ var Interpreter = class _Interpreter {
13552
13573
  let constructor = null;
13553
13574
  const methods = {};
13554
13575
  const staticMethods = {};
13576
+ const instanceFields = [];
13555
13577
  for (const member of node.body.body) {
13556
13578
  if (member.type === "MethodDefinition") {
13557
13579
  const methodName = member.key.name || member.key.value;
@@ -13563,23 +13585,26 @@ var Interpreter = class _Interpreter {
13563
13585
  } else {
13564
13586
  methods[methodName] = methodFunc;
13565
13587
  }
13588
+ } else if (member.type === "PropertyDefinition" && !member.static && !member.declare && !member.abstract) {
13589
+ instanceFields.push(member);
13566
13590
  }
13567
13591
  }
13568
13592
  const classConstructor = function(...args) {
13569
13593
  const instance = Object.create(classConstructor.prototype);
13570
- if (constructor) {
13571
- const result = interpreter.callMethodFunction(constructor, instance, args, env, superClass);
13572
- if (result && result.__explicitReturn && result.value && typeof result.value === "object" && result.value !== instance) {
13573
- return result.value;
13574
- }
13575
- } else if (superClass) {
13576
- superClass.call(instance, ...args);
13594
+ const result = interpreter.constructClassInto(classConstructor, instance, args, env);
13595
+ if (result && result.__explicitReturn && result.value && typeof result.value === "object" && result.value !== instance) {
13596
+ return result.value;
13577
13597
  }
13578
13598
  return instance;
13579
13599
  };
13580
13600
  if (constructor) {
13581
13601
  classConstructor.__constructor = constructor;
13582
13602
  }
13603
+ classConstructor.__instanceFields = instanceFields;
13604
+ classConstructor.__superClass = superClass;
13605
+ classConstructor.__constructInto = (instance, args) => {
13606
+ return interpreter.constructClassInto(classConstructor, instance, args, env);
13607
+ };
13583
13608
  if (superClass) {
13584
13609
  classConstructor.prototype = Object.create(superClass.prototype);
13585
13610
  classConstructor.prototype.constructor = classConstructor;
@@ -13605,6 +13630,59 @@ var Interpreter = class _Interpreter {
13605
13630
  classConstructor.__className = className;
13606
13631
  return classConstructor;
13607
13632
  }
13633
+ constructClassInto(classConstructor, instance, args, env) {
13634
+ const superClass = classConstructor.__superClass;
13635
+ const constructor = classConstructor.__constructor;
13636
+ let fieldsInitialized = false;
13637
+ const initializeOwnFields = () => {
13638
+ if (!fieldsInitialized) {
13639
+ this.initializeClassFields(classConstructor, instance, env);
13640
+ fieldsInitialized = true;
13641
+ }
13642
+ };
13643
+ if (!superClass) {
13644
+ initializeOwnFields();
13645
+ if (constructor) {
13646
+ return this.callMethodFunction(constructor, instance, args, env, null);
13647
+ }
13648
+ return void 0;
13649
+ }
13650
+ if (constructor) {
13651
+ const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
13652
+ initializeOwnFields();
13653
+ return result;
13654
+ }
13655
+ this.initializeSuperClass(superClass, instance, args);
13656
+ initializeOwnFields();
13657
+ return void 0;
13658
+ }
13659
+ initializeSuperClass(superClass, instance, args) {
13660
+ if (superClass.__constructInto) {
13661
+ return superClass.__constructInto(instance, args);
13662
+ }
13663
+ const tempInstance = Reflect.construct(superClass, args, instance.constructor);
13664
+ Object.getOwnPropertyNames(tempInstance).forEach((name) => {
13665
+ instance[name] = tempInstance[name];
13666
+ });
13667
+ return void 0;
13668
+ }
13669
+ initializeClassFields(classConstructor, instance, env) {
13670
+ for (const field of classConstructor.__instanceFields || []) {
13671
+ const fieldEnv = new Environment(env);
13672
+ fieldEnv.define("this", instance);
13673
+ const name = this.getClassFieldName(field, fieldEnv);
13674
+ instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : void 0;
13675
+ }
13676
+ }
13677
+ getClassFieldName(field, env) {
13678
+ if (field.computed) {
13679
+ return this.evaluate(field.key, env);
13680
+ }
13681
+ if (field.key.type === "Identifier" || field.key.type === "PrivateIdentifier") {
13682
+ return field.key.name;
13683
+ }
13684
+ return field.key.value;
13685
+ }
13608
13686
  createMethodFunction(funcNode, env, className) {
13609
13687
  const func = {
13610
13688
  __isFunction: true,
@@ -13615,20 +13693,16 @@ var Interpreter = class _Interpreter {
13615
13693
  };
13616
13694
  return func;
13617
13695
  }
13618
- callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
13696
+ callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
13619
13697
  const funcEnv = new Environment(methodFunc.__env || env);
13620
13698
  funcEnv.define("this", thisContext);
13621
13699
  if (superClass) {
13622
13700
  const superFunc = (...superArgs) => {
13623
- if (superClass.__constructor) {
13624
- this.callMethodFunction(superClass.__constructor, thisContext, superArgs, env, null);
13625
- } else {
13626
- const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
13627
- Object.getOwnPropertyNames(tempInstance).forEach((name) => {
13628
- thisContext[name] = tempInstance[name];
13629
- });
13701
+ const result2 = this.initializeSuperClass(superClass, thisContext, superArgs);
13702
+ if (afterSuper) {
13703
+ afterSuper();
13630
13704
  }
13631
- return void 0;
13705
+ return result2 && result2.__explicitReturn ? result2.value : void 0;
13632
13706
  };
13633
13707
  superFunc.__isSuperConstructor = true;
13634
13708
  superFunc.__superClass = superClass;
package/dist/index.d.cts CHANGED
@@ -12100,22 +12100,48 @@ function getAvailableMethods(obj) {
12100
12100
 
12101
12101
  const methods = new Set();
12102
12102
 
12103
- // Get own properties
12104
- Object.getOwnPropertyNames(obj).forEach(name => {
12105
- if (typeof obj[name] === 'function') {
12106
- methods.add(name);
12103
+ const addSafeMethods = (target, includeConstructor = true) => {
12104
+ let names;
12105
+ try {
12106
+ names = Object.getOwnPropertyNames(target);
12107
+ } catch {
12108
+ return;
12107
12109
  }
12108
- });
12109
12110
 
12110
- // Get prototype methods
12111
- let proto = Object.getPrototypeOf(obj);
12112
- while (proto && proto !== Object.prototype) {
12113
- Object.getOwnPropertyNames(proto).forEach(name => {
12114
- if (typeof proto[name] === 'function' && name !== 'constructor') {
12111
+ names.forEach(name => {
12112
+ if (!includeConstructor && name === 'constructor') return;
12113
+
12114
+ let descriptor;
12115
+ try {
12116
+ descriptor = Object.getOwnPropertyDescriptor(target, name);
12117
+ } catch {
12118
+ return;
12119
+ }
12120
+
12121
+ if (descriptor && 'value' in descriptor && typeof descriptor.value === 'function') {
12115
12122
  methods.add(name);
12116
12123
  }
12117
12124
  });
12118
- proto = Object.getPrototypeOf(proto);
12125
+ };
12126
+
12127
+ // Get own properties
12128
+ addSafeMethods(obj);
12129
+
12130
+ // Get prototype methods
12131
+ let proto;
12132
+ try {
12133
+ proto = Object.getPrototypeOf(obj);
12134
+ } catch {
12135
+ proto = null;
12136
+ }
12137
+
12138
+ while (proto && proto !== Object.prototype) {
12139
+ addSafeMethods(proto, false);
12140
+ try {
12141
+ proto = Object.getPrototypeOf(proto);
12142
+ } catch {
12143
+ proto = null;
12144
+ }
12119
12145
  }
12120
12146
 
12121
12147
  return Array.from(methods).sort();
@@ -14833,6 +14859,7 @@ class Interpreter {
14833
14859
  let constructor = null;
14834
14860
  const methods = {};
14835
14861
  const staticMethods = {};
14862
+ const instanceFields = [];
14836
14863
 
14837
14864
  for (const member of node.body.body) {
14838
14865
  if (member.type === 'MethodDefinition') {
@@ -14846,6 +14873,8 @@ class Interpreter {
14846
14873
  } else {
14847
14874
  methods[methodName] = methodFunc;
14848
14875
  }
14876
+ } else if (member.type === 'PropertyDefinition' && !member.static && !member.declare && !member.abstract) {
14877
+ instanceFields.push(member);
14849
14878
  }
14850
14879
  }
14851
14880
 
@@ -14853,18 +14882,11 @@ class Interpreter {
14853
14882
  const classConstructor = function(...args) {
14854
14883
  // Create instance
14855
14884
  const instance = Object.create(classConstructor.prototype);
14885
+ const result = interpreter.constructClassInto(classConstructor, instance, args, env);
14856
14886
 
14857
- // Call constructor - super() must be called explicitly inside constructor
14858
- if (constructor) {
14859
- const result = interpreter.callMethodFunction(constructor, instance, args, env, superClass);
14860
- // Only use the returned object if it's an explicit return of an object (not the instance)
14861
- if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
14862
- return result.value;
14863
- }
14864
- } else if (superClass) {
14865
- // If no constructor defined but has superClass, implicitly call super()
14866
- // Call the superClass constructor properly - it's a classConstructor function
14867
- superClass.call(instance, ...args);
14887
+ // Only use the returned object if it's an explicit return of an object (not the instance)
14888
+ if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
14889
+ return result.value;
14868
14890
  }
14869
14891
 
14870
14892
  return instance;
@@ -14875,6 +14897,12 @@ class Interpreter {
14875
14897
  classConstructor.__constructor = constructor;
14876
14898
  }
14877
14899
 
14900
+ classConstructor.__instanceFields = instanceFields;
14901
+ classConstructor.__superClass = superClass;
14902
+ classConstructor.__constructInto = (instance, args) => {
14903
+ return interpreter.constructClassInto(classConstructor, instance, args, env);
14904
+ };
14905
+
14878
14906
  // Set up prototype chain
14879
14907
  if (superClass) {
14880
14908
  classConstructor.prototype = Object.create(superClass.prototype);
@@ -14909,6 +14937,69 @@ class Interpreter {
14909
14937
  return classConstructor;
14910
14938
  }
14911
14939
 
14940
+ constructClassInto(classConstructor, instance, args, env) {
14941
+ const superClass = classConstructor.__superClass;
14942
+ const constructor = classConstructor.__constructor;
14943
+ let fieldsInitialized = false;
14944
+
14945
+ const initializeOwnFields = () => {
14946
+ if (!fieldsInitialized) {
14947
+ this.initializeClassFields(classConstructor, instance, env);
14948
+ fieldsInitialized = true;
14949
+ }
14950
+ };
14951
+
14952
+ if (!superClass) {
14953
+ initializeOwnFields();
14954
+ if (constructor) {
14955
+ return this.callMethodFunction(constructor, instance, args, env, null);
14956
+ }
14957
+ return undefined;
14958
+ }
14959
+
14960
+ if (constructor) {
14961
+ const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
14962
+ initializeOwnFields();
14963
+ return result;
14964
+ }
14965
+
14966
+ this.initializeSuperClass(superClass, instance, args);
14967
+ initializeOwnFields();
14968
+ return undefined;
14969
+ }
14970
+
14971
+ initializeSuperClass(superClass, instance, args) {
14972
+ if (superClass.__constructInto) {
14973
+ return superClass.__constructInto(instance, args);
14974
+ }
14975
+
14976
+ // For native constructors like Error, use Reflect.construct and copy instance properties.
14977
+ const tempInstance = Reflect.construct(superClass, args, instance.constructor);
14978
+ Object.getOwnPropertyNames(tempInstance).forEach(name => {
14979
+ instance[name] = tempInstance[name];
14980
+ });
14981
+ return undefined;
14982
+ }
14983
+
14984
+ initializeClassFields(classConstructor, instance, env) {
14985
+ for (const field of classConstructor.__instanceFields || []) {
14986
+ const fieldEnv = new Environment(env);
14987
+ fieldEnv.define('this', instance);
14988
+ const name = this.getClassFieldName(field, fieldEnv);
14989
+ instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
14990
+ }
14991
+ }
14992
+
14993
+ getClassFieldName(field, env) {
14994
+ if (field.computed) {
14995
+ return this.evaluate(field.key, env);
14996
+ }
14997
+ if (field.key.type === 'Identifier' || field.key.type === 'PrivateIdentifier') {
14998
+ return field.key.name;
14999
+ }
15000
+ return field.key.value;
15001
+ }
15002
+
14912
15003
  createMethodFunction(funcNode, env, className) {
14913
15004
  const func = {
14914
15005
  __isFunction: true,
@@ -14920,7 +15011,7 @@ class Interpreter {
14920
15011
  return func;
14921
15012
  }
14922
15013
 
14923
- callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
15014
+ callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
14924
15015
  const funcEnv = new Environment(methodFunc.__env || env);
14925
15016
 
14926
15017
  // Bind 'this'
@@ -14930,21 +15021,11 @@ class Interpreter {
14930
15021
  if (superClass) {
14931
15022
  // Create a super function that calls the parent constructor
14932
15023
  const superFunc = (...superArgs) => {
14933
- // Call the parent constructor method if it exists
14934
- if (superClass.__constructor) {
14935
- this.callMethodFunction(superClass.__constructor, thisContext, superArgs, env, null);
14936
- }
14937
- // Otherwise, call superClass as a regular constructor (for native/external classes)
14938
- else {
14939
- // For native constructors like Error, we need to use Reflect.construct
14940
- // to properly initialize the instance properties
14941
- const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
14942
- // Copy properties from the temp instance to our thisContext
14943
- Object.getOwnPropertyNames(tempInstance).forEach(name => {
14944
- thisContext[name] = tempInstance[name];
14945
- });
15024
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15025
+ if (afterSuper) {
15026
+ afterSuper();
14946
15027
  }
14947
- return undefined;
15028
+ return result && result.__explicitReturn ? result.value : undefined;
14948
15029
  };
14949
15030
  // Store both the function and mark it as super
14950
15031
  superFunc.__isSuperConstructor = true;
package/dist/index.d.ts CHANGED
@@ -12100,22 +12100,48 @@ function getAvailableMethods(obj) {
12100
12100
 
12101
12101
  const methods = new Set();
12102
12102
 
12103
- // Get own properties
12104
- Object.getOwnPropertyNames(obj).forEach(name => {
12105
- if (typeof obj[name] === 'function') {
12106
- methods.add(name);
12103
+ const addSafeMethods = (target, includeConstructor = true) => {
12104
+ let names;
12105
+ try {
12106
+ names = Object.getOwnPropertyNames(target);
12107
+ } catch {
12108
+ return;
12107
12109
  }
12108
- });
12109
12110
 
12110
- // Get prototype methods
12111
- let proto = Object.getPrototypeOf(obj);
12112
- while (proto && proto !== Object.prototype) {
12113
- Object.getOwnPropertyNames(proto).forEach(name => {
12114
- if (typeof proto[name] === 'function' && name !== 'constructor') {
12111
+ names.forEach(name => {
12112
+ if (!includeConstructor && name === 'constructor') return;
12113
+
12114
+ let descriptor;
12115
+ try {
12116
+ descriptor = Object.getOwnPropertyDescriptor(target, name);
12117
+ } catch {
12118
+ return;
12119
+ }
12120
+
12121
+ if (descriptor && 'value' in descriptor && typeof descriptor.value === 'function') {
12115
12122
  methods.add(name);
12116
12123
  }
12117
12124
  });
12118
- proto = Object.getPrototypeOf(proto);
12125
+ };
12126
+
12127
+ // Get own properties
12128
+ addSafeMethods(obj);
12129
+
12130
+ // Get prototype methods
12131
+ let proto;
12132
+ try {
12133
+ proto = Object.getPrototypeOf(obj);
12134
+ } catch {
12135
+ proto = null;
12136
+ }
12137
+
12138
+ while (proto && proto !== Object.prototype) {
12139
+ addSafeMethods(proto, false);
12140
+ try {
12141
+ proto = Object.getPrototypeOf(proto);
12142
+ } catch {
12143
+ proto = null;
12144
+ }
12119
12145
  }
12120
12146
 
12121
12147
  return Array.from(methods).sort();
@@ -14833,6 +14859,7 @@ class Interpreter {
14833
14859
  let constructor = null;
14834
14860
  const methods = {};
14835
14861
  const staticMethods = {};
14862
+ const instanceFields = [];
14836
14863
 
14837
14864
  for (const member of node.body.body) {
14838
14865
  if (member.type === 'MethodDefinition') {
@@ -14846,6 +14873,8 @@ class Interpreter {
14846
14873
  } else {
14847
14874
  methods[methodName] = methodFunc;
14848
14875
  }
14876
+ } else if (member.type === 'PropertyDefinition' && !member.static && !member.declare && !member.abstract) {
14877
+ instanceFields.push(member);
14849
14878
  }
14850
14879
  }
14851
14880
 
@@ -14853,18 +14882,11 @@ class Interpreter {
14853
14882
  const classConstructor = function(...args) {
14854
14883
  // Create instance
14855
14884
  const instance = Object.create(classConstructor.prototype);
14885
+ const result = interpreter.constructClassInto(classConstructor, instance, args, env);
14856
14886
 
14857
- // Call constructor - super() must be called explicitly inside constructor
14858
- if (constructor) {
14859
- const result = interpreter.callMethodFunction(constructor, instance, args, env, superClass);
14860
- // Only use the returned object if it's an explicit return of an object (not the instance)
14861
- if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
14862
- return result.value;
14863
- }
14864
- } else if (superClass) {
14865
- // If no constructor defined but has superClass, implicitly call super()
14866
- // Call the superClass constructor properly - it's a classConstructor function
14867
- superClass.call(instance, ...args);
14887
+ // Only use the returned object if it's an explicit return of an object (not the instance)
14888
+ if (result && result.__explicitReturn && result.value && typeof result.value === 'object' && result.value !== instance) {
14889
+ return result.value;
14868
14890
  }
14869
14891
 
14870
14892
  return instance;
@@ -14875,6 +14897,12 @@ class Interpreter {
14875
14897
  classConstructor.__constructor = constructor;
14876
14898
  }
14877
14899
 
14900
+ classConstructor.__instanceFields = instanceFields;
14901
+ classConstructor.__superClass = superClass;
14902
+ classConstructor.__constructInto = (instance, args) => {
14903
+ return interpreter.constructClassInto(classConstructor, instance, args, env);
14904
+ };
14905
+
14878
14906
  // Set up prototype chain
14879
14907
  if (superClass) {
14880
14908
  classConstructor.prototype = Object.create(superClass.prototype);
@@ -14909,6 +14937,69 @@ class Interpreter {
14909
14937
  return classConstructor;
14910
14938
  }
14911
14939
 
14940
+ constructClassInto(classConstructor, instance, args, env) {
14941
+ const superClass = classConstructor.__superClass;
14942
+ const constructor = classConstructor.__constructor;
14943
+ let fieldsInitialized = false;
14944
+
14945
+ const initializeOwnFields = () => {
14946
+ if (!fieldsInitialized) {
14947
+ this.initializeClassFields(classConstructor, instance, env);
14948
+ fieldsInitialized = true;
14949
+ }
14950
+ };
14951
+
14952
+ if (!superClass) {
14953
+ initializeOwnFields();
14954
+ if (constructor) {
14955
+ return this.callMethodFunction(constructor, instance, args, env, null);
14956
+ }
14957
+ return undefined;
14958
+ }
14959
+
14960
+ if (constructor) {
14961
+ const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
14962
+ initializeOwnFields();
14963
+ return result;
14964
+ }
14965
+
14966
+ this.initializeSuperClass(superClass, instance, args);
14967
+ initializeOwnFields();
14968
+ return undefined;
14969
+ }
14970
+
14971
+ initializeSuperClass(superClass, instance, args) {
14972
+ if (superClass.__constructInto) {
14973
+ return superClass.__constructInto(instance, args);
14974
+ }
14975
+
14976
+ // For native constructors like Error, use Reflect.construct and copy instance properties.
14977
+ const tempInstance = Reflect.construct(superClass, args, instance.constructor);
14978
+ Object.getOwnPropertyNames(tempInstance).forEach(name => {
14979
+ instance[name] = tempInstance[name];
14980
+ });
14981
+ return undefined;
14982
+ }
14983
+
14984
+ initializeClassFields(classConstructor, instance, env) {
14985
+ for (const field of classConstructor.__instanceFields || []) {
14986
+ const fieldEnv = new Environment(env);
14987
+ fieldEnv.define('this', instance);
14988
+ const name = this.getClassFieldName(field, fieldEnv);
14989
+ instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : undefined;
14990
+ }
14991
+ }
14992
+
14993
+ getClassFieldName(field, env) {
14994
+ if (field.computed) {
14995
+ return this.evaluate(field.key, env);
14996
+ }
14997
+ if (field.key.type === 'Identifier' || field.key.type === 'PrivateIdentifier') {
14998
+ return field.key.name;
14999
+ }
15000
+ return field.key.value;
15001
+ }
15002
+
14912
15003
  createMethodFunction(funcNode, env, className) {
14913
15004
  const func = {
14914
15005
  __isFunction: true,
@@ -14920,7 +15011,7 @@ class Interpreter {
14920
15011
  return func;
14921
15012
  }
14922
15013
 
14923
- callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
15014
+ callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
14924
15015
  const funcEnv = new Environment(methodFunc.__env || env);
14925
15016
 
14926
15017
  // Bind 'this'
@@ -14930,21 +15021,11 @@ class Interpreter {
14930
15021
  if (superClass) {
14931
15022
  // Create a super function that calls the parent constructor
14932
15023
  const superFunc = (...superArgs) => {
14933
- // Call the parent constructor method if it exists
14934
- if (superClass.__constructor) {
14935
- this.callMethodFunction(superClass.__constructor, thisContext, superArgs, env, null);
14936
- }
14937
- // Otherwise, call superClass as a regular constructor (for native/external classes)
14938
- else {
14939
- // For native constructors like Error, we need to use Reflect.construct
14940
- // to properly initialize the instance properties
14941
- const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
14942
- // Copy properties from the temp instance to our thisContext
14943
- Object.getOwnPropertyNames(tempInstance).forEach(name => {
14944
- thisContext[name] = tempInstance[name];
14945
- });
15024
+ const result = this.initializeSuperClass(superClass, thisContext, superArgs);
15025
+ if (afterSuper) {
15026
+ afterSuper();
14946
15027
  }
14947
- return undefined;
15028
+ return result && result.__explicitReturn ? result.value : undefined;
14948
15029
  };
14949
15030
  // Store both the function and mark it as super
14950
15031
  superFunc.__isSuperConstructor = true;
package/dist/index.js CHANGED
@@ -11391,19 +11391,40 @@ function findSimilar(target, candidates, maxDistance = 3) {
11391
11391
  function getAvailableMethods(obj) {
11392
11392
  if (obj === null || obj === void 0) return [];
11393
11393
  const methods = /* @__PURE__ */ new Set();
11394
- Object.getOwnPropertyNames(obj).forEach((name) => {
11395
- if (typeof obj[name] === "function") {
11396
- methods.add(name);
11394
+ const addSafeMethods = (target, includeConstructor = true) => {
11395
+ let names;
11396
+ try {
11397
+ names = Object.getOwnPropertyNames(target);
11398
+ } catch {
11399
+ return;
11397
11400
  }
11398
- });
11399
- let proto = Object.getPrototypeOf(obj);
11400
- while (proto && proto !== Object.prototype) {
11401
- Object.getOwnPropertyNames(proto).forEach((name) => {
11402
- if (typeof proto[name] === "function" && name !== "constructor") {
11401
+ names.forEach((name) => {
11402
+ if (!includeConstructor && name === "constructor") return;
11403
+ let descriptor;
11404
+ try {
11405
+ descriptor = Object.getOwnPropertyDescriptor(target, name);
11406
+ } catch {
11407
+ return;
11408
+ }
11409
+ if (descriptor && "value" in descriptor && typeof descriptor.value === "function") {
11403
11410
  methods.add(name);
11404
11411
  }
11405
11412
  });
11406
- proto = Object.getPrototypeOf(proto);
11413
+ };
11414
+ addSafeMethods(obj);
11415
+ let proto;
11416
+ try {
11417
+ proto = Object.getPrototypeOf(obj);
11418
+ } catch {
11419
+ proto = null;
11420
+ }
11421
+ while (proto && proto !== Object.prototype) {
11422
+ addSafeMethods(proto, false);
11423
+ try {
11424
+ proto = Object.getPrototypeOf(proto);
11425
+ } catch {
11426
+ proto = null;
11427
+ }
11407
11428
  }
11408
11429
  return Array.from(methods).sort();
11409
11430
  }
@@ -13518,6 +13539,7 @@ var Interpreter = class _Interpreter {
13518
13539
  let constructor = null;
13519
13540
  const methods = {};
13520
13541
  const staticMethods = {};
13542
+ const instanceFields = [];
13521
13543
  for (const member of node.body.body) {
13522
13544
  if (member.type === "MethodDefinition") {
13523
13545
  const methodName = member.key.name || member.key.value;
@@ -13529,23 +13551,26 @@ var Interpreter = class _Interpreter {
13529
13551
  } else {
13530
13552
  methods[methodName] = methodFunc;
13531
13553
  }
13554
+ } else if (member.type === "PropertyDefinition" && !member.static && !member.declare && !member.abstract) {
13555
+ instanceFields.push(member);
13532
13556
  }
13533
13557
  }
13534
13558
  const classConstructor = function(...args) {
13535
13559
  const instance = Object.create(classConstructor.prototype);
13536
- if (constructor) {
13537
- const result = interpreter.callMethodFunction(constructor, instance, args, env, superClass);
13538
- if (result && result.__explicitReturn && result.value && typeof result.value === "object" && result.value !== instance) {
13539
- return result.value;
13540
- }
13541
- } else if (superClass) {
13542
- superClass.call(instance, ...args);
13560
+ const result = interpreter.constructClassInto(classConstructor, instance, args, env);
13561
+ if (result && result.__explicitReturn && result.value && typeof result.value === "object" && result.value !== instance) {
13562
+ return result.value;
13543
13563
  }
13544
13564
  return instance;
13545
13565
  };
13546
13566
  if (constructor) {
13547
13567
  classConstructor.__constructor = constructor;
13548
13568
  }
13569
+ classConstructor.__instanceFields = instanceFields;
13570
+ classConstructor.__superClass = superClass;
13571
+ classConstructor.__constructInto = (instance, args) => {
13572
+ return interpreter.constructClassInto(classConstructor, instance, args, env);
13573
+ };
13549
13574
  if (superClass) {
13550
13575
  classConstructor.prototype = Object.create(superClass.prototype);
13551
13576
  classConstructor.prototype.constructor = classConstructor;
@@ -13571,6 +13596,59 @@ var Interpreter = class _Interpreter {
13571
13596
  classConstructor.__className = className;
13572
13597
  return classConstructor;
13573
13598
  }
13599
+ constructClassInto(classConstructor, instance, args, env) {
13600
+ const superClass = classConstructor.__superClass;
13601
+ const constructor = classConstructor.__constructor;
13602
+ let fieldsInitialized = false;
13603
+ const initializeOwnFields = () => {
13604
+ if (!fieldsInitialized) {
13605
+ this.initializeClassFields(classConstructor, instance, env);
13606
+ fieldsInitialized = true;
13607
+ }
13608
+ };
13609
+ if (!superClass) {
13610
+ initializeOwnFields();
13611
+ if (constructor) {
13612
+ return this.callMethodFunction(constructor, instance, args, env, null);
13613
+ }
13614
+ return void 0;
13615
+ }
13616
+ if (constructor) {
13617
+ const result = this.callMethodFunction(constructor, instance, args, env, superClass, initializeOwnFields);
13618
+ initializeOwnFields();
13619
+ return result;
13620
+ }
13621
+ this.initializeSuperClass(superClass, instance, args);
13622
+ initializeOwnFields();
13623
+ return void 0;
13624
+ }
13625
+ initializeSuperClass(superClass, instance, args) {
13626
+ if (superClass.__constructInto) {
13627
+ return superClass.__constructInto(instance, args);
13628
+ }
13629
+ const tempInstance = Reflect.construct(superClass, args, instance.constructor);
13630
+ Object.getOwnPropertyNames(tempInstance).forEach((name) => {
13631
+ instance[name] = tempInstance[name];
13632
+ });
13633
+ return void 0;
13634
+ }
13635
+ initializeClassFields(classConstructor, instance, env) {
13636
+ for (const field of classConstructor.__instanceFields || []) {
13637
+ const fieldEnv = new Environment(env);
13638
+ fieldEnv.define("this", instance);
13639
+ const name = this.getClassFieldName(field, fieldEnv);
13640
+ instance[name] = field.value ? this.evaluate(field.value, fieldEnv) : void 0;
13641
+ }
13642
+ }
13643
+ getClassFieldName(field, env) {
13644
+ if (field.computed) {
13645
+ return this.evaluate(field.key, env);
13646
+ }
13647
+ if (field.key.type === "Identifier" || field.key.type === "PrivateIdentifier") {
13648
+ return field.key.name;
13649
+ }
13650
+ return field.key.value;
13651
+ }
13574
13652
  createMethodFunction(funcNode, env, className) {
13575
13653
  const func = {
13576
13654
  __isFunction: true,
@@ -13581,20 +13659,16 @@ var Interpreter = class _Interpreter {
13581
13659
  };
13582
13660
  return func;
13583
13661
  }
13584
- callMethodFunction(methodFunc, thisContext, args, env, superClass = null) {
13662
+ callMethodFunction(methodFunc, thisContext, args, env, superClass = null, afterSuper = null) {
13585
13663
  const funcEnv = new Environment(methodFunc.__env || env);
13586
13664
  funcEnv.define("this", thisContext);
13587
13665
  if (superClass) {
13588
13666
  const superFunc = (...superArgs) => {
13589
- if (superClass.__constructor) {
13590
- this.callMethodFunction(superClass.__constructor, thisContext, superArgs, env, null);
13591
- } else {
13592
- const tempInstance = Reflect.construct(superClass, superArgs, thisContext.constructor);
13593
- Object.getOwnPropertyNames(tempInstance).forEach((name) => {
13594
- thisContext[name] = tempInstance[name];
13595
- });
13667
+ const result2 = this.initializeSuperClass(superClass, thisContext, superArgs);
13668
+ if (afterSuper) {
13669
+ afterSuper();
13596
13670
  }
13597
- return void 0;
13671
+ return result2 && result2.__explicitReturn ? result2.value : void 0;
13598
13672
  };
13599
13673
  superFunc.__isSuperConstructor = true;
13600
13674
  superFunc.__superClass = superClass;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jslike",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
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",