ether-code 0.6.6 → 0.6.8

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.
@@ -5,12 +5,18 @@ class JSGenerator {
5
5
  this.i18n = null
6
6
  this.indent = 0
7
7
  this.output = ''
8
+ this.context = []
9
+
8
10
  this.keywordMap = {}
11
+ this.contextualMap = {}
12
+ this.operatorMap = {}
9
13
  this.methodMap = {}
10
14
  this.builtinMap = {}
11
15
 
12
16
  if (i18nPath) {
13
17
  this.loadI18n(i18nPath)
18
+ } else {
19
+ this.buildDefaultMaps()
14
20
  }
15
21
  }
16
22
 
@@ -21,228 +27,818 @@ class JSGenerator {
21
27
  }
22
28
 
23
29
  buildMaps() {
24
- if (!this.i18n) return
30
+ if (!this.i18n) {
31
+ this.buildDefaultMaps()
32
+ return
33
+ }
25
34
 
26
- const addToMap = (map, section) => {
35
+ const addToMap = (map, section, prefix = '') => {
27
36
  if (!section) return
28
37
  for (const [key, translations] of Object.entries(section)) {
29
- if (translations && translations.fr && translations.js) {
30
- map[translations.fr.toLowerCase()] = translations.js
38
+ if (translations && translations.fr && translations.en) {
39
+ const frKey = translations.fr.toLowerCase()
40
+ const enValue = translations.en
41
+ if (prefix) {
42
+ if (!this.contextualMap[frKey]) {
43
+ this.contextualMap[frKey] = {}
44
+ }
45
+ this.contextualMap[frKey][prefix] = enValue
46
+ }
47
+ if (!map[frKey]) {
48
+ map[frKey] = enValue
49
+ }
31
50
  }
32
51
  }
33
52
  }
34
53
 
35
54
  addToMap(this.keywordMap, this.i18n.variables)
55
+ addToMap(this.keywordMap, this.i18n.portee)
36
56
  addToMap(this.keywordMap, this.i18n.typesPrimitifs)
37
57
  addToMap(this.keywordMap, this.i18n.typesComposites)
38
58
  addToMap(this.keywordMap, this.i18n.valeursSpeciales)
39
- addToMap(this.keywordMap, this.i18n.operateursArithmetiques)
40
- addToMap(this.keywordMap, this.i18n.operateursComparaison)
41
- addToMap(this.keywordMap, this.i18n.operateursLogiques)
42
59
  addToMap(this.keywordMap, this.i18n.structuresControle)
60
+ addToMap(this.keywordMap, this.i18n.boucles)
43
61
  addToMap(this.keywordMap, this.i18n.fonctions)
44
- addToMap(this.keywordMap, this.i18n.asynchrone)
45
62
  addToMap(this.keywordMap, this.i18n.classes)
46
63
  addToMap(this.keywordMap, this.i18n.modules)
47
64
  addToMap(this.keywordMap, this.i18n.erreurs)
65
+ addToMap(this.keywordMap, this.i18n.gestionErreurs)
66
+ addToMap(this.keywordMap, this.i18n.asynchrone)
67
+ addToMap(this.keywordMap, this.i18n.promesses)
48
68
  addToMap(this.keywordMap, this.i18n.generateurs)
49
-
50
- addToMap(this.methodMap, this.i18n.methodesTableau)
51
- addToMap(this.methodMap, this.i18n.methodesChaine)
52
- addToMap(this.methodMap, this.i18n.methodesObjet)
53
- addToMap(this.methodMap, this.i18n.methodesJSON)
54
- addToMap(this.methodMap, this.i18n.methodesMath)
55
- addToMap(this.methodMap, this.i18n.dom)
56
- addToMap(this.methodMap, this.i18n.evenements)
57
- addToMap(this.methodMap, this.i18n.fetch)
58
- addToMap(this.methodMap, this.i18n.console)
59
- addToMap(this.methodMap, this.i18n.stockage)
60
- addToMap(this.methodMap, this.i18n.timers)
69
+ addToMap(this.keywordMap, this.i18n.iterateurs)
70
+ addToMap(this.keywordMap, this.i18n.modeStrict)
71
+ addToMap(this.keywordMap, this.i18n.gabarits)
72
+ addToMap(this.keywordMap, this.i18n.synonymes)
73
+
74
+ addToMap(this.operatorMap, this.i18n.operateursArithmetiques)
75
+ addToMap(this.operatorMap, this.i18n.operateursComparaison)
76
+ addToMap(this.operatorMap, this.i18n.operateursLogiques)
77
+ addToMap(this.operatorMap, this.i18n.operateursBinaires)
78
+ addToMap(this.operatorMap, this.i18n.operateursUnaires)
79
+ addToMap(this.operatorMap, this.i18n.operateursAutres)
80
+
81
+ addToMap(this.methodMap, this.i18n.methodesTableau, 'array')
82
+ addToMap(this.methodMap, this.i18n.methodesChaine, 'string')
83
+ addToMap(this.methodMap, this.i18n.methodesObjet, 'object')
84
+ addToMap(this.methodMap, this.i18n.json, 'json')
85
+ addToMap(this.methodMap, this.i18n.math, 'math')
86
+ addToMap(this.methodMap, this.i18n.number, 'number')
87
+ addToMap(this.methodMap, this.i18n.bigint, 'bigint')
88
+ addToMap(this.methodMap, this.i18n.symbol, 'symbol')
89
+ addToMap(this.methodMap, this.i18n.console, 'console')
90
+ addToMap(this.methodMap, this.i18n.dom, 'dom')
91
+ addToMap(this.methodMap, this.i18n.evenements, 'event')
92
+ addToMap(this.methodMap, this.i18n.fetch, 'fetch')
93
+ addToMap(this.methodMap, this.i18n.stockage, 'storage')
94
+ addToMap(this.methodMap, this.i18n.minuteries, 'timer')
95
+ addToMap(this.methodMap, this.i18n.proxy, 'proxy')
96
+ addToMap(this.methodMap, this.i18n.reflect, 'reflect')
97
+ addToMap(this.methodMap, this.i18n.collections, 'collection')
98
+ addToMap(this.methodMap, this.i18n.date, 'date')
99
+ addToMap(this.methodMap, this.i18n.regexp, 'regexp')
100
+ addToMap(this.methodMap, this.i18n.typedArrays, 'typedarray')
101
+ addToMap(this.methodMap, this.i18n.gestionMemoire, 'memory')
102
+ addToMap(this.methodMap, this.i18n.intl, 'intl')
103
+ addToMap(this.methodMap, this.i18n.fonctionsGlobales, 'global')
104
+
105
+ this.buildConflictResolution()
61
106
  }
62
107
 
63
- translate(word) {
64
- const lower = word.toLowerCase()
65
- return this.keywordMap[lower] || this.methodMap[lower] || this.translateGeneric(word)
108
+ buildConflictResolution() {
109
+ this.conflicts = {
110
+ 'obtenir': {
111
+ 'class': 'get',
112
+ 'object': 'Object.get',
113
+ 'map': 'get',
114
+ 'storage': 'getItem',
115
+ 'default': 'get'
116
+ },
117
+ 'définir': {
118
+ 'class': 'set',
119
+ 'object': 'Object.set',
120
+ 'map': 'set',
121
+ 'storage': 'setItem',
122
+ 'default': 'set'
123
+ },
124
+ 'ajouter': {
125
+ 'array': 'push',
126
+ 'set': 'add',
127
+ 'dom': 'append',
128
+ 'class': 'classList.add',
129
+ 'default': 'push'
130
+ },
131
+ 'supprimer': {
132
+ 'array': 'pop',
133
+ 'object': 'delete',
134
+ 'dom': 'remove',
135
+ 'storage': 'removeItem',
136
+ 'set': 'delete',
137
+ 'map': 'delete',
138
+ 'default': 'delete'
139
+ },
140
+ 'retirer': {
141
+ 'array': 'pop',
142
+ 'stack': 'pop',
143
+ 'default': 'pop'
144
+ },
145
+ 'depuis': {
146
+ 'module': 'from',
147
+ 'array': 'Array.from',
148
+ 'default': 'from'
149
+ },
150
+ 'de': {
151
+ 'loop': 'of',
152
+ 'array': 'Array.of',
153
+ 'iterator': 'Iterator.from',
154
+ 'default': 'of'
155
+ },
156
+ 'valeurs': {
157
+ 'array': 'values',
158
+ 'object': 'Object.values',
159
+ 'map': 'values',
160
+ 'set': 'values',
161
+ 'default': 'values'
162
+ },
163
+ 'clés': {
164
+ 'array': 'keys',
165
+ 'object': 'Object.keys',
166
+ 'map': 'keys',
167
+ 'default': 'keys'
168
+ },
169
+ 'entrées': {
170
+ 'array': 'entries',
171
+ 'object': 'Object.entries',
172
+ 'map': 'entries',
173
+ 'set': 'entries',
174
+ 'default': 'entries'
175
+ },
176
+ 'taille': {
177
+ 'array': 'length',
178
+ 'string': 'length',
179
+ 'set': 'size',
180
+ 'map': 'size',
181
+ 'default': 'length'
182
+ },
183
+ 'longueur': {
184
+ 'array': 'length',
185
+ 'string': 'length',
186
+ 'buffer': 'byteLength',
187
+ 'default': 'length'
188
+ },
189
+ 'effacer': {
190
+ 'console': 'console.clear',
191
+ 'set': 'clear',
192
+ 'map': 'clear',
193
+ 'storage': 'clear',
194
+ 'default': 'clear'
195
+ },
196
+ 'créer': {
197
+ 'object': 'Object.create',
198
+ 'dom': 'createElement',
199
+ 'default': 'create'
200
+ },
201
+ 'a': {
202
+ 'array': 'at',
203
+ 'set': 'has',
204
+ 'map': 'has',
205
+ 'object': 'Object.hasOwn',
206
+ 'default': 'has'
207
+ },
208
+ 'suivant': {
209
+ 'iterator': 'next',
210
+ 'dom': 'nextSibling',
211
+ 'default': 'next'
212
+ },
213
+ 'formater': {
214
+ 'intl': 'format',
215
+ 'date': 'toLocaleString',
216
+ 'default': 'format'
217
+ },
218
+ 'analyser': {
219
+ 'json': 'JSON.parse',
220
+ 'number': 'parseFloat',
221
+ 'date': 'Date.parse',
222
+ 'default': 'JSON.parse'
223
+ },
224
+ 'convertir': {
225
+ 'json': 'JSON.stringify',
226
+ 'string': 'toString',
227
+ 'default': 'JSON.stringify'
228
+ },
229
+ 'inclut': {
230
+ 'array': 'includes',
231
+ 'string': 'includes',
232
+ 'default': 'includes'
233
+ },
234
+ 'trouver': {
235
+ 'array': 'find',
236
+ 'string': 'search',
237
+ 'default': 'find'
238
+ },
239
+ 'joindre': {
240
+ 'array': 'join',
241
+ 'string': 'concat',
242
+ 'default': 'join'
243
+ },
244
+ 'inverser': {
245
+ 'array': 'reverse',
246
+ 'string': 'split().reverse().join()',
247
+ 'default': 'reverse'
248
+ },
249
+ 'trier': {
250
+ 'array': 'sort',
251
+ 'default': 'sort'
252
+ },
253
+ 'filtrer': {
254
+ 'array': 'filter',
255
+ 'default': 'filter'
256
+ },
257
+ 'transformer': {
258
+ 'array': 'map',
259
+ 'default': 'map'
260
+ },
261
+ 'réduire': {
262
+ 'array': 'reduce',
263
+ 'default': 'reduce'
264
+ }
265
+ }
66
266
  }
67
267
 
68
- translateGeneric(word) {
69
- const translations = {
268
+ buildDefaultMaps() {
269
+ this.keywordMap = {
70
270
  'variable': 'let',
71
271
  'constante': 'const',
272
+ 'variable globale': 'var',
273
+ 'utilisant': 'using',
274
+ 'attendre utilisant': 'await using',
72
275
  'fonction': 'function',
276
+ 'fonction fléchée': '=>',
277
+ 'fonction asynchrone': 'async function',
278
+ 'fonction génératrice': 'function*',
73
279
  'retourner': 'return',
74
280
  'si': 'if',
75
281
  'sinon': 'else',
76
282
  'sinon si': 'else if',
77
283
  'pour': 'for',
284
+ 'pour de': 'for...of',
285
+ 'pour dans': 'for...in',
286
+ 'pour attendre de': 'for await...of',
78
287
  'tant que': 'while',
79
288
  'faire': 'do',
289
+ 'faire tant que': 'do...while',
80
290
  'selon': 'switch',
81
291
  'cas': 'case',
82
- 'defaut': 'default',
292
+ 'défaut': 'default',
83
293
  'sortir': 'break',
84
294
  'continuer': 'continue',
295
+ 'étiquette': 'label',
296
+ 'débogueur': 'debugger',
85
297
  'essayer': 'try',
86
298
  'attraper': 'catch',
87
299
  'finalement': 'finally',
88
300
  'lancer': 'throw',
89
301
  'nouveau': 'new',
90
302
  'supprimer': 'delete',
91
- 'typeof': 'typeof',
92
303
  'type de': 'typeof',
93
- 'instanceof': 'instanceof',
94
304
  'instance de': 'instanceof',
95
305
  'dans': 'in',
96
- 'de': 'of',
97
306
  'vrai': 'true',
98
307
  'faux': 'false',
99
308
  'nul': 'null',
100
- 'indefini': 'undefined',
309
+ 'indéfini': 'undefined',
310
+ 'infini': 'Infinity',
311
+ 'infini négatif': '-Infinity',
312
+ 'pas un nombre': 'NaN',
313
+ 'cet objet global': 'globalThis',
101
314
  'ceci': 'this',
102
315
  'classe': 'class',
103
- 'etend': 'extends',
316
+ 'étend': 'extends',
104
317
  'super': 'super',
105
318
  'constructeur': 'constructor',
106
319
  'statique': 'static',
320
+ 'privé': '#',
321
+ 'public': 'public',
322
+ 'protégé': 'protected',
107
323
  'obtenir': 'get',
108
- 'definir': 'set',
324
+ 'définir': 'set',
109
325
  'asynchrone': 'async',
110
326
  'attendre': 'await',
111
- 'produire': 'yield',
327
+ 'céder': 'yield',
328
+ 'céder tout': 'yield*',
329
+ 'générateur': 'generator',
330
+ 'itérateur': 'Iterator',
331
+ 'itérable': 'iterable',
112
332
  'importer': 'import',
113
333
  'exporter': 'export',
334
+ 'exporter par défaut': 'export default',
114
335
  'depuis': 'from',
115
336
  'comme': 'as',
116
- 'par defaut': 'default',
117
- 'et': '&&',
118
- 'ou': '||',
119
- 'non': '!',
120
- 'egal': '===',
121
- 'different': '!==',
122
- 'inferieur': '<',
123
- 'superieur': '>',
124
- 'inferieur ou egal': '<=',
125
- 'superieur ou egal': '>=',
337
+ 'avec': 'with',
338
+ 'promesse': 'Promise',
339
+ 'résoudre': 'resolve',
340
+ 'rejeter': 'reject',
341
+ 'alors': 'then',
342
+ 'tout': 'Promise.all',
343
+ 'tout réglé': 'Promise.allSettled',
344
+ "n'importe": 'Promise.any',
345
+ 'course': 'Promise.race',
346
+ 'avec résolveurs': 'Promise.withResolvers',
347
+ 'erreur': 'Error',
348
+ 'erreur type': 'TypeError',
349
+ 'erreur référence': 'ReferenceError',
350
+ 'erreur syntaxe': 'SyntaxError',
351
+ 'erreur plage': 'RangeError',
352
+ 'erreur URI': 'URIError',
353
+ 'erreur évaluation': 'EvalError',
354
+ 'erreur agrégée': 'AggregateError',
355
+ 'erreur supprimée': 'SuppressedError',
356
+ 'nombre': 'number',
357
+ 'chaîne': 'string',
358
+ 'booléen': 'boolean',
359
+ 'symbole': 'symbol',
360
+ 'grand entier': 'bigint',
361
+ 'objet': 'object',
362
+ 'tableau': 'Array',
363
+ 'date': 'Date',
364
+ 'expression régulière': 'RegExp',
365
+ 'regex': 'RegExp',
366
+ 'ensemble': 'Set',
367
+ 'carte': 'Map',
368
+ 'carte faible': 'WeakMap',
369
+ 'ensemble faible': 'WeakSet',
370
+ 'buffer tableau': 'ArrayBuffer',
371
+ 'vue données': 'DataView',
372
+ 'proxy': 'Proxy',
373
+ 'réfléchir': 'Reflect',
374
+ 'intl': 'Intl',
375
+ 'utiliser strict': 'use strict',
376
+ 'gabarit': 'template literal',
377
+ 'gabarit étiqueté': 'tagged template'
378
+ }
379
+
380
+ this.operatorMap = {
126
381
  'plus': '+',
127
382
  'moins': '-',
128
383
  'fois': '*',
129
- 'divise': '/',
384
+ 'divisé': '/',
130
385
  'modulo': '%',
386
+ 'reste': '%',
131
387
  'puissance': '**',
388
+ 'incrément': '++',
389
+ 'décrément': '--',
390
+ 'égal': '==',
391
+ 'différent': '!=',
392
+ 'strictement égal': '===',
393
+ 'strictement différent': '!==',
394
+ 'supérieur': '>',
395
+ 'inférieur': '<',
396
+ 'supérieur ou égal': '>=',
397
+ 'inférieur ou égal': '<=',
398
+ 'et': '&&',
399
+ 'ou': '||',
400
+ 'non': '!',
401
+ 'coalescence nulle': '??',
402
+ 'chaînage optionnel': '?.',
403
+ 'et binaire': '&',
404
+ 'ou binaire': '|',
405
+ 'ou exclusif': '^',
406
+ 'non binaire': '~',
407
+ 'décalage gauche': '<<',
408
+ 'décalage droite': '>>',
409
+ 'décalage droite non signé': '>>>',
410
+ 'plus unaire': '+',
411
+ 'moins unaire': '-',
412
+ 'vide': 'void',
413
+ 'virgule': ',',
414
+ 'décomposition': '...'
415
+ }
416
+
417
+ this.methodMap = {
418
+ 'afficher': 'console.log',
419
+ 'journal': 'console.log',
420
+ 'erreur': 'console.error',
421
+ 'avertir': 'console.warn',
422
+ 'info': 'console.info',
423
+ 'déboguer': 'console.debug',
424
+ 'table': 'console.table',
425
+ 'groupe': 'console.group',
426
+ 'fin groupe': 'console.groupEnd',
427
+ 'temps': 'console.time',
428
+ 'fin temps': 'console.timeEnd',
429
+ 'trace': 'console.trace',
132
430
  'longueur': 'length',
133
431
  'ajouter': 'push',
134
432
  'retirer': 'pop',
135
- 'decaler': 'shift',
136
- 'inserer debut': 'unshift',
137
- 'trancher': 'slice',
138
- 'epiisser': 'splice',
139
- 'concatener': 'concat',
140
- 'joindre': 'join',
433
+ 'décaler': 'shift',
434
+ 'insérer début': 'unshift',
435
+ 'épisser': 'splice',
436
+ 'remplir': 'fill',
437
+ 'copier dans': 'copyWithin',
141
438
  'inverser': 'reverse',
142
439
  'trier': 'sort',
440
+ 'trancher': 'slice',
441
+ 'concaténer': 'concat',
442
+ 'joindre': 'join',
443
+ 'à': 'at',
444
+ 'index de': 'indexOf',
445
+ 'dernier index de': 'lastIndexOf',
446
+ 'inclut': 'includes',
447
+ 'pour chaque': 'forEach',
448
+ 'transformer': 'map',
143
449
  'filtrer': 'filter',
144
- 'mapper': 'map',
145
- 'reduire': 'reduce',
450
+ 'réduire': 'reduce',
451
+ 'réduire droite': 'reduceRight',
146
452
  'trouver': 'find',
147
453
  'trouver index': 'findIndex',
148
- 'chaque': 'forEach',
149
- 'certains': 'some',
454
+ 'trouver dernier': 'findLast',
455
+ 'trouver dernier index': 'findLastIndex',
456
+ 'quelques': 'some',
150
457
  'tous': 'every',
151
- 'inclut': 'includes',
152
- 'index de': 'indexOf',
153
- 'majuscules': 'toUpperCase',
154
- 'minuscules': 'toLowerCase',
155
- 'diviser': 'split',
156
- 'remplacer': 'replace',
157
- 'supprimer espaces': 'trim',
458
+ 'aplatir': 'flat',
459
+ 'aplatir transformer': 'flatMap',
460
+ 'vers inversé': 'toReversed',
461
+ 'vers trié': 'toSorted',
462
+ 'vers épissé': 'toSpliced',
463
+ 'est tableau': 'Array.isArray',
464
+ 'clés': 'keys',
465
+ 'valeurs': 'values',
466
+ 'entrées': 'entries',
467
+ 'caractère à': 'charAt',
468
+ 'code caractère à': 'charCodeAt',
469
+ 'point de code à': 'codePointAt',
158
470
  'commence par': 'startsWith',
159
- 'finit par': 'endsWith',
160
- 'sous chaine': 'substring',
161
- 'afficher': 'console.log',
162
- 'alerte': 'alert',
163
- 'confirmer': 'confirm',
164
- 'demander': 'prompt',
471
+ 'termine par': 'endsWith',
472
+ 'rechercher': 'search',
473
+ 'correspondance': 'match',
474
+ 'toutes correspondances': 'matchAll',
475
+ 'en majuscules': 'toUpperCase',
476
+ 'en minuscules': 'toLowerCase',
477
+ 'supprimer espaces': 'trim',
478
+ 'supprimer début': 'trimStart',
479
+ 'supprimer fin': 'trimEnd',
480
+ 'compléter début': 'padStart',
481
+ 'compléter fin': 'padEnd',
482
+ 'répéter': 'repeat',
483
+ 'remplacer': 'replace',
484
+ 'remplacer tout': 'replaceAll',
485
+ 'normaliser': 'normalize',
486
+ 'diviser': 'split',
487
+ 'sous-chaîne': 'substring',
488
+ 'depuis code caractère': 'String.fromCharCode',
489
+ 'depuis point de code': 'String.fromCodePoint',
490
+ 'brut': 'String.raw',
491
+ 'clés obj': 'Object.keys',
492
+ 'valeurs obj': 'Object.values',
493
+ 'entrées obj': 'Object.entries',
494
+ 'depuis entrées': 'Object.fromEntries',
495
+ 'assigner': 'Object.assign',
496
+ 'geler': 'Object.freeze',
497
+ 'est gelé': 'Object.isFrozen',
498
+ 'sceller': 'Object.seal',
499
+ 'est scellé': 'Object.isSealed',
500
+ 'empêcher extensions': 'Object.preventExtensions',
501
+ 'est extensible': 'Object.isExtensible',
502
+ 'créer': 'Object.create',
503
+ 'définir propriété': 'Object.defineProperty',
504
+ 'définir propriétés': 'Object.defineProperties',
505
+ 'obtenir descripteur': 'Object.getOwnPropertyDescriptor',
506
+ 'obtenir descripteurs': 'Object.getOwnPropertyDescriptors',
507
+ 'obtenir noms propriétés': 'Object.getOwnPropertyNames',
508
+ 'obtenir symboles propriétés': 'Object.getOwnPropertySymbols',
509
+ 'a propriété': 'Object.hasOwn',
510
+ 'est': 'Object.is',
511
+ 'obtenir prototype de': 'Object.getPrototypeOf',
512
+ 'définir prototype de': 'Object.setPrototypeOf',
513
+ 'grouper par': 'Object.groupBy',
514
+ 'analyser': 'JSON.parse',
515
+ 'convertir': 'JSON.stringify',
516
+ 'sérialiser': 'JSON.stringify',
517
+ 'pi': 'Math.PI',
518
+ 'e': 'Math.E',
519
+ 'arrondi': 'Math.round',
520
+ 'plancher': 'Math.floor',
521
+ 'plafond': 'Math.ceil',
522
+ 'tronquer': 'Math.trunc',
523
+ 'absolu': 'Math.abs',
524
+ 'signe': 'Math.sign',
525
+ 'minimum': 'Math.min',
526
+ 'maximum': 'Math.max',
527
+ 'puissance math': 'Math.pow',
528
+ 'racine carrée': 'Math.sqrt',
529
+ 'racine cubique': 'Math.cbrt',
530
+ 'hypotènuse': 'Math.hypot',
531
+ 'sinus': 'Math.sin',
532
+ 'cosinus': 'Math.cos',
533
+ 'tangente': 'Math.tan',
534
+ 'arc sinus': 'Math.asin',
535
+ 'arc cosinus': 'Math.acos',
536
+ 'arc tangente': 'Math.atan',
537
+ 'arc tangente 2': 'Math.atan2',
538
+ 'sinus hyperbolique': 'Math.sinh',
539
+ 'cosinus hyperbolique': 'Math.cosh',
540
+ 'tangente hyperbolique': 'Math.tanh',
541
+ 'logarithme': 'Math.log',
542
+ 'logarithme 10': 'Math.log10',
543
+ 'logarithme 2': 'Math.log2',
544
+ 'exponentielle': 'Math.exp',
545
+ 'aléatoire': 'Math.random',
546
+ 'epsilon': 'Number.EPSILON',
547
+ 'entier max sûr': 'Number.MAX_SAFE_INTEGER',
548
+ 'entier min sûr': 'Number.MIN_SAFE_INTEGER',
549
+ 'valeur max': 'Number.MAX_VALUE',
550
+ 'valeur min': 'Number.MIN_VALUE',
551
+ 'est fini': 'Number.isFinite',
552
+ 'est entier': 'Number.isInteger',
553
+ 'est NaN': 'Number.isNaN',
554
+ 'est entier sûr': 'Number.isSafeInteger',
555
+ 'analyser flottant': 'Number.parseFloat',
556
+ 'analyser entier': 'Number.parseInt',
557
+ 'vers fixe': 'toFixed',
558
+ 'vers exponentiel': 'toExponential',
559
+ 'vers précision': 'toPrecision',
560
+ 'en tant que entier n': 'BigInt.asIntN',
561
+ 'en tant que non signé n': 'BigInt.asUintN',
562
+ 'symbole': 'Symbol',
563
+ 'symbole pour': 'Symbol.for',
564
+ 'clé pour': 'Symbol.keyFor',
565
+ 'symbole itérateur': 'Symbol.iterator',
566
+ 'symbole itérateur asynchrone': 'Symbol.asyncIterator',
567
+ 'symbole correspondance': 'Symbol.match',
568
+ 'symbole remplacer': 'Symbol.replace',
569
+ 'symbole recherche': 'Symbol.search',
570
+ 'symbole diviser': 'Symbol.split',
571
+ 'symbole a instance': 'Symbol.hasInstance',
572
+ 'symbole espèce': 'Symbol.species',
573
+ 'symbole vers primitif': 'Symbol.toPrimitive',
574
+ 'symbole vers tag chaîne': 'Symbol.toStringTag',
575
+ 'symbole disposer': 'Symbol.dispose',
576
+ 'symbole disposer asynchrone': 'Symbol.asyncDispose',
165
577
  'document': 'document',
166
- 'fenetre': 'window',
167
- 'element par id': 'getElementById',
168
- 'elements par classe': 'getElementsByClassName',
169
- 'elements par tag': 'getElementsByTagName',
170
- 'selecteur': 'querySelector',
171
- 'selecteurs': 'querySelectorAll',
172
- 'creer element': 'createElement',
578
+ 'fenêtre': 'window',
579
+ 'sélecteur': 'querySelector',
580
+ 'sélecteurs': 'querySelectorAll',
581
+ 'élément par id': 'getElementById',
582
+ 'éléments par classe': 'getElementsByClassName',
583
+ 'éléments par tag': 'getElementsByTagName',
584
+ 'créer élément': 'createElement',
585
+ 'créer fragment': 'createDocumentFragment',
586
+ 'créer noeud texte': 'createTextNode',
173
587
  'ajouter enfant': 'appendChild',
174
588
  'supprimer enfant': 'removeChild',
175
- 'attribut': 'getAttribute',
176
- 'definir attribut': 'setAttribute',
177
- 'ecouter': 'addEventListener',
178
- 'stopper ecoute': 'removeEventListener',
179
- 'empecher defaut': 'preventDefault',
589
+ 'remplacer enfant': 'replaceChild',
590
+ 'insérer avant': 'insertBefore',
591
+ 'cloner': 'cloneNode',
592
+ 'supprimer élément': 'remove',
593
+ 'ajouter dom': 'append',
594
+ 'préfixer': 'prepend',
595
+ 'après': 'after',
596
+ 'avant': 'before',
597
+ 'remplacer avec': 'replaceWith',
598
+ 'contenu HTML': 'innerHTML',
599
+ 'HTML externe': 'outerHTML',
600
+ 'contenu texte': 'textContent',
601
+ 'texte interne': 'innerText',
602
+ 'obtenir attribut': 'getAttribute',
603
+ 'définir attribut': 'setAttribute',
604
+ 'supprimer attribut': 'removeAttribute',
605
+ 'a attribut': 'hasAttribute',
606
+ 'basculer attribut': 'toggleAttribute',
607
+ 'liste classes': 'classList',
608
+ 'ajouter classe': 'classList.add',
609
+ 'supprimer classe': 'classList.remove',
610
+ 'basculer classe': 'classList.toggle',
611
+ 'contient classe': 'classList.contains',
612
+ 'style': 'style',
613
+ 'dataset': 'dataset',
614
+ 'parent': 'parentNode',
615
+ 'élément parent': 'parentElement',
616
+ 'enfants': 'children',
617
+ 'premier enfant': 'firstChild',
618
+ 'dernier enfant': 'lastChild',
619
+ 'premier élément enfant': 'firstElementChild',
620
+ 'dernier élément enfant': 'lastElementChild',
621
+ 'suivant dom': 'nextSibling',
622
+ 'précédent': 'previousSibling',
623
+ 'élément suivant': 'nextElementSibling',
624
+ 'élément précédent': 'previousElementSibling',
625
+ 'écouter': 'addEventListener',
626
+ 'ajouter écouteur': 'addEventListener',
627
+ 'supprimer écouteur': 'removeEventListener',
628
+ 'émettre événement': 'dispatchEvent',
629
+ 'empêcher défaut': 'preventDefault',
180
630
  'stopper propagation': 'stopPropagation',
631
+ 'cible': 'target',
632
+ 'cible courante': 'currentTarget',
633
+ 'clic': 'click',
634
+ 'double clic': 'dblclick',
635
+ 'souris bas': 'mousedown',
636
+ 'souris haut': 'mouseup',
637
+ 'souris entre': 'mouseenter',
638
+ 'souris quitte': 'mouseleave',
639
+ 'souris bouge': 'mousemove',
640
+ 'touche bas': 'keydown',
641
+ 'touche haut': 'keyup',
642
+ 'charger': 'load',
643
+ 'redimensionner': 'resize',
644
+ 'défiler': 'scroll',
645
+ 'focus': 'focus',
646
+ 'flou': 'blur',
647
+ 'soumettre': 'submit',
648
+ 'changer': 'change',
649
+ 'entrée': 'input',
650
+ 'récupérer': 'fetch',
651
+ 'chercher': 'fetch',
652
+ 'requête': 'Request',
653
+ 'réponse': 'Response',
654
+ 'en-têtes': 'Headers',
655
+ 'méthode': 'method',
656
+ 'corps': 'body',
657
+ 'mode': 'mode',
658
+ 'cache': 'cache',
659
+ 'signal': 'signal',
660
+ 'json': 'json',
661
+ 'texte': 'text',
662
+ 'blob': 'blob',
663
+ 'tableau buffer': 'arrayBuffer',
664
+ 'données formulaire': 'formData',
665
+ 'ok': 'ok',
666
+ 'statut': 'status',
667
+ 'texte statut': 'statusText',
668
+ 'url': 'url',
181
669
  'stockage local': 'localStorage',
182
670
  'stockage session': 'sessionStorage',
183
671
  'obtenir item': 'getItem',
184
- 'definir item': 'setItem',
672
+ 'définir item': 'setItem',
185
673
  'supprimer item': 'removeItem',
186
674
  'vider': 'clear',
675
+ 'clé': 'key',
187
676
  'temporisation': 'setTimeout',
188
- 'intervalle': 'setInterval',
677
+ 'définir délai': 'setTimeout',
189
678
  'annuler temporisation': 'clearTimeout',
679
+ 'annuler délai': 'clearTimeout',
680
+ 'intervalle': 'setInterval',
681
+ 'définir intervalle': 'setInterval',
190
682
  'annuler intervalle': 'clearInterval',
191
- 'promesse': 'Promise',
192
- 'resoudre': 'resolve',
193
- 'rejeter': 'reject',
194
- 'alors': 'then',
195
- 'capturer': 'catch',
196
- 'tout': 'all',
197
- 'course': 'race',
198
- 'recuperer': 'fetch',
199
- 'json': 'json',
200
- 'texte': 'text',
201
- 'reponse': 'response',
202
- 'requete': 'request',
203
- 'entetes': 'headers',
204
- 'corps': 'body',
205
- 'methode': 'method',
206
- 'analyser': 'JSON.parse',
207
- 'convertir': 'JSON.stringify',
208
- 'nombre': 'Number',
209
- 'chaine': 'String',
210
- 'booleen': 'Boolean',
211
- 'tableau': 'Array',
212
- 'objet': 'Object',
213
- 'date': 'Date',
214
- 'regex': 'RegExp',
215
- 'expression reguliere': 'RegExp',
216
- 'erreur': 'Error',
217
- 'erreur type': 'TypeError',
218
- 'erreur reference': 'ReferenceError',
219
- 'erreur syntaxe': 'SyntaxError',
220
- 'erreur plage': 'RangeError',
221
- 'math': 'Math',
222
- 'aleatoire': 'random',
223
- 'plancher': 'floor',
224
- 'plafond': 'ceil',
225
- 'arrondi': 'round',
226
- 'absolu': 'abs',
227
- 'minimum': 'min',
228
- 'maximum': 'max',
229
- 'puissance math': 'pow',
230
- 'racine': 'sqrt',
231
- 'sinus': 'sin',
232
- 'cosinus': 'cos',
233
- 'tangente': 'tan',
234
- 'pi': 'PI',
683
+ 'demander animation frame': 'requestAnimationFrame',
684
+ 'annuler animation frame': 'cancelAnimationFrame',
685
+ 'gestionnaire': 'handler',
686
+ 'cible proxy': 'target',
687
+ 'révocable': 'Proxy.revocable',
688
+ 'obtenir trap': 'get',
689
+ 'définir trap': 'set',
690
+ 'a trap': 'has',
691
+ 'supprimer propriété': 'deleteProperty',
692
+ 'appliquer trap': 'apply',
693
+ 'construire trap': 'construct',
694
+ 'propres clés': 'ownKeys',
695
+ 'réfléchir.obtenir': 'Reflect.get',
696
+ 'réfléchir.définir': 'Reflect.set',
697
+ 'réfléchir.a': 'Reflect.has',
698
+ 'réfléchir.supprimer propriété': 'Reflect.deleteProperty',
699
+ 'réfléchir.appliquer': 'Reflect.apply',
700
+ 'réfléchir.construire': 'Reflect.construct',
701
+ 'ajouter coll': 'add',
702
+ 'supprimer coll': 'delete',
703
+ 'a coll': 'has',
704
+ 'effacer': 'clear',
705
+ 'taille': 'size',
706
+ 'obtenir coll': 'get',
707
+ 'définir coll': 'set',
708
+ 'union': 'union',
709
+ 'intersection': 'intersection',
710
+ 'différence': 'difference',
711
+ 'différence symétrique': 'symmetricDifference',
712
+ 'est sous-ensemble de': 'isSubsetOf',
713
+ 'est sur-ensemble de': 'isSupersetOf',
714
+ 'grouper par carte': 'Map.groupBy',
235
715
  'maintenant': 'Date.now',
236
- 'heure actuelle': 'Date.now'
716
+ 'obtenir temps': 'getTime',
717
+ 'obtenir année': 'getFullYear',
718
+ 'obtenir mois': 'getMonth',
719
+ 'obtenir date': 'getDate',
720
+ 'obtenir jour': 'getDay',
721
+ 'obtenir heures': 'getHours',
722
+ 'obtenir minutes': 'getMinutes',
723
+ 'obtenir secondes': 'getSeconds',
724
+ 'obtenir millisecondes': 'getMilliseconds',
725
+ 'définir année': 'setFullYear',
726
+ 'définir mois': 'setMonth',
727
+ 'définir date jour': 'setDate',
728
+ 'définir heures': 'setHours',
729
+ 'définir minutes': 'setMinutes',
730
+ 'définir secondes': 'setSeconds',
731
+ 'vers chaîne ISO': 'toISOString',
732
+ 'vers chaîne locale': 'toLocaleString',
733
+ 'tester': 'test',
734
+ 'exécuter': 'exec',
735
+ 'source': 'source',
736
+ 'drapeaux': 'flags',
737
+ 'global': 'global',
738
+ 'ignorer casse': 'ignoreCase',
739
+ 'multiligne': 'multiline',
740
+ 'unicode': 'unicode',
741
+ 'collant': 'sticky',
742
+ 'dot all': 'dotAll',
743
+ 'dernier index': 'lastIndex',
744
+ 'tableau typé': 'TypedArray',
745
+ 'tableau int8': 'Int8Array',
746
+ 'tableau uint8': 'Uint8Array',
747
+ 'tableau int16': 'Int16Array',
748
+ 'tableau uint16': 'Uint16Array',
749
+ 'tableau int32': 'Int32Array',
750
+ 'tableau uint32': 'Uint32Array',
751
+ 'tableau float32': 'Float32Array',
752
+ 'tableau float64': 'Float64Array',
753
+ 'tableau bigint64': 'BigInt64Array',
754
+ 'tableau biguint64': 'BigUint64Array',
755
+ 'buffer tableau partagé': 'SharedArrayBuffer',
756
+ 'longueur octets': 'byteLength',
757
+ 'décalage octets': 'byteOffset',
758
+ 'buffer': 'buffer',
759
+ 'référence faible': 'WeakRef',
760
+ 'déréférencer': 'deref',
761
+ 'registre finalisation': 'FinalizationRegistry',
762
+ 'enregistrer': 'register',
763
+ 'désenregistrer': 'unregister',
764
+ 'pile jetable': 'DisposableStack',
765
+ 'pile jetable asynchrone': 'AsyncDisposableStack',
766
+ 'collateur': 'Intl.Collator',
767
+ 'format date temps': 'Intl.DateTimeFormat',
768
+ 'format liste': 'Intl.ListFormat',
769
+ 'locale': 'Intl.Locale',
770
+ 'format nombre': 'Intl.NumberFormat',
771
+ 'règles pluriel': 'Intl.PluralRules',
772
+ 'format temps relatif': 'Intl.RelativeTimeFormat',
773
+ 'segmenteur': 'Intl.Segmenter',
774
+ 'formater': 'format',
775
+ 'évaluer': 'eval',
776
+ 'décoder URI': 'decodeURI',
777
+ 'décoder composant URI': 'decodeURIComponent',
778
+ 'encoder URI': 'encodeURI',
779
+ 'encoder composant URI': 'encodeURIComponent'
237
780
  }
238
781
 
782
+ this.buildConflictResolution()
783
+ }
784
+
785
+ pushContext(ctx) {
786
+ this.context.push(ctx)
787
+ }
788
+
789
+ popContext() {
790
+ return this.context.pop()
791
+ }
792
+
793
+ getCurrentContext() {
794
+ return this.context.length > 0 ? this.context[this.context.length - 1] : null
795
+ }
796
+
797
+ translateWithContext(word, explicitContext = null) {
798
+ const lower = word.toLowerCase()
799
+ const ctx = explicitContext || this.getCurrentContext()
800
+
801
+ if (this.conflicts[lower] && ctx) {
802
+ const resolved = this.conflicts[lower][ctx] || this.conflicts[lower]['default']
803
+ if (resolved) return resolved
804
+ }
805
+
806
+ if (this.contextualMap[lower] && ctx) {
807
+ const resolved = this.contextualMap[lower][ctx]
808
+ if (resolved) return resolved
809
+ }
810
+
811
+ return this.keywordMap[lower] ||
812
+ this.operatorMap[lower] ||
813
+ this.methodMap[lower] ||
814
+ word
815
+ }
816
+
817
+ translate(word) {
239
818
  const lower = word.toLowerCase()
240
- return translations[lower] || word
819
+
820
+ if (this.keywordMap[lower]) {
821
+ return this.keywordMap[lower]
822
+ }
823
+ if (this.operatorMap[lower]) {
824
+ return this.operatorMap[lower]
825
+ }
826
+ if (this.methodMap[lower]) {
827
+ return this.methodMap[lower]
828
+ }
829
+
830
+ return word
831
+ }
832
+
833
+ translateOperator(op) {
834
+ const lower = op.toLowerCase()
835
+ return this.operatorMap[lower] || op
241
836
  }
242
837
 
243
838
  generate(ast) {
244
839
  this.output = ''
245
840
  this.indent = 0
841
+ this.context = []
246
842
 
247
843
  if (Array.isArray(ast)) {
248
844
  for (const node of ast) {
@@ -260,102 +856,137 @@ class JSGenerator {
260
856
  }
261
857
 
262
858
  generateNode(node) {
263
- if (!node) return
859
+ if (!node) return ''
264
860
 
265
861
  switch (node.type) {
266
862
  case 'Program':
267
- this.generateProgram(node)
268
- break
863
+ return this.generateProgram(node)
269
864
  case 'VariableDeclaration':
270
- this.generateVariableDeclaration(node)
271
- break
865
+ return this.generateVariableDeclaration(node)
272
866
  case 'FunctionDeclaration':
273
- this.generateFunctionDeclaration(node)
274
- break
867
+ return this.generateFunctionDeclaration(node)
868
+ case 'FunctionExpression':
869
+ return this.generateFunctionExpression(node)
275
870
  case 'ClassDeclaration':
276
- this.generateClassDeclaration(node)
277
- break
871
+ return this.generateClassDeclaration(node)
872
+ case 'ClassExpression':
873
+ return this.generateClassExpression(node)
278
874
  case 'IfStatement':
279
- this.generateIfStatement(node)
280
- break
875
+ return this.generateIfStatement(node)
281
876
  case 'ForStatement':
282
- this.generateForStatement(node)
283
- break
877
+ return this.generateForStatement(node)
284
878
  case 'ForOfStatement':
879
+ return this.generateForOfStatement(node)
285
880
  case 'ForInStatement':
286
- this.generateForOfStatement(node)
287
- break
881
+ return this.generateForInStatement(node)
882
+ case 'ForAwaitStatement':
883
+ return this.generateForAwaitStatement(node)
288
884
  case 'WhileStatement':
289
- this.generateWhileStatement(node)
290
- break
885
+ return this.generateWhileStatement(node)
291
886
  case 'DoWhileStatement':
292
- this.generateDoWhileStatement(node)
293
- break
887
+ return this.generateDoWhileStatement(node)
294
888
  case 'SwitchStatement':
295
- this.generateSwitchStatement(node)
296
- break
889
+ return this.generateSwitchStatement(node)
297
890
  case 'TryStatement':
298
- this.generateTryStatement(node)
299
- break
891
+ return this.generateTryStatement(node)
300
892
  case 'ReturnStatement':
301
- this.generateReturnStatement(node)
302
- break
893
+ return this.generateReturnStatement(node)
303
894
  case 'ThrowStatement':
304
- this.generateThrowStatement(node)
305
- break
895
+ return this.generateThrowStatement(node)
306
896
  case 'BreakStatement':
307
- this.writeLine('break;')
308
- break
897
+ return this.generateBreakStatement(node)
309
898
  case 'ContinueStatement':
310
- this.writeLine('continue;')
311
- break
899
+ return this.generateContinueStatement(node)
900
+ case 'LabeledStatement':
901
+ return this.generateLabeledStatement(node)
902
+ case 'DebuggerStatement':
903
+ return this.generateDebuggerStatement(node)
312
904
  case 'ExpressionStatement':
313
- this.generateExpressionStatement(node)
314
- break
905
+ return this.generateExpressionStatement(node)
315
906
  case 'BlockStatement':
316
- this.generateBlockStatement(node)
317
- break
907
+ return this.generateBlockStatement(node)
908
+ case 'EmptyStatement':
909
+ return ''
318
910
  case 'ImportDeclaration':
319
- this.generateImportDeclaration(node)
320
- break
911
+ return this.generateImportDeclaration(node)
321
912
  case 'ExportDeclaration':
322
913
  case 'ExportNamedDeclaration':
914
+ return this.generateExportDeclaration(node)
323
915
  case 'ExportDefaultDeclaration':
324
- this.generateExportDeclaration(node)
325
- break
916
+ return this.generateExportDefaultDeclaration(node)
917
+ case 'ExportAllDeclaration':
918
+ return this.generateExportAllDeclaration(node)
326
919
  case 'ArrowFunctionExpression':
327
920
  return this.generateArrowFunction(node)
328
- case 'FunctionExpression':
329
- return this.generateFunctionExpression(node)
330
921
  case 'CallExpression':
331
922
  return this.generateCallExpression(node)
332
923
  case 'MemberExpression':
333
924
  return this.generateMemberExpression(node)
925
+ case 'OptionalMemberExpression':
926
+ return this.generateOptionalMemberExpression(node)
927
+ case 'OptionalCallExpression':
928
+ return this.generateOptionalCallExpression(node)
929
+ case 'ChainExpression':
930
+ return this.generateChainExpression(node)
334
931
  case 'BinaryExpression':
335
932
  case 'LogicalExpression':
336
933
  return this.generateBinaryExpression(node)
337
934
  case 'UnaryExpression':
338
935
  return this.generateUnaryExpression(node)
936
+ case 'UpdateExpression':
937
+ return this.generateUpdateExpression(node)
339
938
  case 'AssignmentExpression':
340
939
  return this.generateAssignmentExpression(node)
940
+ case 'AssignmentPattern':
941
+ return this.generateAssignmentPattern(node)
341
942
  case 'ConditionalExpression':
342
943
  return this.generateConditionalExpression(node)
343
944
  case 'ObjectExpression':
344
945
  return this.generateObjectExpression(node)
946
+ case 'ObjectPattern':
947
+ return this.generateObjectPattern(node)
345
948
  case 'ArrayExpression':
346
949
  return this.generateArrayExpression(node)
950
+ case 'ArrayPattern':
951
+ return this.generateArrayPattern(node)
952
+ case 'SpreadElement':
953
+ return this.generateSpreadElement(node)
954
+ case 'RestElement':
955
+ return this.generateRestElement(node)
347
956
  case 'Identifier':
348
957
  return this.translate(node.name)
349
- case 'Parameter':
350
- return this.generateParameter(node)
958
+ case 'PrivateIdentifier':
959
+ return this.generatePrivateIdentifier(node)
351
960
  case 'Literal':
352
961
  return this.generateLiteral(node)
353
962
  case 'TemplateLiteral':
354
963
  return this.generateTemplateLiteral(node)
964
+ case 'TaggedTemplateExpression':
965
+ return this.generateTaggedTemplateExpression(node)
355
966
  case 'NewExpression':
356
967
  return this.generateNewExpression(node)
968
+ case 'ThisExpression':
969
+ return 'this'
970
+ case 'Super':
971
+ return 'super'
357
972
  case 'AwaitExpression':
358
973
  return this.generateAwaitExpression(node)
974
+ case 'YieldExpression':
975
+ return this.generateYieldExpression(node)
976
+ case 'SequenceExpression':
977
+ return this.generateSequenceExpression(node)
978
+ case 'Property':
979
+ return this.generateProperty(node)
980
+ case 'MethodDefinition':
981
+ return this.generateMethodDefinition(node)
982
+ case 'PropertyDefinition':
983
+ return this.generatePropertyDefinition(node)
984
+ case 'StaticBlock':
985
+ return this.generateStaticBlock(node)
986
+ case 'MetaProperty':
987
+ return this.generateMetaProperty(node)
988
+ case 'ImportExpression':
989
+ return this.generateImportExpression(node)
359
990
  default:
360
991
  if (node.expression) {
361
992
  return this.generateNode(node.expression)
@@ -371,22 +1002,23 @@ class JSGenerator {
371
1002
  }
372
1003
 
373
1004
  generateVariableDeclaration(node) {
374
- const kind = this.translate(node.kind || 'let')
375
-
376
- if (node.declarations && Array.isArray(node.declarations)) {
377
- for (const decl of node.declarations) {
378
- const name = this.generateNode(decl.id || decl.name)
379
- if (decl.init) {
380
- const init = this.generateNode(decl.init)
381
- this.writeLine(`${kind} ${name} = ${init};`)
382
- } else {
383
- this.writeLine(`${kind} ${name};`)
384
- }
385
- }
386
- } else {
387
- const name = typeof node.name === 'string' ? node.name : this.generateNode(node.name)
388
- if (node.init) {
389
- const init = this.generateNode(node.init)
1005
+ let kind = node.kind || 'let'
1006
+
1007
+ const kindTranslations = {
1008
+ 'variable': 'let',
1009
+ 'constante': 'const',
1010
+ 'variable globale': 'var',
1011
+ 'utilisant': 'using',
1012
+ 'attendre utilisant': 'await using'
1013
+ }
1014
+ kind = kindTranslations[kind.toLowerCase()] || this.translate(kind)
1015
+
1016
+ const declarations = node.declarations || []
1017
+
1018
+ for (const decl of declarations) {
1019
+ const name = this.generateNode(decl.id || decl.name)
1020
+ if (decl.init) {
1021
+ const init = this.generateNode(decl.init)
390
1022
  this.writeLine(`${kind} ${name} = ${init};`)
391
1023
  } else {
392
1024
  this.writeLine(`${kind} ${name};`)
@@ -397,8 +1029,8 @@ class JSGenerator {
397
1029
  generateFunctionDeclaration(node) {
398
1030
  const async = node.async ? 'async ' : ''
399
1031
  const generator = node.generator ? '*' : ''
400
- const name = this.translate(node.id?.name || node.name || '')
401
- const params = (node.params || []).map(p => this.generateParameter(p)).join(', ')
1032
+ const name = node.id ? this.translate(node.id.name || node.id) : ''
1033
+ const params = (node.params || []).map(p => this.generateNode(p)).join(', ')
402
1034
 
403
1035
  this.writeLine(`${async}function${generator} ${name}(${params}) {`)
404
1036
  this.indent++
@@ -411,45 +1043,23 @@ class JSGenerator {
411
1043
  generateFunctionExpression(node) {
412
1044
  const async = node.async ? 'async ' : ''
413
1045
  const generator = node.generator ? '*' : ''
414
- const name = node.name ? this.translate(node.name) : ''
415
- const params = (node.params || []).map(p => this.generateParameter(p)).join(', ')
416
-
417
- const bodyStatements = node.body?.body || []
418
- const bodyCode = bodyStatements.map(stmt => {
419
- const savedOutput = this.output
420
- const savedIndent = this.indent
421
- this.output = ''
422
- this.indent = 1
423
- this.generateNode(stmt)
424
- const stmtCode = this.output.trim()
425
- this.output = savedOutput
426
- this.indent = savedIndent
427
- return stmtCode
428
- }).join('\n ')
429
-
430
- return `${async}function${generator}${name ? ' ' + name : ''}(${params}) {\n ${bodyCode}\n }`
431
- }
1046
+ const name = node.id ? this.translate(node.id.name || node.id) : ''
1047
+ const params = (node.params || []).map(p => this.generateNode(p)).join(', ')
432
1048
 
433
- generateParameter(node) {
434
- if (!node) return ''
435
- if (typeof node === 'string') return node
436
- if (node.type === 'Identifier') return this.translate(node.name)
437
-
438
- let result = this.translate(node.name || '')
439
-
440
- if (node.typeAnnotation) {
441
- result += `: ${this.generateNode(node.typeAnnotation)}`
442
- }
443
-
444
- if (node.default) {
445
- result += ` = ${this.generateNode(node.default)}`
446
- }
447
-
448
- return result
1049
+ let body = ''
1050
+ const savedOutput = this.output
1051
+ this.output = ''
1052
+ this.indent++
1053
+ this.generateNode(node.body)
1054
+ this.indent--
1055
+ body = this.output.trim()
1056
+ this.output = savedOutput
1057
+
1058
+ return `${async}function${generator} ${name}(${params}) {\n${body}\n${this.getIndent()}}`
449
1059
  }
450
1060
 
451
1061
  generateClassDeclaration(node) {
452
- const name = this.translate(node.id?.name || node.name || '')
1062
+ const name = node.id ? (node.id.name || node.id) : ''
453
1063
  const extend = node.superClass ? ` extends ${this.generateNode(node.superClass)}` : ''
454
1064
 
455
1065
  this.writeLine(`class ${name}${extend} {`)
@@ -465,21 +1075,58 @@ class JSGenerator {
465
1075
  this.writeLine('')
466
1076
  }
467
1077
 
1078
+ generateClassExpression(node) {
1079
+ const name = node.id ? (node.id.name || node.id) : ''
1080
+ const extend = node.superClass ? ` extends ${this.generateNode(node.superClass)}` : ''
1081
+
1082
+ let body = ''
1083
+ const savedOutput = this.output
1084
+ this.output = ''
1085
+ this.indent++
1086
+ const members = node.body?.body || node.body || []
1087
+ for (const member of members) {
1088
+ this.generateClassMember(member)
1089
+ }
1090
+ this.indent--
1091
+ body = this.output.trim()
1092
+ this.output = savedOutput
1093
+
1094
+ return `class ${name}${extend} {\n${body}\n${this.getIndent()}}`
1095
+ }
1096
+
468
1097
  generateClassMember(node) {
469
1098
  const isStatic = node.static ? 'static ' : ''
1099
+ const isPrivate = node.key?.type === 'PrivateIdentifier'
470
1100
  const kind = node.kind || 'method'
471
- const name = this.translate(node.key?.name || node.name || '')
1101
+
1102
+ let name
1103
+ if (isPrivate) {
1104
+ name = '#' + (node.key.name || '')
1105
+ } else {
1106
+ const rawName = node.key?.name || node.name || ''
1107
+ if (rawName === 'constructeur') {
1108
+ name = 'constructor'
1109
+ } else if (rawName === 'obtenir') {
1110
+ name = 'get'
1111
+ } else if (rawName === 'définir') {
1112
+ name = 'set'
1113
+ } else {
1114
+ name = rawName
1115
+ }
1116
+ }
1117
+
472
1118
  const params = (node.value?.params || node.params || []).map(p => this.generateNode(p)).join(', ')
473
1119
 
474
1120
  if (kind === 'constructor' || name === 'constructor' || name === 'constructeur') {
475
1121
  this.writeLine(`constructor(${params}) {`)
476
- } else if (kind === 'get') {
1122
+ } else if (kind === 'get' || kind === 'obtenir') {
477
1123
  this.writeLine(`${isStatic}get ${name}() {`)
478
- } else if (kind === 'set') {
1124
+ } else if (kind === 'set' || kind === 'définir') {
479
1125
  this.writeLine(`${isStatic}set ${name}(${params}) {`)
480
1126
  } else {
481
1127
  const async = node.value?.async || node.async ? 'async ' : ''
482
- this.writeLine(`${isStatic}${async}${name}(${params}) {`)
1128
+ const generator = node.value?.generator || node.generator ? '*' : ''
1129
+ this.writeLine(`${isStatic}${async}${generator}${name}(${params}) {`)
483
1130
  }
484
1131
 
485
1132
  this.indent++
@@ -489,22 +1136,52 @@ class JSGenerator {
489
1136
  this.writeLine('')
490
1137
  }
491
1138
 
492
- generateIfStatement(node, isElseIf = false) {
493
- const test = this.generateNode(node.test || node.condition)
1139
+ generateMethodDefinition(node) {
1140
+ return this.generateClassMember(node)
1141
+ }
1142
+
1143
+ generatePropertyDefinition(node) {
1144
+ const isStatic = node.static ? 'static ' : ''
1145
+ const isPrivate = node.key?.type === 'PrivateIdentifier'
494
1146
 
495
- if (isElseIf) {
496
- this.writeLine(`} else if (${test}) {`)
1147
+ let name
1148
+ if (isPrivate) {
1149
+ name = '#' + (node.key.name || '')
497
1150
  } else {
498
- this.writeLine(`if (${test}) {`)
1151
+ name = node.computed ? `[${this.generateNode(node.key)}]` : this.generateNode(node.key)
499
1152
  }
500
1153
 
1154
+ if (node.value) {
1155
+ const value = this.generateNode(node.value)
1156
+ this.writeLine(`${isStatic}${name} = ${value};`)
1157
+ } else {
1158
+ this.writeLine(`${isStatic}${name};`)
1159
+ }
1160
+ }
1161
+
1162
+ generateStaticBlock(node) {
1163
+ this.writeLine('static {')
1164
+ this.indent++
1165
+ this.generateNode(node.body)
1166
+ this.indent--
1167
+ this.writeLine('}')
1168
+ }
1169
+
1170
+ generatePrivateIdentifier(node) {
1171
+ return '#' + (node.name || '')
1172
+ }
1173
+
1174
+ generateIfStatement(node) {
1175
+ const test = this.generateNode(node.test)
1176
+ this.writeLine(`if (${test}) {`)
501
1177
  this.indent++
502
1178
  this.generateNode(node.consequent)
503
1179
  this.indent--
504
1180
 
505
1181
  if (node.alternate) {
506
1182
  if (node.alternate.type === 'IfStatement') {
507
- this.generateIfStatement(node.alternate, true)
1183
+ this.output = this.output.trimEnd() + ' else '
1184
+ this.generateIfStatement(node.alternate)
508
1185
  } else {
509
1186
  this.writeLine('} else {')
510
1187
  this.indent++
@@ -518,7 +1195,19 @@ class JSGenerator {
518
1195
  }
519
1196
 
520
1197
  generateForStatement(node) {
521
- const init = node.init ? this.generateNode(node.init).replace(/;$/, '') : ''
1198
+ let init = ''
1199
+ if (node.init) {
1200
+ if (node.init.type === 'VariableDeclaration') {
1201
+ const kind = this.translate(node.init.kind || 'let')
1202
+ const decls = node.init.declarations.map(d => {
1203
+ const name = this.generateNode(d.id)
1204
+ return d.init ? `${name} = ${this.generateNode(d.init)}` : name
1205
+ }).join(', ')
1206
+ init = `${kind} ${decls}`
1207
+ } else {
1208
+ init = this.generateNode(node.init)
1209
+ }
1210
+ }
522
1211
  const test = node.test ? this.generateNode(node.test) : ''
523
1212
  const update = node.update ? this.generateNode(node.update) : ''
524
1213
 
@@ -530,15 +1219,63 @@ class JSGenerator {
530
1219
  }
531
1220
 
532
1221
  generateForOfStatement(node) {
533
- const left = this.generateNode(node.left)
1222
+ this.pushContext('loop')
1223
+ let left
1224
+ if (node.left.type === 'VariableDeclaration') {
1225
+ const kind = this.translate(node.left.kind || 'const')
1226
+ const name = this.generateNode(node.left.declarations[0].id)
1227
+ left = `${kind} ${name}`
1228
+ } else {
1229
+ left = this.generateNode(node.left)
1230
+ }
534
1231
  const right = this.generateNode(node.right)
535
- const keyword = node.type === 'ForInStatement' ? 'in' : 'of'
536
1232
 
537
- this.writeLine(`for (${left} ${keyword} ${right}) {`)
1233
+ this.writeLine(`for (${left} of ${right}) {`)
538
1234
  this.indent++
539
1235
  this.generateNode(node.body)
540
1236
  this.indent--
541
1237
  this.writeLine('}')
1238
+ this.popContext()
1239
+ }
1240
+
1241
+ generateForInStatement(node) {
1242
+ this.pushContext('loop')
1243
+ let left
1244
+ if (node.left.type === 'VariableDeclaration') {
1245
+ const kind = this.translate(node.left.kind || 'const')
1246
+ const name = this.generateNode(node.left.declarations[0].id)
1247
+ left = `${kind} ${name}`
1248
+ } else {
1249
+ left = this.generateNode(node.left)
1250
+ }
1251
+ const right = this.generateNode(node.right)
1252
+
1253
+ this.writeLine(`for (${left} in ${right}) {`)
1254
+ this.indent++
1255
+ this.generateNode(node.body)
1256
+ this.indent--
1257
+ this.writeLine('}')
1258
+ this.popContext()
1259
+ }
1260
+
1261
+ generateForAwaitStatement(node) {
1262
+ this.pushContext('loop')
1263
+ let left
1264
+ if (node.left.type === 'VariableDeclaration') {
1265
+ const kind = this.translate(node.left.kind || 'const')
1266
+ const name = this.generateNode(node.left.declarations[0].id)
1267
+ left = `${kind} ${name}`
1268
+ } else {
1269
+ left = this.generateNode(node.left)
1270
+ }
1271
+ const right = this.generateNode(node.right)
1272
+
1273
+ this.writeLine(`for await (${left} of ${right}) {`)
1274
+ this.indent++
1275
+ this.generateNode(node.body)
1276
+ this.indent--
1277
+ this.writeLine('}')
1278
+ this.popContext()
542
1279
  }
543
1280
 
544
1281
  generateWhileStatement(node) {
@@ -589,8 +1326,12 @@ class JSGenerator {
589
1326
  this.indent--
590
1327
 
591
1328
  if (node.handler) {
592
- const param = node.handler.param ? this.generateNode(node.handler.param) : 'e'
593
- this.writeLine(`} catch (${param}) {`)
1329
+ const param = node.handler.param ? this.generateNode(node.handler.param) : ''
1330
+ if (param) {
1331
+ this.writeLine(`} catch (${param}) {`)
1332
+ } else {
1333
+ this.writeLine('} catch {')
1334
+ }
594
1335
  this.indent++
595
1336
  this.generateNode(node.handler.body)
596
1337
  this.indent--
@@ -607,9 +1348,8 @@ class JSGenerator {
607
1348
  }
608
1349
 
609
1350
  generateReturnStatement(node) {
610
- const value = node.argument || node.value
611
- if (value) {
612
- const arg = this.generateNode(value)
1351
+ if (node.argument) {
1352
+ const arg = this.generateNode(node.argument)
613
1353
  this.writeLine(`return ${arg};`)
614
1354
  } else {
615
1355
  this.writeLine('return;')
@@ -621,9 +1361,37 @@ class JSGenerator {
621
1361
  this.writeLine(`throw ${arg};`)
622
1362
  }
623
1363
 
1364
+ generateBreakStatement(node) {
1365
+ if (node.label) {
1366
+ this.writeLine(`break ${this.generateNode(node.label)};`)
1367
+ } else {
1368
+ this.writeLine('break;')
1369
+ }
1370
+ }
1371
+
1372
+ generateContinueStatement(node) {
1373
+ if (node.label) {
1374
+ this.writeLine(`continue ${this.generateNode(node.label)};`)
1375
+ } else {
1376
+ this.writeLine('continue;')
1377
+ }
1378
+ }
1379
+
1380
+ generateLabeledStatement(node) {
1381
+ const label = this.generateNode(node.label)
1382
+ this.writeLine(`${label}:`)
1383
+ this.generateNode(node.body)
1384
+ }
1385
+
1386
+ generateDebuggerStatement(node) {
1387
+ this.writeLine('debugger;')
1388
+ }
1389
+
624
1390
  generateExpressionStatement(node) {
625
1391
  const expr = this.generateNode(node.expression)
626
- this.writeLine(`${expr};`)
1392
+ if (expr) {
1393
+ this.writeLine(`${expr};`)
1394
+ }
627
1395
  }
628
1396
 
629
1397
  generateBlockStatement(node) {
@@ -633,11 +1401,19 @@ class JSGenerator {
633
1401
  }
634
1402
 
635
1403
  generateImportDeclaration(node) {
1404
+ this.pushContext('module')
636
1405
  const source = this.generateLiteral(node.source)
637
1406
  const specifiers = node.specifiers || []
1407
+ const attributes = node.attributes || node.assertions || []
638
1408
 
639
1409
  if (specifiers.length === 0) {
640
- this.writeLine(`import ${source};`)
1410
+ if (attributes.length > 0) {
1411
+ const attrs = this.generateImportAttributes(attributes)
1412
+ this.writeLine(`import ${source} with ${attrs};`)
1413
+ } else {
1414
+ this.writeLine(`import ${source};`)
1415
+ }
1416
+ this.popContext()
641
1417
  return
642
1418
  }
643
1419
 
@@ -664,14 +1440,36 @@ class JSGenerator {
664
1440
  importParts.push(`{ ${named} }`)
665
1441
  }
666
1442
 
667
- this.writeLine(`import ${importParts.join(', ')} from ${source};`)
1443
+ if (attributes.length > 0) {
1444
+ const attrs = this.generateImportAttributes(attributes)
1445
+ this.writeLine(`import ${importParts.join(', ')} from ${source} with ${attrs};`)
1446
+ } else {
1447
+ this.writeLine(`import ${importParts.join(', ')} from ${source};`)
1448
+ }
1449
+ this.popContext()
1450
+ }
1451
+
1452
+ generateImportAttributes(attributes) {
1453
+ const attrs = attributes.map(attr => {
1454
+ const key = this.generateNode(attr.key)
1455
+ const value = this.generateNode(attr.value)
1456
+ return `${key}: ${value}`
1457
+ }).join(', ')
1458
+ return `{ ${attrs} }`
1459
+ }
1460
+
1461
+ generateImportExpression(node) {
1462
+ const source = this.generateNode(node.source)
1463
+ if (node.options) {
1464
+ const options = this.generateNode(node.options)
1465
+ return `import(${source}, ${options})`
1466
+ }
1467
+ return `import(${source})`
668
1468
  }
669
1469
 
670
1470
  generateExportDeclaration(node) {
671
- if (node.default || node.type === 'ExportDefaultDeclaration') {
672
- const decl = this.generateNode(node.declaration)
673
- this.writeLine(`export default ${decl};`)
674
- } else if (node.declaration) {
1471
+ this.pushContext('module')
1472
+ if (node.declaration) {
675
1473
  this.output += 'export '
676
1474
  this.generateNode(node.declaration)
677
1475
  } else if (node.specifiers) {
@@ -680,14 +1478,45 @@ class JSGenerator {
680
1478
  const exported = this.generateNode(s.exported)
681
1479
  return local === exported ? local : `${local} as ${exported}`
682
1480
  }).join(', ')
683
- this.writeLine(`export { ${specs} };`)
1481
+
1482
+ if (node.source) {
1483
+ const source = this.generateLiteral(node.source)
1484
+ this.writeLine(`export { ${specs} } from ${source};`)
1485
+ } else {
1486
+ this.writeLine(`export { ${specs} };`)
1487
+ }
1488
+ }
1489
+ this.popContext()
1490
+ }
1491
+
1492
+ generateExportDefaultDeclaration(node) {
1493
+ this.pushContext('module')
1494
+ const decl = this.generateNode(node.declaration)
1495
+ if (node.declaration.type === 'FunctionDeclaration' ||
1496
+ node.declaration.type === 'ClassDeclaration') {
1497
+ this.output = this.output.replace(/\n$/, '')
1498
+ } else {
1499
+ this.writeLine(`export default ${decl};`)
1500
+ }
1501
+ this.popContext()
1502
+ }
1503
+
1504
+ generateExportAllDeclaration(node) {
1505
+ const source = this.generateLiteral(node.source)
1506
+ if (node.exported) {
1507
+ const exported = this.generateNode(node.exported)
1508
+ this.writeLine(`export * as ${exported} from ${source};`)
1509
+ } else {
1510
+ this.writeLine(`export * from ${source};`)
684
1511
  }
685
1512
  }
686
1513
 
687
1514
  generateArrowFunction(node) {
688
1515
  const async = node.async ? 'async ' : ''
689
1516
  const params = (node.params || []).map(p => this.generateNode(p)).join(', ')
690
- const paramsStr = node.params?.length === 1 ? params : `(${params})`
1517
+ const paramsStr = node.params?.length === 1 && node.params[0].type === 'Identifier'
1518
+ ? params
1519
+ : `(${params})`
691
1520
 
692
1521
  if (node.body?.type === 'BlockStatement') {
693
1522
  let body = ''
@@ -713,19 +1542,56 @@ class JSGenerator {
713
1542
 
714
1543
  generateMemberExpression(node) {
715
1544
  const object = this.generateNode(node.object)
716
- const property = this.generateNode(node.property)
1545
+ const property = node.computed
1546
+ ? this.generateNode(node.property)
1547
+ : (node.property.name || this.generateNode(node.property))
717
1548
 
718
1549
  if (node.computed) {
719
1550
  return `${object}[${property}]`
720
1551
  }
721
- return `${object}.${property}`
1552
+
1553
+ const translatedProperty = this.translate(property)
1554
+
1555
+ if (translatedProperty.includes('.')) {
1556
+ const parts = translatedProperty.split('.')
1557
+ if (parts[0].toLowerCase() === object.toLowerCase()) {
1558
+ return translatedProperty
1559
+ }
1560
+ return `${object}.${parts.slice(-1)[0]}`
1561
+ }
1562
+
1563
+ return `${object}.${translatedProperty}`
1564
+ }
1565
+
1566
+ generateOptionalMemberExpression(node) {
1567
+ const object = this.generateNode(node.object)
1568
+ const property = node.computed
1569
+ ? this.generateNode(node.property)
1570
+ : (node.property.name || this.generateNode(node.property))
1571
+
1572
+ if (node.computed) {
1573
+ return `${object}?.[${property}]`
1574
+ }
1575
+
1576
+ const translatedProperty = this.translate(property)
1577
+ return `${object}?.${translatedProperty}`
1578
+ }
1579
+
1580
+ generateOptionalCallExpression(node) {
1581
+ const callee = this.generateNode(node.callee)
1582
+ const args = (node.arguments || []).map(a => this.generateNode(a)).join(', ')
1583
+ return `${callee}?.(${args})`
1584
+ }
1585
+
1586
+ generateChainExpression(node) {
1587
+ return this.generateNode(node.expression)
722
1588
  }
723
1589
 
724
1590
  generateBinaryExpression(node) {
725
1591
  const left = this.generateNode(node.left)
726
1592
  const right = this.generateNode(node.right)
727
1593
  const op = this.translateOperator(node.operator)
728
- return `${left} ${op} ${right}`
1594
+ return `(${left} ${op} ${right})`
729
1595
  }
730
1596
 
731
1597
  generateUnaryExpression(node) {
@@ -733,9 +1599,22 @@ class JSGenerator {
733
1599
  const op = this.translateOperator(node.operator)
734
1600
 
735
1601
  if (node.prefix) {
736
- return op === 'typeof' || op === 'delete' || op === 'void'
737
- ? `${op} ${arg}`
738
- : `${op}${arg}`
1602
+ if (op === 'typeof' || op === 'delete' || op === 'void' ||
1603
+ op === 'type de' || op === 'supprimer' || op === 'vide') {
1604
+ const translatedOp = this.translateOperator(op)
1605
+ return `${translatedOp} ${arg}`
1606
+ }
1607
+ return `${op}${arg}`
1608
+ }
1609
+ return `${arg}${op}`
1610
+ }
1611
+
1612
+ generateUpdateExpression(node) {
1613
+ const arg = this.generateNode(node.argument)
1614
+ const op = node.operator
1615
+
1616
+ if (node.prefix) {
1617
+ return `${op}${arg}`
739
1618
  }
740
1619
  return `${arg}${op}`
741
1620
  }
@@ -747,6 +1626,12 @@ class JSGenerator {
747
1626
  return `${left} ${op} ${right}`
748
1627
  }
749
1628
 
1629
+ generateAssignmentPattern(node) {
1630
+ const left = this.generateNode(node.left)
1631
+ const right = this.generateNode(node.right)
1632
+ return `${left} = ${right}`
1633
+ }
1634
+
750
1635
  generateConditionalExpression(node) {
751
1636
  const test = this.generateNode(node.test)
752
1637
  const consequent = this.generateNode(node.consequent)
@@ -756,17 +1641,10 @@ class JSGenerator {
756
1641
 
757
1642
  generateObjectExpression(node) {
758
1643
  const props = (node.properties || []).map(p => {
759
- const key = p.computed ? `[${this.generateNode(p.key)}]` : this.generateNode(p.key)
760
- const value = this.generateNode(p.value)
761
-
762
- if (p.shorthand || key === value) {
763
- return key
764
- }
765
- if (p.method) {
766
- const params = (p.value.params || []).map(param => this.generateNode(param)).join(', ')
767
- return `${key}(${params}) { ... }`
1644
+ if (p.type === 'SpreadElement') {
1645
+ return this.generateSpreadElement(p)
768
1646
  }
769
- return `${key}: ${value}`
1647
+ return this.generateProperty(p)
770
1648
  })
771
1649
 
772
1650
  if (props.length === 0) return '{}'
@@ -776,8 +1654,87 @@ class JSGenerator {
776
1654
  return `{\n${this.getIndent()} ${props.join(',\n' + this.getIndent() + ' ')}\n${this.getIndent()}}`
777
1655
  }
778
1656
 
1657
+ generateProperty(node) {
1658
+ const key = node.computed
1659
+ ? `[${this.generateNode(node.key)}]`
1660
+ : this.generateNode(node.key)
1661
+
1662
+ if (node.shorthand) {
1663
+ return key
1664
+ }
1665
+
1666
+ if (node.method) {
1667
+ const async = node.value?.async ? 'async ' : ''
1668
+ const generator = node.value?.generator ? '*' : ''
1669
+ const params = (node.value?.params || []).map(p => this.generateNode(p)).join(', ')
1670
+
1671
+ let body = ''
1672
+ const savedOutput = this.output
1673
+ this.output = ''
1674
+ this.indent++
1675
+ this.generateNode(node.value?.body)
1676
+ this.indent--
1677
+ body = this.output.trim()
1678
+ this.output = savedOutput
1679
+
1680
+ return `${async}${generator}${key}(${params}) {\n${body}\n${this.getIndent()}}`
1681
+ }
1682
+
1683
+ if (node.kind === 'get') {
1684
+ let body = ''
1685
+ const savedOutput = this.output
1686
+ this.output = ''
1687
+ this.indent++
1688
+ this.generateNode(node.value?.body)
1689
+ this.indent--
1690
+ body = this.output.trim()
1691
+ this.output = savedOutput
1692
+
1693
+ return `get ${key}() {\n${body}\n${this.getIndent()}}`
1694
+ }
1695
+
1696
+ if (node.kind === 'set') {
1697
+ const params = (node.value?.params || []).map(p => this.generateNode(p)).join(', ')
1698
+ let body = ''
1699
+ const savedOutput = this.output
1700
+ this.output = ''
1701
+ this.indent++
1702
+ this.generateNode(node.value?.body)
1703
+ this.indent--
1704
+ body = this.output.trim()
1705
+ this.output = savedOutput
1706
+
1707
+ return `set ${key}(${params}) {\n${body}\n${this.getIndent()}}`
1708
+ }
1709
+
1710
+ const value = this.generateNode(node.value)
1711
+ return `${key}: ${value}`
1712
+ }
1713
+
1714
+ generateObjectPattern(node) {
1715
+ const props = (node.properties || []).map(p => {
1716
+ if (p.type === 'RestElement') {
1717
+ return this.generateRestElement(p)
1718
+ }
1719
+
1720
+ const key = this.generateNode(p.key)
1721
+ const value = this.generateNode(p.value)
1722
+
1723
+ if (p.shorthand || key === value) {
1724
+ return key
1725
+ }
1726
+ return `${key}: ${value}`
1727
+ }).join(', ')
1728
+
1729
+ return `{ ${props} }`
1730
+ }
1731
+
779
1732
  generateArrayExpression(node) {
780
- const elements = (node.elements || []).map(e => e ? this.generateNode(e) : '')
1733
+ const elements = (node.elements || []).map(e => {
1734
+ if (!e) return ''
1735
+ if (e.type === 'SpreadElement') return this.generateSpreadElement(e)
1736
+ return this.generateNode(e)
1737
+ })
781
1738
 
782
1739
  if (elements.length === 0) return '[]'
783
1740
  if (elements.length <= 5 && !elements.some(e => e.includes('\n'))) {
@@ -786,16 +1743,39 @@ class JSGenerator {
786
1743
  return `[\n${this.getIndent()} ${elements.join(',\n' + this.getIndent() + ' ')}\n${this.getIndent()}]`
787
1744
  }
788
1745
 
1746
+ generateArrayPattern(node) {
1747
+ const elements = (node.elements || []).map(e => {
1748
+ if (!e) return ''
1749
+ if (e.type === 'RestElement') return this.generateRestElement(e)
1750
+ return this.generateNode(e)
1751
+ }).join(', ')
1752
+
1753
+ return `[${elements}]`
1754
+ }
1755
+
1756
+ generateSpreadElement(node) {
1757
+ const arg = this.generateNode(node.argument)
1758
+ return `...${arg}`
1759
+ }
1760
+
1761
+ generateRestElement(node) {
1762
+ const arg = this.generateNode(node.argument)
1763
+ return `...${arg}`
1764
+ }
1765
+
789
1766
  generateLiteral(node) {
790
1767
  if (node.raw) return node.raw
791
1768
  if (typeof node.value === 'string') {
792
- return `"${node.value.replace(/"/g, '\\"')}"`
1769
+ return `"${node.value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`
793
1770
  }
794
1771
  if (node.value === null) return 'null'
795
1772
  if (node.value === undefined) return 'undefined'
796
1773
  if (node.regex) {
797
1774
  return `/${node.regex.pattern}/${node.regex.flags}`
798
1775
  }
1776
+ if (typeof node.value === 'bigint' || (typeof node.value === 'string' && node.bigint)) {
1777
+ return `${node.value}n`
1778
+ }
799
1779
  return String(node.value)
800
1780
  }
801
1781
 
@@ -814,6 +1794,12 @@ class JSGenerator {
814
1794
  return result + '`'
815
1795
  }
816
1796
 
1797
+ generateTaggedTemplateExpression(node) {
1798
+ const tag = this.generateNode(node.tag)
1799
+ const quasi = this.generateTemplateLiteral(node.quasi)
1800
+ return `${tag}${quasi}`
1801
+ }
1802
+
817
1803
  generateNewExpression(node) {
818
1804
  const callee = this.generateNode(node.callee)
819
1805
  const args = (node.arguments || []).map(a => this.generateNode(a)).join(', ')
@@ -825,21 +1811,24 @@ class JSGenerator {
825
1811
  return `await ${arg}`
826
1812
  }
827
1813
 
828
- translateOperator(op) {
829
- const operators = {
830
- 'et': '&&',
831
- 'ou': '||',
832
- 'non': '!',
833
- 'egal': '===',
834
- 'different': '!==',
835
- 'plus': '+',
836
- 'moins': '-',
837
- 'fois': '*',
838
- 'divise': '/',
839
- 'modulo': '%',
840
- 'puissance': '**'
1814
+ generateYieldExpression(node) {
1815
+ const delegate = node.delegate ? '*' : ''
1816
+ if (node.argument) {
1817
+ const arg = this.generateNode(node.argument)
1818
+ return `yield${delegate} ${arg}`
841
1819
  }
842
- return operators[op] || op
1820
+ return `yield${delegate}`
1821
+ }
1822
+
1823
+ generateSequenceExpression(node) {
1824
+ const expressions = (node.expressions || []).map(e => this.generateNode(e))
1825
+ return `(${expressions.join(', ')})`
1826
+ }
1827
+
1828
+ generateMetaProperty(node) {
1829
+ const meta = node.meta?.name || node.meta
1830
+ const property = node.property?.name || node.property
1831
+ return `${meta}.${property}`
843
1832
  }
844
1833
 
845
1834
  writeLine(text) {
@@ -853,4 +1842,4 @@ class JSGenerator {
853
1842
 
854
1843
  module.exports = {
855
1844
  JSGenerator
856
- }
1845
+ }