porffor 0.56.8 → 0.57.1

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.
@@ -1322,7 +1322,7 @@ const asmFuncToAsm = (scope, func, extra) => func(scope, {
1322
1322
  allocPage: (scope, name) => allocPage({ scope, pages }, name)
1323
1323
  }, extra);
1324
1324
 
1325
- const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [], globals: globalTypes = [], globalInits = [], returns = [], returnType, localNames = [], globalNames = [], table = false, constr = false, hasRestArgument = false, usesTag = false, usesImports = false, usedTypes = [] } = {}) => {
1325
+ const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [], globals: globalTypes = [], globalInits = [], returns = [], returnType, localNames = [], globalNames = [], table = false, constr = false, hasRestArgument = false, usesTag = false, usesImports = false, returnTypes } = {}) => {
1326
1326
  if (wasm == null) { // called with no built-in
1327
1327
  log.warning('codegen', `${name} has no built-in!`);
1328
1328
  wasm = [];
@@ -1379,7 +1379,12 @@ const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTy
1379
1379
 
1380
1380
  if (table) funcs.table = true;
1381
1381
  if (usesTag) ensureTag();
1382
- for (const x of usedTypes) typeUsed(func, x);
1382
+
1383
+ if (returnTypes) {
1384
+ for (const x of returnTypes) typeUsed(func, x);
1385
+ } else if (returnType != null) {
1386
+ typeUsed(func, returnType);
1387
+ }
1383
1388
 
1384
1389
  func.wasm = wasm;
1385
1390
  return func;
@@ -1752,7 +1757,7 @@ const getNodeType = (scope, node) => {
1752
1757
  const out = typeof ret === 'number' ? [ number(ret, Valtype.i32) ] : ret;
1753
1758
  if (guess != null) out.guess = typeof guess === 'number' ? [ number(guess, Valtype.i32) ] : guess;
1754
1759
 
1755
- typeUsed(scope, knownType(scope, out));
1760
+ if (!node._doNotMarkTypeUsed) typeUsed(scope, knownType(scope, out));
1756
1761
  return out;
1757
1762
  };
1758
1763
 
@@ -2654,7 +2659,8 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2654
2659
  args = args.slice(0, paramCount - 1);
2655
2660
  args.push({
2656
2661
  type: 'ArrayExpression',
2657
- elements: restArgs
2662
+ elements: restArgs,
2663
+ _doNotMarkTypeUsed: true
2658
2664
  });
2659
2665
  }
2660
2666
  }
@@ -3015,10 +3021,14 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
3015
3021
  };
3016
3022
 
3017
3023
  if (globalThis.precompile) {
3018
- // just magic precompile things™
3019
- out.push([ null, 'typeswitch case start', types ]);
3020
- add();
3021
- out.push([ null, 'typeswitch case end' ]);
3024
+ if (scope.usedTypes && types.some(x => scope.usedTypes.has(x))) {
3025
+ add();
3026
+ } else {
3027
+ // just magic precompile things™
3028
+ out.push([ null, 'typeswitch case start', types ]);
3029
+ add();
3030
+ out.push([ null, 'typeswitch case end' ]);
3031
+ }
3022
3032
  } else {
3023
3033
  if (types.some(x => usedTypes.has(x))) {
3024
3034
  // type already used, just add it now
@@ -3135,7 +3145,7 @@ const extractTypeAnnotation = decl => {
3135
3145
  let a = decl;
3136
3146
  while (a.typeAnnotation) a = a.typeAnnotation;
3137
3147
 
3138
- let type = null, elementType = null;
3148
+ let types = null, type = null, elementType = null;
3139
3149
  if (a.typeName) {
3140
3150
  type = a.typeName.name;
3141
3151
  } else if (a.type.endsWith('Keyword')) {
@@ -3144,12 +3154,16 @@ const extractTypeAnnotation = decl => {
3144
3154
  } else if (a.type === 'TSArrayType') {
3145
3155
  type = 'array';
3146
3156
  elementType = extractTypeAnnotation(a.elementType).type;
3157
+ } else if (a.type === 'TSUnionType') {
3158
+ types = a.types.map(x => extractTypeAnnotation(x).type);
3147
3159
  }
3148
3160
 
3149
3161
  const typeName = type;
3150
3162
  type = typeAnnoToPorfType(type);
3151
3163
 
3152
- return { type, typeName, elementType };
3164
+ if (!types && type != null) types = [ type ];
3165
+
3166
+ return { type, types, typeName, elementType };
3153
3167
  };
3154
3168
 
3155
3169
  const setLocalWithType = (scope, name, isGlobal, decl, tee = false, overrideType = undefined) => {
@@ -5099,6 +5113,10 @@ const generateSwitch = (scope, decl) => {
5099
5113
  if (canTypeCheck) {
5100
5114
  depth.push('switch_typeswitch');
5101
5115
 
5116
+ // temporarily stub scope used types to have none always included for these cases
5117
+ const usedTypes = scope.usedTypes;
5118
+ scope.usedTypes = { add: () => {}, has: () => false };
5119
+
5102
5120
  const out = typeSwitch(scope, getNodeType(scope, decl.discriminant.arguments[0]), () => {
5103
5121
  const bc = [];
5104
5122
  let types = [];
@@ -5114,6 +5132,8 @@ const generateSwitch = (scope, decl) => {
5114
5132
  return bc;
5115
5133
  }, Blocktype.void, true);
5116
5134
 
5135
+ scope.usedTypes = usedTypes;
5136
+
5117
5137
  depth.pop();
5118
5138
  out.push(number(UNDEFINED));
5119
5139
  return out;
@@ -6602,6 +6622,8 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6602
6622
  const typeAnno = extractTypeAnnotation(type);
6603
6623
  addVarMetadata(func, name, false, typeAnno);
6604
6624
 
6625
+ if (typeAnno.types) for (const x of typeAnno.types) typeUsed(func, x);
6626
+
6605
6627
  // automatically add throws if unexpected this type to builtins
6606
6628
  if (globalThis.precompile && i === 0 && func.name.includes('_prototype_') && !func.name.startsWith('__Porffor_')) {
6607
6629
  if (typeAnno.type === TYPES.array) {
@@ -6707,6 +6729,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6707
6729
  // make out generator local
6708
6730
  allocVar(func, '#generator_out', false, false);
6709
6731
  typeUsed(func, func.async ? TYPES.__porffor_asyncgenerator : TYPES.__porffor_generator);
6732
+ if (func.async) typeUsed(func, TYPES.promise);
6710
6733
  }
6711
6734
 
6712
6735
  if (func.async && !func.generator) {
@@ -6788,11 +6811,15 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6788
6811
  funcs.push(func);
6789
6812
 
6790
6813
  if (typedInput && decl.returnType) {
6791
- const { type } = extractTypeAnnotation(decl.returnType);
6814
+ const { type, types } = extractTypeAnnotation(decl.returnType);
6815
+
6792
6816
  if (type != null) {
6793
6817
  typeUsed(func, type);
6794
6818
  func.returnType = type;
6795
6819
  func.returns = func.returnType === TYPES.undefined && !func.async && !func.generator ? [] : [ valtypeBinary ];
6820
+ } else if (types != null) {
6821
+ func.returnTypes = types;
6822
+ for (const x of types) typeUsed(func, x);
6796
6823
  }
6797
6824
  }
6798
6825
 
@@ -6836,7 +6863,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6836
6863
  break;
6837
6864
  }
6838
6865
 
6839
- args.push({ name, def, destr, type: typedInput && params[i].typeAnnotation });
6866
+ args.push({ name, def, destr, type: typedInput && x.typeAnnotation });
6840
6867
  }
6841
6868
 
6842
6869
  func.params = new Array((params.length + (func.constr ? 2 : (func.method ? 1 : 0))) * 2).fill(0).map((_, i) => i % 2 ? Valtype.i32 : valtypeBinary);
@@ -260,13 +260,11 @@ ${funcs.map(x => {
260
260
  // todo: check for other identifier unsafe characters
261
261
  const name = x.name.includes('#') ? `['${x.name}']` : `.${x.name}`;
262
262
 
263
- const usedTypes = [...(x.usedTypes ?? [])].filter(x => ![ TYPES.empty, TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ].includes(x));
264
-
263
+ const returnTypes = [...(x.returnTypes ?? [])].filter(x => ![ TYPES.empty, TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ].includes(x));
265
264
  return `this${name} = {
266
265
  wasm:${rewriteWasm(x.wasm)},
267
- params:${JSON.stringify(x.params)},typedParams:1,returns:${JSON.stringify(x.returns)},${x.returnType != null ? `returnType:${JSON.stringify(x.returnType)},` : ''}
266
+ params:${JSON.stringify(x.params)},typedParams:1,returns:${JSON.stringify(x.returns)},${x.returnType != null ? `returnType:${JSON.stringify(x.returnType)},` : ''}${returnTypes.length > 0 ? `returnTypes:${JSON.stringify(returnTypes)},` : ''}
268
267
  locals:${JSON.stringify(locals.slice(x.params.length).map(x => x[1].type))},localNames:${JSON.stringify(locals.map(x => x[0]))},
269
- ${usedTypes.length > 0 ? `usedTypes:${JSON.stringify(usedTypes)},` : ''}
270
268
  ${x.globalInits ? `globalInits:{${Object.keys(x.globalInits).map(y => `${y}:${rewriteWasm(x.globalInits[y])}`).join(',')}},` : ''}${x.data && Object.keys(x.data).length > 0 ? `data:${JSON.stringify(x.data)},` : ''}
271
269
  ${x.table ? `table:1,` : ''}${x.constr ? `constr:1,` : ''}${x.hasRestArgument ? `hasRestArgument:1,` : ''}${x.usesTag ? `usesTag:1,` : ''}${x.usesImports ? `usesImports:1,` : ''}
272
270
  }`.replaceAll('\n\n', '\n').replaceAll('\n\n', '\n').replaceAll('\n\n', '\n');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.56.8",
4
+ "version": "0.57.1",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.56.8';
3
+ globalThis.version = '0.57.1';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
@@ -46,9 +46,11 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
46
46
  // flags
47
47
  console.log(`\n\x1B[1m\x1B[4mFlags\x1B[0m`);
48
48
  for (let [ flag, desc ] of Object.entries({
49
+ 'On': 'Optimization level, use -O(0|\x1B[1m1\x1B[0m|2|3)',
50
+ t: 'Force parsing input as TypeScript',
51
+ d: 'Debug mode (include names in Wasm and debug logs)',
49
52
  module: 'Parse input as a module',
50
- t: 'Force TypeScript input',
51
- d: 'Debug mode (include names in Wasm and debug logs)'
53
+ secure: 'Secure mode (error on unsafe Porffor features eg FFI)'
52
54
  })) {
53
55
  flag = '-' + flag;
54
56
  if (flag.length > 3) flag = '-' + flag;
@@ -57,10 +59,10 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
57
59
  }
58
60
 
59
61
  // niche flags
60
- if (process.argv.includes('--flags')) {
62
+ if (process.argv.includes('all')) {
61
63
  for (let [ flag, desc ] of Object.entries({
62
64
  f: 'Print disassembled Wasm generated from user functions',
63
- pgo: 'Enable PGO (profile-guided optimization)',
65
+ pgo: 'Enable profile-guided optimization',
64
66
  valtype: 'Valtype to use, not well supported (i32|i64|\x1B[1mf64\x1B[0m)',
65
67
  'no-coctc': 'Disable COCTC (cross-object compile-time cache)',
66
68
  cyclone: 'Enable experimental Cyclone optimizer',
@@ -77,7 +79,7 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
77
79
  console.log(` \x1B[1m${flag}\x1B[0m${' '.repeat(36 - flag.length)}${desc}`);
78
80
  }
79
81
  } else {
80
- console.log(` \x1B[2m(To view all flags also use --flags)\x1B[0m`);
82
+ console.log(` \x1B[90m(To view all flags use --help all)\x1B[0m`);
81
83
  }
82
84
 
83
85
  console.log();
@@ -1,335 +0,0 @@
1
- // Optional Chaining Tests
2
- // This file tests all major features of the optional chaining operator (?.)
3
-
4
- // Test utility function
5
- function assert(condition, message) {
6
- if (!condition) {
7
- throw new Error('Assertion failed: ' + message);
8
- }
9
- return true;
10
- }
11
-
12
- // BASIC OBJECT PROPERTY ACCESS TESTS
13
- console.log('\n=== Basic Object Property Access ===');
14
-
15
- // Test 1: Basic property access with existing property
16
- (function() {
17
- const obj = { a: 1 };
18
- assert(obj?.a === 1, 'Basic property access failed');
19
- console.log('✓ Basic property access with existing property');
20
- })();
21
-
22
- // Test 2: Basic property access with undefined object
23
- (function() {
24
- const obj = undefined;
25
- assert(obj?.a === undefined, 'Optional chaining with undefined object failed');
26
- console.log('✓ Basic property access with undefined object');
27
- })();
28
-
29
- // Test 3: Basic property access with null object
30
- (function() {
31
- const obj = null;
32
- assert(obj?.a === undefined, 'Optional chaining with null object failed');
33
- console.log('✓ Basic property access with null object');
34
- })();
35
-
36
- // NESTED PROPERTY ACCESS TESTS
37
- console.log('\n=== Nested Property Access ===');
38
-
39
- // Test 4: Nested property access with all properties existing
40
- (function() {
41
- const obj = { a: { b: { c: 42 } } };
42
- assert(obj?.a?.b?.c === 42, 'Nested property access failed');
43
- console.log('✓ Nested property access with all properties existing');
44
- })();
45
-
46
- // Test 5: Nested property access with missing intermediate property
47
- (function() {
48
- const obj = { a: {} };
49
- assert(obj?.a?.b?.c === undefined, 'Nested property access with missing intermediate property failed');
50
- console.log('✓ Nested property access with missing intermediate property');
51
- })();
52
-
53
- // Test 6: Nested property access with null intermediate property
54
- (function() {
55
- const obj = { a: { b: null } };
56
- assert(obj?.a?.b?.c === undefined, 'Nested property access with null intermediate property failed');
57
- console.log('✓ Nested property access with null intermediate property');
58
- })();
59
-
60
- // METHOD CALL TESTS
61
- console.log('\n=== Method Call Tests ===');
62
-
63
- // Test 7: Method call on existing method
64
- (function() {
65
- const obj = {
66
- method: function() { return 'result'; }
67
- };
68
- assert(obj?.method?.() === 'result', 'Method call on existing method failed');
69
- console.log('✓ Method call on existing method');
70
- })();
71
-
72
- // Test 8: Method call on undefined object
73
- (function() {
74
- const obj = undefined;
75
- assert(obj?.method?.() === undefined, 'Method call on undefined object failed');
76
- console.log('✓ Method call on undefined object');
77
- })();
78
-
79
- // Test 9: Method call on null method
80
- (function() {
81
- const obj = { method: null };
82
- assert(obj?.method?.() === undefined, 'Method call on null method failed');
83
- console.log('✓ Method call on null method');
84
- })();
85
-
86
- // Test 10: Method call on undefined method
87
- (function() {
88
- const obj = {};
89
- assert(obj?.method?.() === undefined, 'Method call on undefined method failed');
90
- console.log('✓ Method call on undefined method');
91
- })();
92
-
93
- // ARRAY ELEMENT ACCESS TESTS
94
- console.log('\n=== Array Element Access ===');
95
-
96
- // Test 11: Array element access with valid index
97
- (function() {
98
- const arr = [1, 2, 3];
99
- assert(arr?.[1] === 2, 'Array element access with valid index failed');
100
- console.log('✓ Array element access with valid index');
101
- })();
102
-
103
- // Test 12: Array element access with undefined array
104
- (function() {
105
- const arr = undefined;
106
- assert(arr?.[1] === undefined, 'Array element access with undefined array failed');
107
- console.log('✓ Array element access with undefined array');
108
- })();
109
-
110
- // Test 13: Array element access with null array
111
- (function() {
112
- const arr = null;
113
- assert(arr?.[1] === undefined, 'Array element access with null array failed');
114
- console.log('✓ Array element access with null array');
115
- })();
116
-
117
- // Test 14: Access array method with optional chaining
118
- (function() {
119
- const arr = [1, 2, 3];
120
- assert(arr?.map(x => x * 2)?.[0] === 2, 'Access array method with optional chaining failed');
121
- console.log('✓ Access array method with optional chaining');
122
- })();
123
-
124
- // MIXED SYNTAX TESTS
125
- console.log('\n=== Mixed Syntax Tests ===');
126
-
127
- // Test 15: Mix of array and object property access
128
- (function() {
129
- const obj = { arr: [{ val: 42 }] };
130
- assert(obj?.arr?.[0]?.val === 42, 'Mix of array and object property access failed');
131
- console.log('✓ Mix of array and object property access');
132
- })();
133
-
134
- // Test 16: Method returning object with property
135
- (function() {
136
- const obj = {
137
- getObject: function() { return { prop: 'value' }; }
138
- };
139
- assert(obj?.getObject?.()?.prop === 'value', 'Method returning object with property failed');
140
- console.log('✓ Method returning object with property');
141
- })();
142
-
143
- // Test 17: Object with method returning array
144
- (function() {
145
- const obj = {
146
- getArray: function() { return [1, 2, 3]; }
147
- };
148
- assert(obj?.getArray?.()?.[1] === 2, 'Object with method returning array failed');
149
- console.log('✓ Object with method returning array');
150
- })();
151
-
152
- // COMPLEX EXPRESSIONS AND EDGE CASES
153
- console.log('\n=== Complex Expressions and Edge Cases ===');
154
-
155
- // Test 18: Optional chaining with function arguments
156
- (function() {
157
- const obj = {
158
- method: function(a, b) { return a + b; }
159
- };
160
- assert(obj?.method?.(1, 2) === 3, 'Optional chaining with function arguments failed');
161
- console.log('✓ Optional chaining with function arguments');
162
- })();
163
-
164
- // Test 19: Optional chaining in expressions
165
- (function() {
166
- const obj = { a: 5 };
167
- assert((obj?.a + 5) === 10, 'Optional chaining in expressions failed');
168
- console.log('✓ Optional chaining in expressions');
169
- })();
170
-
171
- // Test 20: Optional chaining with property names containing special characters
172
- (function() {
173
- const obj = { 'special-prop': 42 };
174
- assert(obj?.['special-prop'] === 42, 'Optional chaining with property names containing special characters failed');
175
- console.log('✓ Optional chaining with property names containing special characters');
176
- })();
177
-
178
- // Test 21: Optional chaining with computed property names
179
- (function() {
180
- const key = 'dynamicKey';
181
- const obj = { dynamicKey: 'dynamic value' };
182
- assert(obj?.[key] === 'dynamic value', 'Optional chaining with computed property names failed');
183
- console.log('✓ Optional chaining with computed property names');
184
- })();
185
-
186
- // Test 22: Optional chaining with Symbol properties
187
- (function() {
188
- const sym = Symbol('test');
189
- const obj = {};
190
- obj[sym] = 'symbol value';
191
- assert(obj?.[sym] === 'symbol value', 'Optional chaining with Symbol properties failed');
192
- console.log('✓ Optional chaining with Symbol properties');
193
- })();
194
-
195
- // Test 23: Optional chaining with object returned from function
196
- (function() {
197
- function getObject(returnValue) {
198
- return returnValue ? { prop: 'exists' } : null;
199
- }
200
- assert(getObject(true)?.prop === 'exists', 'Optional chaining with object returned from function (true case) failed');
201
- assert(getObject(false)?.prop === undefined, 'Optional chaining with object returned from function (false case) failed');
202
- console.log('✓ Optional chaining with object returned from function');
203
- })();
204
-
205
- // Test 24: Optional chaining with prototype chain
206
- (function() {
207
- const proto = { inheritedProp: 'inherited' };
208
- const obj = Object.create(proto);
209
- assert(obj?.inheritedProp === 'inherited', 'Optional chaining with prototype chain failed');
210
- console.log('✓ Optional chaining with prototype chain');
211
- })();
212
-
213
- // Test 25: Optional chaining with getters
214
- (function() {
215
- const obj = {
216
- get prop() { return 'getter value'; }
217
- };
218
- assert(obj?.prop === 'getter value', 'Optional chaining with getters failed');
219
- console.log('✓ Optional chaining with getters');
220
- })();
221
-
222
- // SHORT-CIRCUIT EVALUATION TESTS
223
- console.log('\n=== Short-circuit Evaluation Tests ===');
224
-
225
- // Test 26: Short-circuit evaluation - should not call function after undefined
226
- (function() {
227
- let functionCalled = false;
228
- const obj = undefined;
229
-
230
- function sideEffect() {
231
- functionCalled = true;
232
- return 'side effect';
233
- }
234
-
235
- obj?.prop?.[sideEffect()];
236
- assert(functionCalled === false, 'Short-circuit evaluation failed - function called when it should not have been');
237
- console.log('✓ Short-circuit evaluation - function not called after undefined');
238
- })();
239
-
240
- // Test 27: Non-short-circuit evaluation - should call function when property exists
241
- (function() {
242
- let functionCalled = false;
243
- const obj = { prop: {} };
244
-
245
- function sideEffect() {
246
- functionCalled = true;
247
- return 'key';
248
- }
249
-
250
- obj?.prop?.[sideEffect()];
251
- assert(functionCalled === true, 'Non-short-circuit evaluation failed - function not called when it should have been');
252
- console.log('✓ Non-short-circuit evaluation - function called when property exists');
253
- })();
254
-
255
- // ASSIGNMENT AND DESTRUCTURING TESTS
256
- console.log('\n=== Assignment and Destructuring Tests ===');
257
-
258
- // Test 28: Optional chaining in destructuring
259
- (function() {
260
- const obj = { nested: { value: 42 } };
261
- const { nested: { value } = {} } = obj ?? {};
262
- assert(value === 42, 'Optional chaining in destructuring failed');
263
- console.log('✓ Optional chaining in destructuring');
264
- })();
265
-
266
- // Test 29: Optional chaining with the nullish coalescing operator
267
- (function() {
268
- const obj = null;
269
- const value = obj?.prop ?? 'default';
270
- assert(value === 'default', 'Optional chaining with nullish coalescing operator failed');
271
- console.log('✓ Optional chaining with nullish coalescing operator');
272
- })();
273
-
274
- // Test 30: Optional chaining in logical expressions
275
- (function() {
276
- const obj = { prop: true };
277
- const nullObj = null;
278
-
279
- assert((obj?.prop && 'yes') === 'yes', 'Optional chaining in logical AND expression failed');
280
- assert((nullObj?.prop && 'yes') === undefined, 'Optional chaining in logical AND expression with null failed');
281
- assert((obj?.prop || 'fallback') === true, 'Optional chaining in logical OR expression failed');
282
- assert((nullObj?.prop || 'fallback') === 'fallback', 'Optional chaining in logical OR expression with null failed');
283
-
284
- console.log('✓ Optional chaining in logical expressions');
285
- })();
286
-
287
- // PERFORMANCE EDGE CASES
288
- console.log('\n=== Performance Edge Cases ===');
289
-
290
- // Test 31: Deep nesting - many levels
291
- (function() {
292
- const obj = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: 'deep' } } } } } } } } } };
293
- assert(obj?.a?.b?.c?.d?.e?.f?.g?.h?.i?.j === 'deep', 'Deep nesting optional chaining failed');
294
- console.log('✓ Deep nesting - many levels');
295
- })();
296
-
297
- // Test 32: Complex real-world scenario
298
- (function() {
299
- const data = {
300
- user: {
301
- profile: {
302
- name: 'John',
303
- address: {
304
- city: 'New York',
305
- zipcode: '10001'
306
- }
307
- },
308
- preferences: {
309
- theme: 'dark',
310
- notifications: {
311
- email: true,
312
- sms: false
313
- }
314
- },
315
- friends: [
316
- { id: 1, name: 'Alice' },
317
- { id: 2, name: 'Bob' }
318
- ]
319
- }
320
- };
321
-
322
- // Multiple complex optional chaining expressions
323
- assert(data?.user?.profile?.name === 'John', 'Complex scenario - user name test failed');
324
- assert(data?.user?.profile?.address?.city === 'New York', 'Complex scenario - address city test failed');
325
- assert(data?.user?.preferences?.notifications?.email === true, 'Complex scenario - notifications email test failed');
326
- assert(data?.user?.friends?.[1]?.name === 'Bob', 'Complex scenario - friends name test failed');
327
- assert(data?.user?.nonexistent?.something === undefined, 'Complex scenario - nonexistent property test failed');
328
-
329
- console.log('✓ Complex real-world scenario');
330
- })();
331
-
332
- // SUMMARY
333
- console.log('\n=== Test Summary ===');
334
- console.log('All tests completed successfully!');
335
- console.log('Total tests: 32');
package/r.cjs DELETED
@@ -1,71 +0,0 @@
1
-
2
- // class C {
3
- // // static #method = () => 1;
4
- // static #method() {
5
- // return 'Test262';
6
- // }
7
-
8
- // static getPrivateMethod() {
9
- // this.#method = () => 2;
10
- // return this.#method();
11
- // }
12
- // }
13
-
14
- // console.log(C.getPrivateMethod())
15
-
16
- // var __assert_throws = (expectedErrorConstructor, func) => {
17
- // if (typeof func !== 'function') {
18
- // throw new Test262Error('assert.throws invoked with a non-function value');
19
- // }
20
-
21
- // try {
22
- // func();
23
- // } catch {
24
- // return;
25
- // }
26
-
27
- // throw new Test262Error('assert.throws failed');
28
- // };
29
-
30
- // var __assert__isSameValue = (a, b) => {
31
- // if (a === b) {
32
- // // Handle +/-0 vs. -/+0
33
- // return a !== 0 || 1 / a === 1 / b;
34
- // }
35
-
36
- // // Handle NaN vs. NaN
37
- // return a !== a && b !== b;
38
- // };
39
-
40
- // var __assert_sameValue = (actual, expected) => {
41
- // if (__assert__isSameValue(actual, expected)) {
42
- // return;
43
- // }
44
-
45
- // throw new Test262Error('assert.sameValue failed');
46
- // };
47
-
48
- // (function() {
49
- // eval(
50
- // '__assert_throws(ReferenceError, function() {\
51
- // f;\
52
- // }, "An initialized binding is not created prior to evaluation");\
53
- // __assert_sameValue(\
54
- // typeof f,\
55
- // "undefined",\
56
- // "An uninitialized binding is not created prior to evaluation"\
57
- // );\
58
- // \
59
- // {\
60
- // let f = 123;if (false) ; else function f() { }}\
61
- // \
62
- // __assert_throws(ReferenceError, function() {\
63
- // f;\
64
- // }, "An initialized binding is not created following evaluation");\
65
- // __assert_sameValue(\
66
- // typeof f,\
67
- // "undefined",\
68
- // "An uninitialized binding is not created following evaluation"\
69
- // );'
70
- // );
71
- // }());