ether-code 0.1.6 → 0.1.7

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.
Files changed (44) hide show
  1. package/cli/ether.js +1 -1
  2. package/generators/css-generator.js +42 -55
  3. package/generators/graphql-generator.js +19 -22
  4. package/generators/html-generator.js +51 -220
  5. package/generators/js-generator.js +76 -157
  6. package/generators/node-generator.js +49 -93
  7. package/generators/php-generator.js +46 -68
  8. package/generators/python-generator.js +35 -54
  9. package/generators/react-generator.js +37 -47
  10. package/generators/ruby-generator.js +59 -119
  11. package/generators/sql-generator.js +42 -63
  12. package/generators/ts-generator.js +59 -133
  13. package/i18n/i18n-css.json +147 -147
  14. package/i18n/i18n-graphql.json +6 -6
  15. package/i18n/i18n-html.json +135 -135
  16. package/i18n/i18n-js.json +107 -107
  17. package/i18n/i18n-node.json +14 -14
  18. package/i18n/i18n-php.json +177 -177
  19. package/i18n/i18n-python.json +16 -16
  20. package/i18n/i18n-react.json +97 -97
  21. package/i18n/i18n-ruby.json +22 -22
  22. package/i18n/i18n-sql.json +153 -153
  23. package/i18n/i18n-ts.json +10 -10
  24. package/lexer/ether-lexer.js +175 -34
  25. package/lexer/tokens.js +6 -6
  26. package/package.json +1 -1
  27. package/parsers/ast-css.js +0 -545
  28. package/parsers/ast-graphql.js +0 -424
  29. package/parsers/ast-html.js +0 -886
  30. package/parsers/ast-js.js +0 -750
  31. package/parsers/ast-node.js +0 -2440
  32. package/parsers/ast-php.js +0 -957
  33. package/parsers/ast-react.js +0 -580
  34. package/parsers/ast-ruby.js +0 -895
  35. package/parsers/ast-ts.js +0 -1352
  36. package/parsers/css-parser.js +0 -1981
  37. package/parsers/graphql-parser.js +0 -2011
  38. package/parsers/html-parser.js +0 -1182
  39. package/parsers/js-parser.js +0 -2564
  40. package/parsers/node-parser.js +0 -2644
  41. package/parsers/php-parser.js +0 -3037
  42. package/parsers/react-parser.js +0 -1035
  43. package/parsers/ruby-parser.js +0 -2680
  44. package/parsers/ts-parser.js +0 -3881
@@ -1,2644 +0,0 @@
1
- const AST = require('./ast-node')
2
-
3
- class NodeParser {
4
- constructor(i18n = null) {
5
- this.i18n = i18n || {}
6
- this.pos = 0
7
- this.input = ''
8
- this.tokens = []
9
- this.current = 0
10
- this.lang = 'fr'
11
- }
12
-
13
- setLanguage(lang) {
14
- this.lang = lang
15
- }
16
-
17
- buildKeywordMap() {
18
- const map = {}
19
- const addMapping = (category, key, nodeValue) => {
20
- if (this.i18n[category] && this.i18n[category][key]) {
21
- const translations = this.i18n[category][key]
22
- Object.values(translations).forEach(term => {
23
- if (term) map[term.toLowerCase()] = nodeValue
24
- })
25
- }
26
- }
27
-
28
- addMapping('modulesCommonJS', 'charger', 'require')
29
- addMapping('modulesCommonJS', 'moduleNode', 'module')
30
- addMapping('modulesCommonJS', 'exporter', 'exports')
31
- addMapping('modulesCommonJS', 'moduleExports', 'module.exports')
32
-
33
- addMapping('modulesES', 'importer', 'import')
34
- addMapping('modulesES', 'exporterES', 'export')
35
- addMapping('modulesES', 'exporterDefaut', 'export default')
36
- addMapping('modulesES', 'importerDynamique', 'import()')
37
-
38
- addMapping('fsLecture', 'lireFichier', 'fs.readFile')
39
- addMapping('fsLecture', 'lireFichierSync', 'fs.readFileSync')
40
- addMapping('fsLecture', 'lireRepertoire', 'fs.readdir')
41
- addMapping('fsLecture', 'lireRepertoireSync', 'fs.readdirSync')
42
-
43
- addMapping('fsEcriture', 'ecrireFichier', 'fs.writeFile')
44
- addMapping('fsEcriture', 'ecrireFichierSync', 'fs.writeFileSync')
45
- addMapping('fsEcriture', 'ajouterFichier', 'fs.appendFile')
46
- addMapping('fsEcriture', 'ajouterFichierSync', 'fs.appendFileSync')
47
-
48
- addMapping('fsGestion', 'creerDossier', 'fs.mkdir')
49
- addMapping('fsGestion', 'creerDossierSync', 'fs.mkdirSync')
50
- addMapping('fsGestion', 'supprimerFichier', 'fs.unlink')
51
- addMapping('fsGestion', 'supprimerFichierSync', 'fs.unlinkSync')
52
- addMapping('fsGestion', 'supprimerDossier', 'fs.rmdir')
53
- addMapping('fsGestion', 'supprimerDossierSync', 'fs.rmdirSync')
54
- addMapping('fsGestion', 'supprimer', 'fs.rm')
55
- addMapping('fsGestion', 'supprimerSync', 'fs.rmSync')
56
- addMapping('fsGestion', 'renommerFichier', 'fs.rename')
57
- addMapping('fsGestion', 'renommerSync', 'fs.renameSync')
58
- addMapping('fsGestion', 'copierFichier', 'fs.copyFile')
59
- addMapping('fsGestion', 'copierFichierSync', 'fs.copyFileSync')
60
-
61
- addMapping('fsInfos', 'statsFichier', 'fs.stat')
62
- addMapping('fsInfos', 'statsSync', 'fs.statSync')
63
- addMapping('fsInfos', 'lienStats', 'fs.lstat')
64
- addMapping('fsInfos', 'existeFichier', 'fs.existsSync')
65
- addMapping('fsInfos', 'accesFichier', 'fs.access')
66
- addMapping('fsInfos', 'accesSync', 'fs.accessSync')
67
-
68
- addMapping('fsFlux', 'creerFluxLecture', 'fs.createReadStream')
69
- addMapping('fsFlux', 'creerFluxEcriture', 'fs.createWriteStream')
70
-
71
- addMapping('fsSurveillance', 'surveillerFichier', 'fs.watchFile')
72
- addMapping('fsSurveillance', 'arreterSurveillance', 'fs.unwatchFile')
73
- addMapping('fsSurveillance', 'surveiller', 'fs.watch')
74
-
75
- addMapping('path', 'joindre', 'path.join')
76
- addMapping('path', 'resoudre', 'path.resolve')
77
- addMapping('path', 'normaliser', 'path.normalize')
78
- addMapping('path', 'estAbsolu', 'path.isAbsolute')
79
- addMapping('path', 'relatif', 'path.relative')
80
- addMapping('path', 'repertoire', 'path.dirname')
81
- addMapping('path', 'nomBase', 'path.basename')
82
- addMapping('path', 'extension', 'path.extname')
83
- addMapping('path', 'analyser', 'path.parse')
84
- addMapping('path', 'formater', 'path.format')
85
-
86
- addMapping('httpServeur', 'creerServeur', 'http.createServer')
87
- addMapping('httpServeur', 'creerServeurSecurise', 'https.createServer')
88
- addMapping('httpServeur', 'ecouter', 'server.listen')
89
- addMapping('httpServeur', 'fermerServeur', 'server.close')
90
-
91
- addMapping('httpRequete', 'requeteHttp', 'http.request')
92
- addMapping('httpRequete', 'recuperer', 'http.get')
93
- addMapping('httpRequete', 'requeteSecurisee', 'https.request')
94
- addMapping('httpRequete', 'recupererSecurise', 'https.get')
95
-
96
- addMapping('httpResponse', 'codeStatut', 'res.statusCode')
97
- addMapping('httpResponse', 'messageStatut', 'res.statusMessage')
98
- addMapping('httpResponse', 'definirEntete', 'res.setHeader')
99
- addMapping('httpResponse', 'obtenirEntete', 'res.getHeader')
100
- addMapping('httpResponse', 'supprimerEntete', 'res.removeHeader')
101
- addMapping('httpResponse', 'ecrireEntete', 'res.writeHead')
102
- addMapping('httpResponse', 'ecrireReponse', 'res.write')
103
- addMapping('httpResponse', 'terminerReponse', 'res.end')
104
-
105
- addMapping('process', 'arguments', 'process.argv')
106
- addMapping('process', 'environnement', 'process.env')
107
- addMapping('process', 'idProcessus', 'process.pid')
108
- addMapping('process', 'plateforme', 'process.platform')
109
- addMapping('process', 'architecture', 'process.arch')
110
- addMapping('process', 'versionNode', 'process.version')
111
-
112
- addMapping('processMethodes', 'repertoireCourant', 'process.cwd')
113
- addMapping('processMethodes', 'changerRepertoire', 'process.chdir')
114
- addMapping('processMethodes', 'quitter', 'process.exit')
115
- addMapping('processMethodes', 'tuer', 'process.kill')
116
- addMapping('processMethodes', 'prochainTick', 'process.nextTick')
117
- addMapping('processMethodes', 'utilisationMemoire', 'process.memoryUsage')
118
- addMapping('processMethodes', 'utilisationCpu', 'process.cpuUsage')
119
- addMapping('processMethodes', 'tempsExecution', 'process.uptime')
120
- addMapping('processMethodes', 'tempsHauteResolution', 'process.hrtime')
121
-
122
- addMapping('processFlux', 'entreeStandard', 'process.stdin')
123
- addMapping('processFlux', 'sortieStandard', 'process.stdout')
124
- addMapping('processFlux', 'sortieErreur', 'process.stderr')
125
-
126
- addMapping('events', 'EmetteurEvenements', 'EventEmitter')
127
- addMapping('events', 'emettre', 'emit')
128
- addMapping('events', 'surEvenement', 'on')
129
- addMapping('events', 'uneFois', 'once')
130
- addMapping('events', 'supprimerEcouteur', 'removeListener')
131
- addMapping('events', 'supprimerTousEcouteurs', 'removeAllListeners')
132
- addMapping('events', 'ecouteurs', 'listeners')
133
- addMapping('events', 'nombreEcouteurs', 'listenerCount')
134
- addMapping('events', 'definirMaxEcouteurs', 'setMaxListeners')
135
-
136
- addMapping('streams', 'FluxLecture', 'stream.Readable')
137
- addMapping('streams', 'FluxEcriture', 'stream.Writable')
138
- addMapping('streams', 'FluxDuplex', 'stream.Duplex')
139
- addMapping('streams', 'FluxTransformation', 'stream.Transform')
140
- addMapping('streams', 'FluxPassage', 'stream.PassThrough')
141
- addMapping('streams', 'tuyauter', 'pipe')
142
- addMapping('streams', 'detuyauter', 'unpipe')
143
- addMapping('streams', 'lireFlux', 'read')
144
- addMapping('streams', 'ecrireFlux', 'write')
145
- addMapping('streams', 'terminerFlux', 'end')
146
- addMapping('streams', 'detruireFlux', 'destroy')
147
- addMapping('streams', 'pauserFlux', 'pause')
148
- addMapping('streams', 'reprendreFlux', 'resume')
149
-
150
- addMapping('buffer', 'tamponAlloc', 'Buffer.alloc')
151
- addMapping('buffer', 'tamponAllocNonSecurise', 'Buffer.allocUnsafe')
152
- addMapping('buffer', 'tamponDepuis', 'Buffer.from')
153
- addMapping('buffer', 'concatenerTampons', 'Buffer.concat')
154
- addMapping('buffer', 'comparerTampons', 'Buffer.compare')
155
- addMapping('buffer', 'estTampon', 'Buffer.isBuffer')
156
- addMapping('buffer', 'tailleOctets', 'Buffer.byteLength')
157
- addMapping('buffer', 'versChaine', 'toString')
158
- addMapping('buffer', 'versJSON', 'toJSON')
159
- addMapping('buffer', 'copier', 'copy')
160
- addMapping('buffer', 'trancher', 'slice')
161
- addMapping('buffer', 'sousTableau', 'subarray')
162
- addMapping('buffer', 'remplir', 'fill')
163
- addMapping('buffer', 'inclut', 'includes')
164
-
165
- addMapping('os', 'typeOS', 'os.type')
166
- addMapping('os', 'plateformeOS', 'os.platform')
167
- addMapping('os', 'architectureOS', 'os.arch')
168
- addMapping('os', 'versionOS', 'os.version')
169
- addMapping('os', 'releaseOS', 'os.release')
170
- addMapping('os', 'nomHote', 'os.hostname')
171
- addMapping('os', 'memoireTotale', 'os.totalmem')
172
- addMapping('os', 'memoireLibre', 'os.freemem')
173
- addMapping('os', 'cpus', 'os.cpus')
174
- addMapping('os', 'chargeSysteme', 'os.loadavg')
175
- addMapping('os', 'infoUtilisateur', 'os.userInfo')
176
- addMapping('os', 'repertoireHome', 'os.homedir')
177
- addMapping('os', 'repertoireTemp', 'os.tmpdir')
178
- addMapping('os', 'interfacesReseau', 'os.networkInterfaces')
179
- addMapping('os', 'tempsActivite', 'os.uptime')
180
-
181
- addMapping('crypto', 'creerHash', 'crypto.createHash')
182
- addMapping('crypto', 'creerHmac', 'crypto.createHmac')
183
- addMapping('crypto', 'mettreAJour', 'update')
184
- addMapping('crypto', 'digest', 'digest')
185
- addMapping('crypto', 'creerChiffreur', 'crypto.createCipheriv')
186
- addMapping('crypto', 'creerDechiffreur', 'crypto.createDecipheriv')
187
- addMapping('crypto', 'octetsAleatoires', 'crypto.randomBytes')
188
- addMapping('crypto', 'remplirAleatoire', 'crypto.randomFill')
189
- addMapping('crypto', 'uuidAleatoire', 'crypto.randomUUID')
190
- addMapping('crypto', 'entierAleatoire', 'crypto.randomInt')
191
- addMapping('crypto', 'pbkdf2', 'crypto.pbkdf2')
192
- addMapping('crypto', 'pbkdf2Sync', 'crypto.pbkdf2Sync')
193
- addMapping('crypto', 'scrypt', 'crypto.scrypt')
194
- addMapping('crypto', 'scryptSync', 'crypto.scryptSync')
195
- addMapping('crypto', 'creerSignature', 'crypto.createSign')
196
- addMapping('crypto', 'creerVerificateur', 'crypto.createVerify')
197
- addMapping('crypto', 'signer', 'sign')
198
- addMapping('crypto', 'verifier', 'verify')
199
-
200
- addMapping('url', 'URLNode', 'URL')
201
- addMapping('url', 'analyserUrl', 'url.parse')
202
- addMapping('url', 'formaterUrl', 'url.format')
203
- addMapping('url', 'resoudreUrl', 'url.resolve')
204
- addMapping('url', 'ParamsRecherche', 'URLSearchParams')
205
- addMapping('url', 'obtenir', 'get')
206
- addMapping('url', 'obtenirTous', 'getAll')
207
- addMapping('url', 'ajouter', 'append')
208
- addMapping('url', 'definir', 'set')
209
- addMapping('url', 'possede', 'has')
210
- addMapping('url', 'trier', 'sort')
211
-
212
- addMapping('childProcess', 'spawn', 'child_process.spawn')
213
- addMapping('childProcess', 'exec', 'child_process.exec')
214
- addMapping('childProcess', 'execFile', 'child_process.execFile')
215
- addMapping('childProcess', 'fork', 'child_process.fork')
216
- addMapping('childProcess', 'spawnSync', 'child_process.spawnSync')
217
- addMapping('childProcess', 'execSync', 'child_process.execSync')
218
- addMapping('childProcess', 'execFileSync', 'child_process.execFileSync')
219
- addMapping('childProcess', 'tuerEnfant', 'child.kill')
220
- addMapping('childProcess', 'envoyerMessage', 'child.send')
221
- addMapping('childProcess', 'deconnecterEnfant', 'child.disconnect')
222
-
223
- addMapping('util', 'promisifier', 'util.promisify')
224
- addMapping('util', 'callbackifier', 'util.callbackify')
225
- addMapping('util', 'formaterUtil', 'util.format')
226
- addMapping('util', 'inspecter', 'util.inspect')
227
- addMapping('util', 'obsolete', 'util.deprecate')
228
- addMapping('util', 'estTableau', 'util.types.isArray')
229
- addMapping('util', 'estDate', 'util.types.isDate')
230
- addMapping('util', 'estErreur', 'util.types.isNativeError')
231
- addMapping('util', 'estPromesse', 'util.types.isPromise')
232
- addMapping('util', 'estRegExp', 'util.types.isRegExp')
233
-
234
- addMapping('dns', 'resoudreHote', 'dns.lookup')
235
- addMapping('dns', 'resoudre', 'dns.resolve')
236
- addMapping('dns', 'resoudre4', 'dns.resolve4')
237
- addMapping('dns', 'resoudre6', 'dns.resolve6')
238
- addMapping('dns', 'resoudreMx', 'dns.resolveMx')
239
- addMapping('dns', 'resoudreTxt', 'dns.resolveTxt')
240
- addMapping('dns', 'resoudreNs', 'dns.resolveNs')
241
- addMapping('dns', 'resoudreCname', 'dns.resolveCname')
242
- addMapping('dns', 'resoudreInverse', 'dns.reverse')
243
-
244
- addMapping('timers', 'definirDelai', 'setTimeout')
245
- addMapping('timers', 'annulerDelai', 'clearTimeout')
246
- addMapping('timers', 'definirIntervalle', 'setInterval')
247
- addMapping('timers', 'annulerIntervalle', 'clearInterval')
248
- addMapping('timers', 'definirImmediat', 'setImmediate')
249
- addMapping('timers', 'annulerImmediat', 'clearImmediate')
250
-
251
- addMapping('console', 'afficher', 'console.log')
252
- addMapping('console', 'erreur', 'console.error')
253
- addMapping('console', 'avertir', 'console.warn')
254
- addMapping('console', 'info', 'console.info')
255
- addMapping('console', 'debug', 'console.debug')
256
- addMapping('console', 'tableau', 'console.table')
257
- addMapping('console', 'temps', 'console.time')
258
- addMapping('console', 'finTemps', 'console.timeEnd')
259
- addMapping('console', 'tempsLog', 'console.timeLog')
260
- addMapping('console', 'trace', 'console.trace')
261
- addMapping('console', 'vider', 'console.clear')
262
- addMapping('console', 'compter', 'console.count')
263
- addMapping('console', 'reinitialiserCompteur', 'console.countReset')
264
- addMapping('console', 'groupe', 'console.group')
265
- addMapping('console', 'finGroupe', 'console.groupEnd')
266
- addMapping('console', 'groupeReduit', 'console.groupCollapsed')
267
- addMapping('console', 'affirmer', 'console.assert')
268
- addMapping('console', 'repertoireConsole', 'console.dir')
269
-
270
- addMapping('globaux', 'global', 'global')
271
- addMapping('globaux', 'globalThis', 'globalThis')
272
- addMapping('globaux', 'nomFichier', '__filename')
273
- addMapping('globaux', 'nomRepertoire', '__dirname')
274
-
275
- addMapping('globauxModule', 'exportations', 'exports')
276
- addMapping('globauxModule', 'cacheRequire', 'require.cache')
277
- addMapping('globauxModule', 'resoudreRequire', 'require.resolve')
278
-
279
- return map
280
- }
281
-
282
- tokenize(input) {
283
- this.input = input
284
- this.pos = 0
285
- this.tokens = []
286
-
287
- while (this.pos < input.length) {
288
- this.skipWhitespace()
289
- if (this.pos >= input.length) break
290
-
291
- const char = input[this.pos]
292
-
293
- if (char === '/' && input[this.pos + 1] === '/') {
294
- this.skipLineComment()
295
- continue
296
- }
297
-
298
- if (char === '/' && input[this.pos + 1] === '*') {
299
- this.skipBlockComment()
300
- continue
301
- }
302
-
303
- if (char === '"' || char === "'") {
304
- this.tokens.push(this.readString())
305
- continue
306
- }
307
-
308
- if (char === '`') {
309
- this.tokens.push(this.readTemplateLiteral())
310
- continue
311
- }
312
-
313
- if (/[0-9]/.test(char)) {
314
- this.tokens.push(this.readNumber())
315
- continue
316
- }
317
-
318
- if (/[a-zA-Z_$\u00C0-\u024F\u0400-\u04FF\u4E00-\u9FFF\u3040-\u309F\u30A0-\u30FF]/.test(char)) {
319
- this.tokens.push(this.readIdentifier())
320
- continue
321
- }
322
-
323
- if ('(){}[],.;:'.includes(char)) {
324
- this.tokens.push({ type: 'punctuation', value: char })
325
- this.pos++
326
- continue
327
- }
328
-
329
- if ('+-*/%=<>!&|^~?@#'.includes(char)) {
330
- this.tokens.push(this.readOperator())
331
- continue
332
- }
333
-
334
- this.pos++
335
- }
336
-
337
- return this.tokens
338
- }
339
-
340
- skipWhitespace() {
341
- while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) {
342
- this.pos++
343
- }
344
- }
345
-
346
- skipLineComment() {
347
- while (this.pos < this.input.length && this.input[this.pos] !== '\n') {
348
- this.pos++
349
- }
350
- }
351
-
352
- skipBlockComment() {
353
- this.pos += 2
354
- while (this.pos < this.input.length - 1) {
355
- if (this.input[this.pos] === '*' && this.input[this.pos + 1] === '/') {
356
- this.pos += 2
357
- return
358
- }
359
- this.pos++
360
- }
361
- }
362
-
363
- readString() {
364
- const quote = this.input[this.pos]
365
- let value = ''
366
- this.pos++
367
- while (this.pos < this.input.length && this.input[this.pos] !== quote) {
368
- if (this.input[this.pos] === '\\') {
369
- this.pos++
370
- value += this.input[this.pos] || ''
371
- } else {
372
- value += this.input[this.pos]
373
- }
374
- this.pos++
375
- }
376
- this.pos++
377
- return { type: 'string', value, raw: `${quote}${value}${quote}` }
378
- }
379
-
380
- readTemplateLiteral() {
381
- this.pos++
382
- let value = ''
383
- const expressions = []
384
- while (this.pos < this.input.length && this.input[this.pos] !== '`') {
385
- if (this.input[this.pos] === '$' && this.input[this.pos + 1] === '{') {
386
- expressions.push({ quasi: value, start: this.pos })
387
- value = ''
388
- this.pos += 2
389
- let depth = 1
390
- let expr = ''
391
- while (depth > 0 && this.pos < this.input.length) {
392
- if (this.input[this.pos] === '{') depth++
393
- if (this.input[this.pos] === '}') depth--
394
- if (depth > 0) expr += this.input[this.pos]
395
- this.pos++
396
- }
397
- expressions[expressions.length - 1].expression = expr
398
- } else {
399
- value += this.input[this.pos]
400
- this.pos++
401
- }
402
- }
403
- this.pos++
404
- return { type: 'template', value, expressions }
405
- }
406
-
407
- readNumber() {
408
- let value = ''
409
- let isFloat = false
410
- let isHex = false
411
- let isBinary = false
412
- let isOctal = false
413
-
414
- if (this.input[this.pos] === '0') {
415
- if (this.input[this.pos + 1] === 'x' || this.input[this.pos + 1] === 'X') {
416
- isHex = true
417
- value = '0x'
418
- this.pos += 2
419
- } else if (this.input[this.pos + 1] === 'b' || this.input[this.pos + 1] === 'B') {
420
- isBinary = true
421
- value = '0b'
422
- this.pos += 2
423
- } else if (this.input[this.pos + 1] === 'o' || this.input[this.pos + 1] === 'O') {
424
- isOctal = true
425
- value = '0o'
426
- this.pos += 2
427
- }
428
- }
429
-
430
- while (this.pos < this.input.length) {
431
- const char = this.input[this.pos]
432
- if (isHex && /[0-9a-fA-F_]/.test(char)) {
433
- if (char !== '_') value += char
434
- this.pos++
435
- } else if (isBinary && /[01_]/.test(char)) {
436
- if (char !== '_') value += char
437
- this.pos++
438
- } else if (isOctal && /[0-7_]/.test(char)) {
439
- if (char !== '_') value += char
440
- this.pos++
441
- } else if (!isHex && !isBinary && !isOctal && /[0-9_]/.test(char)) {
442
- if (char !== '_') value += char
443
- this.pos++
444
- } else if (char === '.' && !isFloat && !isHex && !isBinary && !isOctal) {
445
- isFloat = true
446
- value += char
447
- this.pos++
448
- } else if ((char === 'e' || char === 'E') && !isHex && !isBinary && !isOctal) {
449
- value += char
450
- this.pos++
451
- if (this.input[this.pos] === '+' || this.input[this.pos] === '-') {
452
- value += this.input[this.pos]
453
- this.pos++
454
- }
455
- } else if (char === 'n') {
456
- this.pos++
457
- return { type: 'bigint', value: BigInt(value), raw: value + 'n' }
458
- } else {
459
- break
460
- }
461
- }
462
-
463
- return { type: 'number', value: isFloat ? parseFloat(value) : parseInt(value), raw: value }
464
- }
465
-
466
- readIdentifier() {
467
- let value = ''
468
- while (this.pos < this.input.length && /[a-zA-Z0-9_$\u00C0-\u024F\u0400-\u04FF\u4E00-\u9FFF\u3040-\u309F\u30A0-\u30FF]/.test(this.input[this.pos])) {
469
- value += this.input[this.pos]
470
- this.pos++
471
- }
472
- const keywords = ['si', 'sinon', 'sinonsi', 'pour', 'tantque', 'faire', 'retourner', 'essayer', 'saufsi', 'enfin', 'lancer', 'classe', 'herite', 'hérite', 'nouveau', 'soi', 'super', 'statique', 'asynchrone', 'attendre', 'generateur', 'générateur', 'produire', 'def', 'définir', 'fonction', 'const', 'soit', 'vrai', 'faux', 'nul', 'indefini', 'indéfini', 'de', 'dans', 'depuis', 'comme', 'cas', 'selon', 'defaut', 'défaut', 'continuer', 'sortir', 'debugger', 'debogueur', 'débogueur', 'avec', 'etiquette', 'étiquette']
473
- const keywordsEN = ['if', 'else', 'elseif', 'for', 'while', 'do', 'return', 'try', 'catch', 'finally', 'throw', 'class', 'extends', 'new', 'this', 'super', 'static', 'async', 'await', 'generator', 'yield', 'function', 'const', 'let', 'true', 'false', 'null', 'undefined', 'of', 'in', 'from', 'as', 'case', 'switch', 'default', 'continue', 'break', 'debugger', 'with', 'label']
474
- const keywordsES = ['si', 'sino', 'sinosi', 'para', 'mientras', 'hacer', 'retornar', 'intentar', 'capturar', 'finalmente', 'lanzar', 'clase', 'extiende', 'nuevo', 'esto', 'super', 'estatico', 'estático', 'asincrono', 'asíncrono', 'esperar', 'generador', 'producir', 'funcion', 'función', 'const', 'let', 'verdadero', 'falso', 'nulo', 'indefinido', 'de', 'en', 'desde', 'como', 'caso', 'segun', 'según', 'porDefecto', 'continuar', 'romper', 'depurador', 'con', 'etiqueta']
475
- const keywordsRU = ['если', 'иначе', 'иначеесли', 'для', 'пока', 'делать', 'вернуть', 'попробовать', 'поймать', 'наконец', 'бросить', 'класс', 'расширяет', 'новый', 'это', 'супер', 'статический', 'асинхронный', 'ждать', 'генератор', 'выдать', 'функция', 'конст', 'пусть', 'истина', 'ложь', 'ноль', 'неопределено', 'из', 'в', 'от', 'как', 'случай', 'переключатель', 'поумолчанию', 'продолжить', 'прервать', 'отладчик', 'с', 'метка']
476
- const keywordsZH = ['如果', '否则', '否则如果', '对于', '当', '做', '返回', '尝试', '捕获', '最终', '抛出', '类', '继承', '新建', '这', '超级', '静态', '异步', '等待', '生成器', '产出', '函数', '常量', '让', '真', '假', '空', '未定义', '的', '在', '从', '作为', '情况', '开关', '默认', '继续', '中断', '调试器', '与', '标签']
477
- const keywordsJA = ['もし', 'そうでなければ', 'でなければもし', 'ため', 'の間', 'する', '戻る', 'トライ', 'キャッチ', 'ファイナリー', 'スロー', 'クラス', '継承', '新規', 'これ', 'スーパー', 'スタティック', '非同期', '待つ', 'ジェネレーター', '譲る', '関数', '定数', 'レット', '真実', '偽', 'ヌル', '未定義', 'の', 'の中', 'から', 'として', 'ケース', 'スイッチ', 'デフォルト', '続ける', 'ブレーク', 'デバッガー', 'と共に', 'ラベル']
478
- if (keywords.includes(value) || keywordsEN.includes(value) || keywordsES.includes(value) || keywordsRU.includes(value) || keywordsZH.includes(value) || keywordsJA.includes(value)) {
479
- return { type: 'keyword', value }
480
- }
481
- return { type: 'identifier', value }
482
- }
483
-
484
- readOperator() {
485
- const ops3 = ['===', '!==', '>>>', '**=', '&&=', '||=', '??=', '...']
486
- const ops2 = ['==', '!=', '<=', '>=', '&&', '||', '??', '++', '--', '+=', '-=', '*=', '/=', '%=', '**', '=>', '->', '<<', '>>', '&=', '|=', '^=', '?.', '::']
487
-
488
- const three = this.input.substr(this.pos, 3)
489
- if (ops3.includes(three)) {
490
- this.pos += 3
491
- return { type: 'operator', value: three }
492
- }
493
-
494
- const two = this.input.substr(this.pos, 2)
495
- if (ops2.includes(two)) {
496
- this.pos += 2
497
- return { type: 'operator', value: two }
498
- }
499
-
500
- const char = this.input[this.pos]
501
- this.pos++
502
- return { type: 'operator', value: char }
503
- }
504
-
505
- parse(input) {
506
- this.tokenize(input)
507
- this.current = 0
508
- this.keywordMap = this.buildKeywordMap()
509
- const body = []
510
-
511
- while (this.current < this.tokens.length) {
512
- const stmt = this.parseStatement()
513
- if (stmt) body.push(stmt)
514
- }
515
-
516
- return new AST.Program(body)
517
- }
518
-
519
- peek(offset = 0) {
520
- return this.tokens[this.current + offset]
521
- }
522
-
523
- consume() {
524
- return this.tokens[this.current++]
525
- }
526
-
527
- expect(type, value = null) {
528
- const token = this.consume()
529
- if (!token || token.type !== type || (value !== null && token.value !== value)) {
530
- throw new Error(`Expected ${type}${value ? ` '${value}'` : ''}, got ${token ? `${token.type} '${token.value}'` : 'EOF'}`)
531
- }
532
- return token
533
- }
534
-
535
- match(type, value = null) {
536
- const token = this.peek()
537
- if (!token) return false
538
- if (token.type !== type) return false
539
- if (value !== null && token.value !== value) return false
540
- return true
541
- }
542
-
543
- parseStatement() {
544
- const token = this.peek()
545
- if (!token) return null
546
-
547
- if (token.type === 'keyword') {
548
- switch (token.value) {
549
- case 'charger':
550
- case 'require':
551
- return this.parseRequire()
552
- case 'importer':
553
- case 'import':
554
- return this.parseImport()
555
- case 'exporter':
556
- case 'exporterES':
557
- case 'export':
558
- return this.parseExport()
559
- case 'si':
560
- case 'if':
561
- return this.parseIfStatement()
562
- case 'pour':
563
- case 'for':
564
- return this.parseForStatement()
565
- case 'tantque':
566
- case 'while':
567
- return this.parseWhileStatement()
568
- case 'faire':
569
- case 'do':
570
- return this.parseDoWhileStatement()
571
- case 'selon':
572
- case 'switch':
573
- return this.parseSwitchStatement()
574
- case 'essayer':
575
- case 'try':
576
- return this.parseTryStatement()
577
- case 'lancer':
578
- case 'throw':
579
- return this.parseThrowStatement()
580
- case 'retourner':
581
- case 'return':
582
- return this.parseReturnStatement()
583
- case 'sortir':
584
- case 'break':
585
- this.consume()
586
- return new AST.BreakStatement()
587
- case 'continuer':
588
- case 'continue':
589
- this.consume()
590
- return new AST.ContinueStatement()
591
- case 'debugger':
592
- this.consume()
593
- return new AST.DebuggerStatement()
594
- case 'classe':
595
- case 'class':
596
- return this.parseClassDeclaration()
597
- case 'def':
598
- case 'fonction':
599
- case 'function':
600
- return this.parseFunctionDeclaration()
601
- case 'asynchrone':
602
- case 'async':
603
- return this.parseAsyncFunction()
604
- case 'generateur':
605
- case 'generator':
606
- return this.parseGeneratorFunction()
607
- case 'const':
608
- case 'soit':
609
- case 'let':
610
- return this.parseVariableDeclaration()
611
- }
612
- }
613
-
614
- if (token.type === 'identifier') {
615
- const nodeValue = this.keywordMap[token.value.toLowerCase()]
616
- if (nodeValue) {
617
- return this.parseNodeAPICall(nodeValue)
618
- }
619
-
620
- if (token.value === 'moduleExports' || token.value === 'exportarModulo') {
621
- return this.parseModuleExports()
622
- }
623
- }
624
-
625
- return this.parseExpressionStatement()
626
- }
627
-
628
- parseRequire() {
629
- this.consume()
630
- let variable = null
631
- let destructuring = null
632
-
633
- if (this.match('punctuation', '{')) {
634
- destructuring = this.parseObjectPattern()
635
- } else if (this.match('identifier')) {
636
- variable = this.consume().value
637
- }
638
-
639
- if (this.match('keyword', 'depuis') || this.match('keyword', 'from')) {
640
- this.consume()
641
- }
642
-
643
- const moduleToken = this.expect('string')
644
- const module = moduleToken.value
645
-
646
- if (destructuring) {
647
- return new AST.RequireDestructuring(module, destructuring.properties)
648
- }
649
-
650
- return new AST.RequireStatement(module, variable)
651
- }
652
-
653
- parseImport() {
654
- this.consume()
655
- const specifiers = []
656
- let source = null
657
-
658
- if (this.match('punctuation', '*')) {
659
- this.consume()
660
- this.expect('keyword', 'comme') || this.expect('keyword', 'as')
661
- const local = new AST.Identifier(this.expect('identifier').value)
662
- specifiers.push(new AST.ImportNamespaceSpecifier(local))
663
- } else if (this.match('punctuation', '{')) {
664
- this.consume()
665
- while (!this.match('punctuation', '}')) {
666
- const imported = new AST.Identifier(this.expect('identifier').value)
667
- let local = imported
668
- if (this.match('keyword', 'comme') || this.match('keyword', 'as')) {
669
- this.consume()
670
- local = new AST.Identifier(this.expect('identifier').value)
671
- }
672
- specifiers.push(new AST.ImportSpecifier(imported, local))
673
- if (this.match('punctuation', ',')) this.consume()
674
- }
675
- this.expect('punctuation', '}')
676
- } else if (this.match('identifier')) {
677
- const local = new AST.Identifier(this.consume().value)
678
- specifiers.push(new AST.ImportDefaultSpecifier(local))
679
-
680
- if (this.match('punctuation', ',')) {
681
- this.consume()
682
- if (this.match('punctuation', '{')) {
683
- this.consume()
684
- while (!this.match('punctuation', '}')) {
685
- const imported = new AST.Identifier(this.expect('identifier').value)
686
- let localNamed = imported
687
- if (this.match('keyword', 'comme') || this.match('keyword', 'as')) {
688
- this.consume()
689
- localNamed = new AST.Identifier(this.expect('identifier').value)
690
- }
691
- specifiers.push(new AST.ImportSpecifier(imported, localNamed))
692
- if (this.match('punctuation', ',')) this.consume()
693
- }
694
- this.expect('punctuation', '}')
695
- }
696
- }
697
- }
698
-
699
- if (this.match('keyword', 'depuis') || this.match('keyword', 'from')) {
700
- this.consume()
701
- }
702
-
703
- source = new AST.StringLiteral(this.expect('string').value)
704
-
705
- return new AST.ImportDeclaration(specifiers, source)
706
- }
707
-
708
- parseExport() {
709
- this.consume()
710
-
711
- if (this.match('keyword', 'defaut') || this.match('keyword', 'default') ||
712
- this.peek()?.value === 'exporterDefaut' || this.peek()?.value === 'exportDefault') {
713
- if (this.match('keyword')) this.consume()
714
- const declaration = this.parseExpression()
715
- return new AST.ExportDefaultDeclaration(declaration)
716
- }
717
-
718
- if (this.match('punctuation', '{')) {
719
- this.consume()
720
- const specifiers = []
721
- while (!this.match('punctuation', '}')) {
722
- const local = new AST.Identifier(this.expect('identifier').value)
723
- let exported = local
724
- if (this.match('keyword', 'comme') || this.match('keyword', 'as')) {
725
- this.consume()
726
- exported = new AST.Identifier(this.expect('identifier').value)
727
- }
728
- specifiers.push(new AST.ExportSpecifier(local, exported))
729
- if (this.match('punctuation', ',')) this.consume()
730
- }
731
- this.expect('punctuation', '}')
732
-
733
- let source = null
734
- if (this.match('keyword', 'depuis') || this.match('keyword', 'from')) {
735
- this.consume()
736
- source = new AST.StringLiteral(this.expect('string').value)
737
- }
738
- return new AST.ExportNamedDeclaration(null, specifiers, source)
739
- }
740
-
741
- if (this.match('keyword', 'classe') || this.match('keyword', 'class')) {
742
- const declaration = this.parseClassDeclaration()
743
- return new AST.ExportNamedDeclaration(declaration)
744
- }
745
-
746
- if (this.match('keyword', 'def') || this.match('keyword', 'fonction') || this.match('keyword', 'function')) {
747
- const declaration = this.parseFunctionDeclaration()
748
- return new AST.ExportNamedDeclaration(declaration)
749
- }
750
-
751
- if (this.match('keyword', 'const') || this.match('keyword', 'soit') || this.match('keyword', 'let')) {
752
- const declaration = this.parseVariableDeclaration()
753
- return new AST.ExportNamedDeclaration(declaration)
754
- }
755
-
756
- return new AST.ExportNamedDeclaration(this.parseExpression())
757
- }
758
-
759
- parseModuleExports() {
760
- this.consume()
761
- this.expect('operator', '=')
762
- const value = this.parseExpression()
763
- return new AST.ModuleExports(value)
764
- }
765
-
766
- parseNodeAPICall(nodeValue) {
767
- this.consume()
768
-
769
- if (this.match('punctuation', ':')) {
770
- this.consume()
771
- }
772
-
773
- const args = this.parseArguments()
774
-
775
- switch (nodeValue) {
776
- case 'fs.readFile':
777
- return new AST.FSReadFile(args[0], args[1], args[2])
778
- case 'fs.readFileSync':
779
- return new AST.FSReadFileSync(args[0], args[1])
780
- case 'fs.writeFile':
781
- return new AST.FSWriteFile(args[0], args[1], args[2], args[3])
782
- case 'fs.writeFileSync':
783
- return new AST.FSWriteFileSync(args[0], args[1], args[2])
784
- case 'fs.readdir':
785
- return new AST.FSReadDir(args[0], args[1], args[2])
786
- case 'fs.mkdir':
787
- return new AST.FSMkdir(args[0], args[1], args[2])
788
- case 'fs.unlink':
789
- return new AST.FSUnlink(args[0], args[1])
790
- case 'fs.rmdir':
791
- return new AST.FSRmdir(args[0], args[1], args[2])
792
- case 'fs.rm':
793
- return new AST.FSRm(args[0], args[1], args[2])
794
- case 'fs.rename':
795
- return new AST.FSRename(args[0], args[1], args[2])
796
- case 'fs.copyFile':
797
- return new AST.FSCopyFile(args[0], args[1], args[2], args[3])
798
- case 'fs.stat':
799
- return new AST.FSStat(args[0], args[1], args[2])
800
- case 'fs.existsSync':
801
- return new AST.FSExists(args[0])
802
- case 'fs.access':
803
- return new AST.FSAccess(args[0], args[1], args[2])
804
- case 'fs.appendFile':
805
- return new AST.FSAppendFile(args[0], args[1], args[2], args[3])
806
- case 'fs.createReadStream':
807
- return new AST.FSCreateReadStream(args[0], args[1])
808
- case 'fs.createWriteStream':
809
- return new AST.FSCreateWriteStream(args[0], args[1])
810
- case 'fs.watch':
811
- return new AST.FSWatch(args[0], args[1], args[2])
812
- case 'fs.watchFile':
813
- return new AST.FSWatchFile(args[0], args[1], args[2])
814
- case 'path.join':
815
- return new AST.PathJoin(args)
816
- case 'path.resolve':
817
- return new AST.PathResolve(args)
818
- case 'path.normalize':
819
- return new AST.PathNormalize(args[0])
820
- case 'path.dirname':
821
- return new AST.PathDirname(args[0])
822
- case 'path.basename':
823
- return new AST.PathBasename(args[0], args[1])
824
- case 'path.extname':
825
- return new AST.PathExtname(args[0])
826
- case 'path.parse':
827
- return new AST.PathParse(args[0])
828
- case 'path.format':
829
- return new AST.PathFormat(args[0])
830
- case 'path.isAbsolute':
831
- return new AST.PathIsAbsolute(args[0])
832
- case 'path.relative':
833
- return new AST.PathRelative(args[0], args[1])
834
- case 'http.createServer':
835
- return new AST.HttpCreateServer(args[0])
836
- case 'https.createServer':
837
- return new AST.HttpsCreateServer(args[0], args[1])
838
- case 'server.listen':
839
- return new AST.ServerListen(args[0], args[1], args[2], args[3])
840
- case 'server.close':
841
- return new AST.ServerClose(args[0])
842
- case 'http.request':
843
- return new AST.HttpRequest(args[0], args[1])
844
- case 'http.get':
845
- return new AST.HttpGet(args[0], args[1], args[2])
846
- case 'process.cwd':
847
- return new AST.ProcessCwd()
848
- case 'process.chdir':
849
- return new AST.ProcessChdir(args[0])
850
- case 'process.exit':
851
- return new AST.ProcessExit(args[0])
852
- case 'process.kill':
853
- return new AST.ProcessKill(args[0], args[1])
854
- case 'process.nextTick':
855
- return new AST.ProcessNextTick(args[0], args.slice(1))
856
- case 'process.memoryUsage':
857
- return new AST.ProcessMemoryUsage()
858
- case 'process.cpuUsage':
859
- return new AST.ProcessCpuUsage(args[0])
860
- case 'process.uptime':
861
- return new AST.ProcessUptime()
862
- case 'process.hrtime':
863
- return new AST.ProcessHrtime(args[0])
864
- case 'crypto.createHash':
865
- return new AST.CryptoCreateHash(args[0], args[1])
866
- case 'crypto.createHmac':
867
- return new AST.CryptoCreateHmac(args[0], args[1], args[2])
868
- case 'crypto.randomBytes':
869
- return new AST.CryptoRandomBytes(args[0], args[1])
870
- case 'crypto.randomUUID':
871
- return new AST.CryptoRandomUUID(args[0])
872
- case 'crypto.randomInt':
873
- return new AST.CryptoRandomInt(args[0], args[1], args[2])
874
- case 'crypto.pbkdf2':
875
- return new AST.CryptoPbkdf2(args[0], args[1], args[2], args[3], args[4], args[5])
876
- case 'crypto.pbkdf2Sync':
877
- return new AST.CryptoPbkdf2Sync(args[0], args[1], args[2], args[3], args[4])
878
- case 'crypto.scrypt':
879
- return new AST.CryptoScrypt(args[0], args[1], args[2], args[3], args[4])
880
- case 'crypto.scryptSync':
881
- return new AST.CryptoScryptSync(args[0], args[1], args[2], args[3])
882
- case 'Buffer.alloc':
883
- return new AST.BufferAlloc(args[0], args[1], args[2])
884
- case 'Buffer.allocUnsafe':
885
- return new AST.BufferAllocUnsafe(args[0])
886
- case 'Buffer.from':
887
- return new AST.BufferFrom(args[0], args[1], args[2])
888
- case 'Buffer.concat':
889
- return new AST.BufferConcat(args[0], args[1])
890
- case 'Buffer.compare':
891
- return new AST.BufferCompare(args[0], args[1])
892
- case 'Buffer.isBuffer':
893
- return new AST.BufferIsBuffer(args[0])
894
- case 'Buffer.byteLength':
895
- return new AST.BufferByteLength(args[0], args[1])
896
- case 'os.type':
897
- return new AST.OsType()
898
- case 'os.platform':
899
- return new AST.OsPlatform()
900
- case 'os.arch':
901
- return new AST.OsArch()
902
- case 'os.version':
903
- return new AST.OsVersion()
904
- case 'os.release':
905
- return new AST.OsRelease()
906
- case 'os.hostname':
907
- return new AST.OsHostname()
908
- case 'os.totalmem':
909
- return new AST.OsTotalmem()
910
- case 'os.freemem':
911
- return new AST.OsFreemem()
912
- case 'os.cpus':
913
- return new AST.OsCpus()
914
- case 'os.loadavg':
915
- return new AST.OsLoadavg()
916
- case 'os.userInfo':
917
- return new AST.OsUserInfo(args[0])
918
- case 'os.homedir':
919
- return new AST.OsHomedir()
920
- case 'os.tmpdir':
921
- return new AST.OsTmpdir()
922
- case 'os.networkInterfaces':
923
- return new AST.OsNetworkInterfaces()
924
- case 'os.uptime':
925
- return new AST.OsUptime()
926
- case 'child_process.spawn':
927
- return new AST.ChildProcessSpawn(args[0], args[1], args[2])
928
- case 'child_process.exec':
929
- return new AST.ChildProcessExec(args[0], args[1], args[2])
930
- case 'child_process.execFile':
931
- return new AST.ChildProcessExecFile(args[0], args[1], args[2], args[3])
932
- case 'child_process.fork':
933
- return new AST.ChildProcessFork(args[0], args[1], args[2])
934
- case 'child_process.spawnSync':
935
- return new AST.ChildProcessSpawnSync(args[0], args[1], args[2])
936
- case 'child_process.execSync':
937
- return new AST.ChildProcessExecSync(args[0], args[1])
938
- case 'child_process.execFileSync':
939
- return new AST.ChildProcessExecFileSync(args[0], args[1], args[2])
940
- case 'util.promisify':
941
- return new AST.UtilPromisify(args[0])
942
- case 'util.callbackify':
943
- return new AST.UtilCallbackify(args[0])
944
- case 'util.format':
945
- return new AST.UtilFormat(args[0], args.slice(1))
946
- case 'util.inspect':
947
- return new AST.UtilInspect(args[0], args[1])
948
- case 'util.deprecate':
949
- return new AST.UtilDeprecate(args[0], args[1], args[2])
950
- case 'dns.lookup':
951
- return new AST.DnsLookup(args[0], args[1], args[2])
952
- case 'dns.resolve':
953
- return new AST.DnsResolve(args[0], args[1], args[2])
954
- case 'dns.resolve4':
955
- return new AST.DnsResolve4(args[0], args[1], args[2])
956
- case 'dns.resolve6':
957
- return new AST.DnsResolve6(args[0], args[1], args[2])
958
- case 'dns.resolveMx':
959
- return new AST.DnsResolveMx(args[0], args[1])
960
- case 'dns.resolveTxt':
961
- return new AST.DnsResolveTxt(args[0], args[1])
962
- case 'dns.resolveNs':
963
- return new AST.DnsResolveNs(args[0], args[1])
964
- case 'dns.resolveCname':
965
- return new AST.DnsResolveCname(args[0], args[1])
966
- case 'dns.reverse':
967
- return new AST.DnsReverse(args[0], args[1])
968
- case 'setTimeout':
969
- return new AST.SetTimeout(args[0], args[1], args.slice(2))
970
- case 'clearTimeout':
971
- return new AST.ClearTimeout(args[0])
972
- case 'setInterval':
973
- return new AST.SetInterval(args[0], args[1], args.slice(2))
974
- case 'clearInterval':
975
- return new AST.ClearInterval(args[0])
976
- case 'setImmediate':
977
- return new AST.SetImmediate(args[0], args.slice(1))
978
- case 'clearImmediate':
979
- return new AST.ClearImmediate(args[0])
980
- case 'console.log':
981
- return new AST.ConsoleLog(args)
982
- case 'console.error':
983
- return new AST.ConsoleError(args)
984
- case 'console.warn':
985
- return new AST.ConsoleWarn(args)
986
- case 'console.info':
987
- return new AST.ConsoleInfo(args)
988
- case 'console.debug':
989
- return new AST.ConsoleDebug(args)
990
- case 'console.table':
991
- return new AST.ConsoleTable(args[0], args[1])
992
- case 'console.time':
993
- return new AST.ConsoleTime(args[0])
994
- case 'console.timeEnd':
995
- return new AST.ConsoleTimeEnd(args[0])
996
- case 'console.timeLog':
997
- return new AST.ConsoleTimeLog(args[0], args.slice(1))
998
- case 'console.trace':
999
- return new AST.ConsoleTrace(args)
1000
- case 'console.clear':
1001
- return new AST.ConsoleClear()
1002
- case 'console.count':
1003
- return new AST.ConsoleCount(args[0])
1004
- case 'console.countReset':
1005
- return new AST.ConsoleCountReset(args[0])
1006
- case 'console.group':
1007
- return new AST.ConsoleGroup(args)
1008
- case 'console.groupEnd':
1009
- return new AST.ConsoleGroupEnd()
1010
- case 'console.groupCollapsed':
1011
- return new AST.ConsoleGroupCollapsed(args)
1012
- case 'console.assert':
1013
- return new AST.ConsoleAssert(args[0], args.slice(1))
1014
- case 'console.dir':
1015
- return new AST.ConsoleDir(args[0], args[1])
1016
- case '__dirname':
1017
- return new AST.Dirname()
1018
- case '__filename':
1019
- return new AST.Filename()
1020
- default:
1021
- return new AST.CallExpression(
1022
- new AST.Identifier(nodeValue),
1023
- args
1024
- )
1025
- }
1026
- }
1027
-
1028
- parseArguments() {
1029
- const args = []
1030
-
1031
- if (this.match('punctuation', '(')) {
1032
- this.consume()
1033
- while (!this.match('punctuation', ')')) {
1034
- args.push(this.parseExpression())
1035
- if (this.match('punctuation', ',')) this.consume()
1036
- }
1037
- this.expect('punctuation', ')')
1038
- } else {
1039
- while (this.peek() && !this.isStatementEnd()) {
1040
- args.push(this.parseExpression())
1041
- if (this.match('punctuation', ',')) {
1042
- this.consume()
1043
- } else {
1044
- break
1045
- }
1046
- }
1047
- }
1048
-
1049
- return args
1050
- }
1051
-
1052
- isStatementEnd() {
1053
- const token = this.peek()
1054
- if (!token) return true
1055
- if (token.type === 'punctuation' && [';', '}', ')'].includes(token.value)) return true
1056
- if (token.type === 'keyword') return true
1057
- return false
1058
- }
1059
-
1060
- parseIfStatement() {
1061
- this.consume()
1062
-
1063
- if (this.match('punctuation', ':')) this.consume()
1064
-
1065
- const test = this.parseExpression()
1066
- const consequent = this.parseBlock()
1067
- let alternate = null
1068
-
1069
- if (this.match('keyword', 'sinonsi') || this.match('keyword', 'elseif')) {
1070
- alternate = this.parseIfStatement()
1071
- } else if (this.match('keyword', 'sinon') || this.match('keyword', 'else')) {
1072
- this.consume()
1073
- alternate = this.parseBlock()
1074
- }
1075
-
1076
- return new AST.IfStatement(test, consequent, alternate)
1077
- }
1078
-
1079
- parseForStatement() {
1080
- this.consume()
1081
-
1082
- if (this.match('punctuation', ':')) this.consume()
1083
-
1084
- const id = this.expect('identifier')
1085
- const left = new AST.Identifier(id.value)
1086
-
1087
- if (this.match('keyword', 'dans') || this.match('keyword', 'in')) {
1088
- this.consume()
1089
- const right = this.parseExpression()
1090
- const body = this.parseBlock()
1091
- return new AST.ForInStatement(left, right, body)
1092
- }
1093
-
1094
- if (this.match('keyword', 'de') || this.match('keyword', 'of')) {
1095
- this.consume()
1096
- const right = this.parseExpression()
1097
- const body = this.parseBlock()
1098
- return new AST.ForOfStatement(left, right, body)
1099
- }
1100
-
1101
- this.expect('operator', '=')
1102
- const initValue = this.parseExpression()
1103
- const init = new AST.VariableDeclaration('let', [
1104
- new AST.VariableDeclarator(left, initValue)
1105
- ])
1106
-
1107
- this.expect('punctuation', ';')
1108
- const test = this.parseExpression()
1109
- this.expect('punctuation', ';')
1110
- const update = this.parseExpression()
1111
- const body = this.parseBlock()
1112
-
1113
- return new AST.ForStatement(init, test, update, body)
1114
- }
1115
-
1116
- parseWhileStatement() {
1117
- this.consume()
1118
- if (this.match('punctuation', ':')) this.consume()
1119
- const test = this.parseExpression()
1120
- const body = this.parseBlock()
1121
- return new AST.WhileStatement(test, body)
1122
- }
1123
-
1124
- parseDoWhileStatement() {
1125
- this.consume()
1126
- const body = this.parseBlock()
1127
- this.expect('keyword', 'tantque') || this.expect('keyword', 'while')
1128
- if (this.match('punctuation', ':')) this.consume()
1129
- const test = this.parseExpression()
1130
- return new AST.DoWhileStatement(body, test)
1131
- }
1132
-
1133
- parseSwitchStatement() {
1134
- this.consume()
1135
- if (this.match('punctuation', ':')) this.consume()
1136
- const discriminant = this.parseExpression()
1137
- const cases = []
1138
-
1139
- while (this.match('keyword', 'cas') || this.match('keyword', 'case') ||
1140
- this.match('keyword', 'defaut') || this.match('keyword', 'default')) {
1141
- const isDefault = this.peek().value === 'defaut' || this.peek().value === 'default'
1142
- this.consume()
1143
-
1144
- let test = null
1145
- if (!isDefault) {
1146
- if (this.match('punctuation', ':')) this.consume()
1147
- test = this.parseExpression()
1148
- }
1149
-
1150
- if (this.match('punctuation', ':')) this.consume()
1151
-
1152
- const consequent = []
1153
- while (this.peek() &&
1154
- !this.match('keyword', 'cas') && !this.match('keyword', 'case') &&
1155
- !this.match('keyword', 'defaut') && !this.match('keyword', 'default') &&
1156
- !this.match('punctuation', '}')) {
1157
- const stmt = this.parseStatement()
1158
- if (stmt) consequent.push(stmt)
1159
- }
1160
-
1161
- cases.push(new AST.SwitchCase(test, consequent))
1162
- }
1163
-
1164
- return new AST.SwitchStatement(discriminant, cases)
1165
- }
1166
-
1167
- parseTryStatement() {
1168
- this.consume()
1169
- const block = this.parseBlock()
1170
- let handler = null
1171
- let finalizer = null
1172
-
1173
- if (this.match('keyword', 'saufsi') || this.match('keyword', 'catch')) {
1174
- this.consume()
1175
- let param = null
1176
- if (this.match('identifier')) {
1177
- param = new AST.Identifier(this.consume().value)
1178
- }
1179
- const handlerBody = this.parseBlock()
1180
- handler = new AST.CatchClause(param, handlerBody)
1181
- }
1182
-
1183
- if (this.match('keyword', 'enfin') || this.match('keyword', 'finally')) {
1184
- this.consume()
1185
- finalizer = this.parseBlock()
1186
- }
1187
-
1188
- return new AST.TryStatement(block, handler, finalizer)
1189
- }
1190
-
1191
- parseThrowStatement() {
1192
- this.consume()
1193
- if (this.match('punctuation', ':')) this.consume()
1194
- const argument = this.parseExpression()
1195
- return new AST.ThrowStatement(argument)
1196
- }
1197
-
1198
- parseReturnStatement() {
1199
- this.consume()
1200
- if (this.match('punctuation', ':')) this.consume()
1201
-
1202
- if (this.isStatementEnd()) {
1203
- return new AST.ReturnStatement(null)
1204
- }
1205
-
1206
- const argument = this.parseExpression()
1207
- return new AST.ReturnStatement(argument)
1208
- }
1209
-
1210
- parseClassDeclaration() {
1211
- this.consume()
1212
- const id = new AST.Identifier(this.expect('identifier').value)
1213
- let superClass = null
1214
-
1215
- if (this.match('keyword', 'herite') || this.match('keyword', 'extends')) {
1216
- this.consume()
1217
- superClass = new AST.Identifier(this.expect('identifier').value)
1218
- }
1219
-
1220
- const body = this.parseClassBody()
1221
- return new AST.ClassDeclaration(id, superClass, body)
1222
- }
1223
-
1224
- parseClassBody() {
1225
- const body = []
1226
-
1227
- while (this.peek() && !this.match('keyword') && !this.isStatementEnd()) {
1228
- const isStatic = this.match('keyword', 'statique') || this.match('keyword', 'static')
1229
- if (isStatic) this.consume()
1230
-
1231
- if (this.match('keyword', 'def') || this.match('keyword', 'fonction') || this.match('keyword', 'function')) {
1232
- this.consume()
1233
- const key = new AST.Identifier(this.expect('identifier').value)
1234
- const params = this.parseParams()
1235
- const methodBody = this.parseBlock()
1236
- const value = new AST.FunctionExpression(null, params, methodBody)
1237
-
1238
- let kind = 'method'
1239
- if (key.name === 'initialiser' || key.name === 'constructor') {
1240
- kind = 'constructor'
1241
- } else if (key.name.startsWith('obtenir') || key.name.startsWith('get')) {
1242
- kind = 'get'
1243
- } else if (key.name.startsWith('definir') || key.name.startsWith('set')) {
1244
- kind = 'set'
1245
- }
1246
-
1247
- body.push(new AST.MethodDefinition(key, value, kind, false, isStatic))
1248
- } else if (this.match('identifier')) {
1249
- const key = new AST.Identifier(this.consume().value)
1250
- let value = null
1251
- if (this.match('operator', '=')) {
1252
- this.consume()
1253
- value = this.parseExpression()
1254
- }
1255
- body.push(new AST.PropertyDefinition(key, value, false, isStatic))
1256
- } else {
1257
- break
1258
- }
1259
- }
1260
-
1261
- return new AST.ClassBody(body)
1262
- }
1263
-
1264
- parseFunctionDeclaration() {
1265
- this.consume()
1266
- const id = new AST.Identifier(this.expect('identifier').value)
1267
- const params = this.parseParams()
1268
- const body = this.parseBlock()
1269
- return new AST.FunctionDeclaration(id, params, body)
1270
- }
1271
-
1272
- parseAsyncFunction() {
1273
- this.consume()
1274
-
1275
- if (this.match('keyword', 'def') || this.match('keyword', 'fonction') || this.match('keyword', 'function')) {
1276
- this.consume()
1277
- }
1278
-
1279
- const id = new AST.Identifier(this.expect('identifier').value)
1280
- const params = this.parseParams()
1281
- const body = this.parseBlock()
1282
- return new AST.FunctionDeclaration(id, params, body, true)
1283
- }
1284
-
1285
- parseGeneratorFunction() {
1286
- this.consume()
1287
-
1288
- if (this.match('keyword', 'def') || this.match('keyword', 'fonction') || this.match('keyword', 'function')) {
1289
- this.consume()
1290
- }
1291
-
1292
- const id = new AST.Identifier(this.expect('identifier').value)
1293
- const params = this.parseParams()
1294
- const body = this.parseBlock()
1295
- return new AST.FunctionDeclaration(id, params, body, false, true)
1296
- }
1297
-
1298
- parseParams() {
1299
- const params = []
1300
-
1301
- if (this.match('punctuation', '(')) {
1302
- this.consume()
1303
- while (!this.match('punctuation', ')')) {
1304
- if (this.match('operator', '...')) {
1305
- this.consume()
1306
- const arg = new AST.Identifier(this.expect('identifier').value)
1307
- params.push(new AST.RestElement(arg))
1308
- } else {
1309
- const param = new AST.Identifier(this.expect('identifier').value)
1310
- if (this.match('operator', '=')) {
1311
- this.consume()
1312
- const defaultValue = this.parseExpression()
1313
- params.push(new AST.AssignmentPattern(param, defaultValue))
1314
- } else {
1315
- params.push(param)
1316
- }
1317
- }
1318
- if (this.match('punctuation', ',')) this.consume()
1319
- }
1320
- this.expect('punctuation', ')')
1321
- } else if (this.match('punctuation', ':')) {
1322
- this.consume()
1323
- while (this.match('identifier')) {
1324
- const param = new AST.Identifier(this.consume().value)
1325
- if (this.match('operator', '=')) {
1326
- this.consume()
1327
- const defaultValue = this.parseExpression()
1328
- params.push(new AST.AssignmentPattern(param, defaultValue))
1329
- } else {
1330
- params.push(param)
1331
- }
1332
- if (this.match('punctuation', ',')) this.consume()
1333
- }
1334
- }
1335
-
1336
- return params
1337
- }
1338
-
1339
- parseBlock() {
1340
- const body = []
1341
- const startIndent = this.getIndentLevel()
1342
-
1343
- while (this.peek()) {
1344
- const currentIndent = this.getIndentLevel()
1345
- if (currentIndent <= startIndent && body.length > 0) break
1346
-
1347
- const stmt = this.parseStatement()
1348
- if (stmt) body.push(stmt)
1349
- else break
1350
- }
1351
-
1352
- return new AST.BlockStatement(body)
1353
- }
1354
-
1355
- getIndentLevel() {
1356
- return 0
1357
- }
1358
-
1359
- parseVariableDeclaration() {
1360
- const kindToken = this.consume()
1361
- const kind = kindToken.value === 'const' ? 'const' : 'let'
1362
- const declarations = []
1363
-
1364
- do {
1365
- let id
1366
- if (this.match('punctuation', '{')) {
1367
- id = this.parseObjectPattern()
1368
- } else if (this.match('punctuation', '[')) {
1369
- id = this.parseArrayPattern()
1370
- } else {
1371
- id = new AST.Identifier(this.expect('identifier').value)
1372
- }
1373
-
1374
- let init = null
1375
- if (this.match('operator', '=')) {
1376
- this.consume()
1377
- init = this.parseExpression()
1378
- }
1379
-
1380
- declarations.push(new AST.VariableDeclarator(id, init))
1381
- } while (this.match('punctuation', ',') && this.consume())
1382
-
1383
- return new AST.VariableDeclaration(kind, declarations)
1384
- }
1385
-
1386
- parseObjectPattern() {
1387
- this.expect('punctuation', '{')
1388
- const properties = []
1389
-
1390
- while (!this.match('punctuation', '}')) {
1391
- const key = new AST.Identifier(this.expect('identifier').value)
1392
- let value = key
1393
-
1394
- if (this.match('punctuation', ':')) {
1395
- this.consume()
1396
- value = new AST.Identifier(this.expect('identifier').value)
1397
- }
1398
-
1399
- let defaultValue = null
1400
- if (this.match('operator', '=')) {
1401
- this.consume()
1402
- defaultValue = this.parseExpression()
1403
- value = new AST.AssignmentPattern(value, defaultValue)
1404
- }
1405
-
1406
- properties.push(new AST.Property(key, value, key === value))
1407
- if (this.match('punctuation', ',')) this.consume()
1408
- }
1409
-
1410
- this.expect('punctuation', '}')
1411
- return new AST.ObjectPattern(properties)
1412
- }
1413
-
1414
- parseArrayPattern() {
1415
- this.expect('punctuation', '[')
1416
- const elements = []
1417
-
1418
- while (!this.match('punctuation', ']')) {
1419
- if (this.match('punctuation', ',')) {
1420
- elements.push(null)
1421
- this.consume()
1422
- continue
1423
- }
1424
-
1425
- if (this.match('operator', '...')) {
1426
- this.consume()
1427
- const arg = new AST.Identifier(this.expect('identifier').value)
1428
- elements.push(new AST.RestElement(arg))
1429
- } else {
1430
- let element = new AST.Identifier(this.expect('identifier').value)
1431
- if (this.match('operator', '=')) {
1432
- this.consume()
1433
- const defaultValue = this.parseExpression()
1434
- element = new AST.AssignmentPattern(element, defaultValue)
1435
- }
1436
- elements.push(element)
1437
- }
1438
-
1439
- if (this.match('punctuation', ',')) this.consume()
1440
- }
1441
-
1442
- this.expect('punctuation', ']')
1443
- return new AST.ArrayPattern(elements)
1444
- }
1445
-
1446
- parseExpressionStatement() {
1447
- const expr = this.parseExpression()
1448
- return new AST.ExpressionStatement(expr)
1449
- }
1450
-
1451
- parseExpression() {
1452
- return this.parseAssignment()
1453
- }
1454
-
1455
- parseAssignment() {
1456
- const left = this.parseTernary()
1457
-
1458
- if (this.match('operator', '=') || this.match('operator', '+=') ||
1459
- this.match('operator', '-=') || this.match('operator', '*=') ||
1460
- this.match('operator', '/=') || this.match('operator', '%=') ||
1461
- this.match('operator', '**=') || this.match('operator', '&&=') ||
1462
- this.match('operator', '||=') || this.match('operator', '??=')) {
1463
- const op = this.consume().value
1464
- const right = this.parseAssignment()
1465
- return new AST.AssignmentExpression(op, left, right)
1466
- }
1467
-
1468
- return left
1469
- }
1470
-
1471
- parseTernary() {
1472
- const test = this.parseLogicalOr()
1473
-
1474
- if (this.match('operator', '?')) {
1475
- this.consume()
1476
- const consequent = this.parseExpression()
1477
- this.expect('punctuation', ':')
1478
- const alternate = this.parseExpression()
1479
- return new AST.ConditionalExpression(test, consequent, alternate)
1480
- }
1481
-
1482
- return test
1483
- }
1484
-
1485
- parseLogicalOr() {
1486
- let left = this.parseLogicalAnd()
1487
-
1488
- while (this.match('operator', '||') || this.match('operator', '??')) {
1489
- const op = this.consume().value
1490
- const right = this.parseLogicalAnd()
1491
- left = new AST.LogicalExpression(op, left, right)
1492
- }
1493
-
1494
- return left
1495
- }
1496
-
1497
- parseLogicalAnd() {
1498
- let left = this.parseBitwiseOr()
1499
-
1500
- while (this.match('operator', '&&')) {
1501
- this.consume()
1502
- const right = this.parseBitwiseOr()
1503
- left = new AST.LogicalExpression('&&', left, right)
1504
- }
1505
-
1506
- return left
1507
- }
1508
-
1509
- parseBitwiseOr() {
1510
- let left = this.parseBitwiseXor()
1511
-
1512
- while (this.match('operator', '|') && !this.match('operator', '||')) {
1513
- this.consume()
1514
- const right = this.parseBitwiseXor()
1515
- left = new AST.BinaryExpression('|', left, right)
1516
- }
1517
-
1518
- return left
1519
- }
1520
-
1521
- parseBitwiseXor() {
1522
- let left = this.parseBitwiseAnd()
1523
-
1524
- while (this.match('operator', '^')) {
1525
- this.consume()
1526
- const right = this.parseBitwiseAnd()
1527
- left = new AST.BinaryExpression('^', left, right)
1528
- }
1529
-
1530
- return left
1531
- }
1532
-
1533
- parseBitwiseAnd() {
1534
- let left = this.parseEquality()
1535
-
1536
- while (this.match('operator', '&') && !this.match('operator', '&&')) {
1537
- this.consume()
1538
- const right = this.parseEquality()
1539
- left = new AST.BinaryExpression('&', left, right)
1540
- }
1541
-
1542
- return left
1543
- }
1544
-
1545
- parseEquality() {
1546
- let left = this.parseComparison()
1547
-
1548
- while (this.match('operator', '==') || this.match('operator', '!=') ||
1549
- this.match('operator', '===') || this.match('operator', '!==')) {
1550
- const op = this.consume().value
1551
- const right = this.parseComparison()
1552
- left = new AST.BinaryExpression(op, left, right)
1553
- }
1554
-
1555
- return left
1556
- }
1557
-
1558
- parseComparison() {
1559
- let left = this.parseShift()
1560
-
1561
- while (this.match('operator', '<') || this.match('operator', '>') ||
1562
- this.match('operator', '<=') || this.match('operator', '>=')) {
1563
- const op = this.consume().value
1564
- const right = this.parseShift()
1565
- left = new AST.BinaryExpression(op, left, right)
1566
- }
1567
-
1568
- return left
1569
- }
1570
-
1571
- parseShift() {
1572
- let left = this.parseAdditive()
1573
-
1574
- while (this.match('operator', '<<') || this.match('operator', '>>') ||
1575
- this.match('operator', '>>>')) {
1576
- const op = this.consume().value
1577
- const right = this.parseAdditive()
1578
- left = new AST.BinaryExpression(op, left, right)
1579
- }
1580
-
1581
- return left
1582
- }
1583
-
1584
- parseAdditive() {
1585
- let left = this.parseMultiplicative()
1586
-
1587
- while (this.match('operator', '+') || this.match('operator', '-')) {
1588
- const op = this.consume().value
1589
- const right = this.parseMultiplicative()
1590
- left = new AST.BinaryExpression(op, left, right)
1591
- }
1592
-
1593
- return left
1594
- }
1595
-
1596
- parseMultiplicative() {
1597
- let left = this.parseExponentiation()
1598
-
1599
- while (this.match('operator', '*') || this.match('operator', '/') ||
1600
- this.match('operator', '%')) {
1601
- const op = this.consume().value
1602
- const right = this.parseExponentiation()
1603
- left = new AST.BinaryExpression(op, left, right)
1604
- }
1605
-
1606
- return left
1607
- }
1608
-
1609
- parseExponentiation() {
1610
- let left = this.parseUnary()
1611
-
1612
- if (this.match('operator', '**')) {
1613
- this.consume()
1614
- const right = this.parseExponentiation()
1615
- left = new AST.BinaryExpression('**', left, right)
1616
- }
1617
-
1618
- return left
1619
- }
1620
-
1621
- parseUnary() {
1622
- if (this.match('operator', '!') || this.match('operator', '-') ||
1623
- this.match('operator', '+') || this.match('operator', '~') ||
1624
- this.match('operator', '...')) {
1625
- const op = this.consume().value
1626
- if (op === '...') {
1627
- const argument = this.parseUnary()
1628
- return new AST.SpreadElement(argument)
1629
- }
1630
- const argument = this.parseUnary()
1631
- return new AST.UnaryExpression(op, argument)
1632
- }
1633
-
1634
- if (this.match('keyword', 'attendre') || this.match('keyword', 'await')) {
1635
- this.consume()
1636
- const argument = this.parseUnary()
1637
- return new AST.AwaitExpression(argument)
1638
- }
1639
-
1640
- if (this.match('keyword', 'produire') || this.match('keyword', 'yield')) {
1641
- this.consume()
1642
- let delegate = false
1643
- if (this.match('operator', '*')) {
1644
- this.consume()
1645
- delegate = true
1646
- }
1647
- const argument = this.parseUnary()
1648
- return new AST.YieldExpression(argument, delegate)
1649
- }
1650
-
1651
- if (this.match('operator', '++') || this.match('operator', '--')) {
1652
- const op = this.consume().value
1653
- const argument = this.parseUnary()
1654
- return new AST.UpdateExpression(op, argument, true)
1655
- }
1656
-
1657
- return this.parseUpdate()
1658
- }
1659
-
1660
- parseUpdate() {
1661
- const argument = this.parseCall()
1662
-
1663
- if (this.match('operator', '++') || this.match('operator', '--')) {
1664
- const op = this.consume().value
1665
- return new AST.UpdateExpression(op, argument, false)
1666
- }
1667
-
1668
- return argument
1669
- }
1670
-
1671
- parseCall() {
1672
- let callee = this.parseMember()
1673
-
1674
- while (true) {
1675
- if (this.match('punctuation', '(')) {
1676
- this.consume()
1677
- const args = []
1678
- while (!this.match('punctuation', ')')) {
1679
- args.push(this.parseExpression())
1680
- if (this.match('punctuation', ',')) this.consume()
1681
- }
1682
- this.expect('punctuation', ')')
1683
- callee = new AST.CallExpression(callee, args)
1684
- } else if (this.match('punctuation', ':') &&
1685
- this.peek(1) &&
1686
- (this.peek(1).type === 'string' || this.peek(1).type === 'number' || this.peek(1).type === 'identifier')) {
1687
- this.consume()
1688
- const args = this.parseArguments()
1689
- callee = new AST.CallExpression(callee, args)
1690
- } else if (this.match('operator', '?.')) {
1691
- this.consume()
1692
- if (this.match('punctuation', '(')) {
1693
- this.consume()
1694
- const args = []
1695
- while (!this.match('punctuation', ')')) {
1696
- args.push(this.parseExpression())
1697
- if (this.match('punctuation', ',')) this.consume()
1698
- }
1699
- this.expect('punctuation', ')')
1700
- callee = new AST.CallExpression(callee, args, true)
1701
- } else {
1702
- const property = new AST.Identifier(this.expect('identifier').value)
1703
- callee = new AST.MemberExpression(callee, property, false, true)
1704
- }
1705
- } else {
1706
- break
1707
- }
1708
- }
1709
-
1710
- return callee
1711
- }
1712
-
1713
- parseMember() {
1714
- let object = this.parsePrimary()
1715
-
1716
- while (true) {
1717
- if (this.match('punctuation', '.')) {
1718
- this.consume()
1719
- const property = new AST.Identifier(this.expect('identifier').value)
1720
- object = new AST.MemberExpression(object, property)
1721
- } else if (this.match('punctuation', '[')) {
1722
- this.consume()
1723
- const property = this.parseExpression()
1724
- this.expect('punctuation', ']')
1725
- object = new AST.MemberExpression(object, property, true)
1726
- } else {
1727
- break
1728
- }
1729
- }
1730
-
1731
- return object
1732
- }
1733
-
1734
- parsePrimary() {
1735
- const token = this.peek()
1736
- if (!token) return null
1737
-
1738
- if (token.type === 'number') {
1739
- this.consume()
1740
- return new AST.NumericLiteral(token.value, token.raw)
1741
- }
1742
-
1743
- if (token.type === 'bigint') {
1744
- this.consume()
1745
- return new AST.BigIntLiteral(token.value, token.raw)
1746
- }
1747
-
1748
- if (token.type === 'string') {
1749
- this.consume()
1750
- return new AST.StringLiteral(token.value, token.raw)
1751
- }
1752
-
1753
- if (token.type === 'template') {
1754
- return this.parseTemplateLiteral()
1755
- }
1756
-
1757
- if (token.type === 'keyword') {
1758
- if (token.value === 'vrai' || token.value === 'true') {
1759
- this.consume()
1760
- return new AST.BooleanLiteral(true)
1761
- }
1762
- if (token.value === 'faux' || token.value === 'false') {
1763
- this.consume()
1764
- return new AST.BooleanLiteral(false)
1765
- }
1766
- if (token.value === 'nul' || token.value === 'null') {
1767
- this.consume()
1768
- return new AST.NullLiteral()
1769
- }
1770
- if (token.value === 'indefini' || token.value === 'undefined') {
1771
- this.consume()
1772
- return new AST.UndefinedLiteral()
1773
- }
1774
- if (token.value === 'soi' || token.value === 'this') {
1775
- this.consume()
1776
- return new AST.ThisExpression()
1777
- }
1778
- if (token.value === 'super') {
1779
- this.consume()
1780
- return new AST.Super()
1781
- }
1782
- if (token.value === 'nouveau' || token.value === 'new') {
1783
- return this.parseNewExpression()
1784
- }
1785
- }
1786
-
1787
- if (token.type === 'identifier') {
1788
- const nodeValue = this.keywordMap[token.value.toLowerCase()]
1789
- if (nodeValue) {
1790
- return this.parseNodeAPICall(nodeValue)
1791
- }
1792
- this.consume()
1793
- return new AST.Identifier(token.value)
1794
- }
1795
-
1796
- if (this.match('punctuation', '(')) {
1797
- this.consume()
1798
-
1799
- if (this.match('punctuation', ')') || this.isArrowParams()) {
1800
- return this.parseArrowFunction()
1801
- }
1802
-
1803
- const expr = this.parseExpression()
1804
- this.expect('punctuation', ')')
1805
- return expr
1806
- }
1807
-
1808
- if (this.match('punctuation', '[')) {
1809
- return this.parseArrayExpression()
1810
- }
1811
-
1812
- if (this.match('punctuation', '{')) {
1813
- return this.parseObjectExpression()
1814
- }
1815
-
1816
- if (this.match('operator', '->') || this.match('operator', '=>')) {
1817
- return this.parseArrowFunction()
1818
- }
1819
-
1820
- this.consume()
1821
- return new AST.Identifier(token.value || '')
1822
- }
1823
-
1824
- isArrowParams() {
1825
- let depth = 1
1826
- let pos = this.current
1827
- while (depth > 0 && pos < this.tokens.length) {
1828
- const t = this.tokens[pos]
1829
- if (t.value === '(') depth++
1830
- if (t.value === ')') depth--
1831
- pos++
1832
- }
1833
- const next = this.tokens[pos]
1834
- return next && (next.value === '->' || next.value === '=>')
1835
- }
1836
-
1837
- parseArrowFunction() {
1838
- const params = []
1839
-
1840
- if (this.match('punctuation', '(')) {
1841
- while (!this.match('punctuation', ')')) {
1842
- if (this.match('operator', '...')) {
1843
- this.consume()
1844
- const arg = new AST.Identifier(this.expect('identifier').value)
1845
- params.push(new AST.RestElement(arg))
1846
- } else if (this.match('identifier')) {
1847
- const param = new AST.Identifier(this.consume().value)
1848
- if (this.match('operator', '=')) {
1849
- this.consume()
1850
- const defaultValue = this.parseExpression()
1851
- params.push(new AST.AssignmentPattern(param, defaultValue))
1852
- } else {
1853
- params.push(param)
1854
- }
1855
- }
1856
- if (this.match('punctuation', ',')) this.consume()
1857
- }
1858
- if (this.match('punctuation', ')')) this.consume()
1859
- }
1860
-
1861
- if (this.match('operator', '->') || this.match('operator', '=>')) {
1862
- this.consume()
1863
- }
1864
-
1865
- let body
1866
- let expression = false
1867
-
1868
- if (this.match('punctuation', '{')) {
1869
- body = this.parseBlock()
1870
- } else {
1871
- body = this.parseExpression()
1872
- expression = true
1873
- }
1874
-
1875
- return new AST.ArrowFunctionExpression(params, body, false, expression)
1876
- }
1877
-
1878
- parseNewExpression() {
1879
- this.consume()
1880
- const callee = this.parseMember()
1881
- let args = []
1882
-
1883
- if (this.match('punctuation', '(')) {
1884
- this.consume()
1885
- while (!this.match('punctuation', ')')) {
1886
- args.push(this.parseExpression())
1887
- if (this.match('punctuation', ',')) this.consume()
1888
- }
1889
- this.expect('punctuation', ')')
1890
- } else if (this.match('punctuation', ':')) {
1891
- this.consume()
1892
- args = this.parseArguments()
1893
- }
1894
-
1895
- return new AST.NewExpression(callee, args)
1896
- }
1897
-
1898
- parseArrayExpression() {
1899
- this.expect('punctuation', '[')
1900
- const elements = []
1901
-
1902
- while (!this.match('punctuation', ']')) {
1903
- if (this.match('punctuation', ',')) {
1904
- elements.push(null)
1905
- this.consume()
1906
- continue
1907
- }
1908
- elements.push(this.parseExpression())
1909
- if (this.match('punctuation', ',')) this.consume()
1910
- }
1911
-
1912
- this.expect('punctuation', ']')
1913
- return new AST.ArrayExpression(elements)
1914
- }
1915
-
1916
- parseObjectExpression() {
1917
- this.expect('punctuation', '{')
1918
- const properties = []
1919
-
1920
- while (!this.match('punctuation', '}')) {
1921
- if (this.match('operator', '...')) {
1922
- this.consume()
1923
- const arg = this.parseExpression()
1924
- properties.push(new AST.SpreadElement(arg))
1925
- } else {
1926
- let computed = false
1927
- let key
1928
-
1929
- if (this.match('punctuation', '[')) {
1930
- computed = true
1931
- this.consume()
1932
- key = this.parseExpression()
1933
- this.expect('punctuation', ']')
1934
- } else if (this.match('string')) {
1935
- key = new AST.StringLiteral(this.consume().value)
1936
- } else if (this.match('number')) {
1937
- key = new AST.NumericLiteral(this.consume().value)
1938
- } else {
1939
- key = new AST.Identifier(this.expect('identifier').value)
1940
- }
1941
-
1942
- let value = key
1943
- let shorthand = true
1944
-
1945
- if (this.match('punctuation', ':')) {
1946
- this.consume()
1947
- value = this.parseExpression()
1948
- shorthand = false
1949
- } else if (this.match('punctuation', '(') || this.match('operator', '->') || this.match('operator', '=>')) {
1950
- const params = this.parseParams()
1951
- if (this.match('operator', '->') || this.match('operator', '=>')) this.consume()
1952
- const body = this.parseBlock()
1953
- value = new AST.FunctionExpression(null, params, body)
1954
- shorthand = false
1955
- }
1956
-
1957
- properties.push(new AST.Property(key, value, shorthand, computed))
1958
- }
1959
-
1960
- if (this.match('punctuation', ',')) this.consume()
1961
- }
1962
-
1963
- this.expect('punctuation', '}')
1964
- return new AST.ObjectExpression(properties)
1965
- }
1966
-
1967
- parseTemplateLiteral() {
1968
- const token = this.consume()
1969
- const quasis = []
1970
- const expressions = []
1971
-
1972
- if (token.expressions && token.expressions.length > 0) {
1973
- let lastEnd = 0
1974
- token.expressions.forEach((expr, i) => {
1975
- quasis.push(new AST.TemplateElement({ raw: expr.quasi, cooked: expr.quasi }, false))
1976
- const exprParser = new NodeParser(this.i18n)
1977
- const parsed = exprParser.parse(expr.expression)
1978
- if (parsed.body.length > 0 && parsed.body[0].expression) {
1979
- expressions.push(parsed.body[0].expression)
1980
- }
1981
- })
1982
- quasis.push(new AST.TemplateElement({ raw: token.value, cooked: token.value }, true))
1983
- } else {
1984
- quasis.push(new AST.TemplateElement({ raw: token.value, cooked: token.value }, true))
1985
- }
1986
-
1987
- return new AST.TemplateLiteral(quasis, expressions)
1988
- }
1989
- }
1990
-
1991
- class NodeCodeGenerator {
1992
- constructor() {
1993
- this.indent = 0
1994
- this.indentStr = ' '
1995
- }
1996
-
1997
- generate(node) {
1998
- if (!node) return ''
1999
- const method = `generate${node.type}`
2000
- if (this[method]) {
2001
- return this[method](node)
2002
- }
2003
- return ''
2004
- }
2005
-
2006
- getIndent() {
2007
- return this.indentStr.repeat(this.indent)
2008
- }
2009
-
2010
- generateProgram(node) {
2011
- return node.body.map(stmt => this.generate(stmt)).join('\n')
2012
- }
2013
-
2014
- generateRequireStatement(node) {
2015
- if (node.variable) {
2016
- return `const ${node.variable} = require("${node.module}");`
2017
- }
2018
- return `require("${node.module}");`
2019
- }
2020
-
2021
- generateRequireDestructuring(node) {
2022
- const props = node.properties.map(p => {
2023
- if (p.shorthand) return p.key.name
2024
- return `${p.key.name}: ${this.generate(p.value)}`
2025
- }).join(', ')
2026
- return `const { ${props} } = require("${node.module}");`
2027
- }
2028
-
2029
- generateImportDeclaration(node) {
2030
- const specifiers = node.specifiers.map(s => this.generate(s)).join(', ')
2031
- return `import ${specifiers} from ${this.generate(node.source)};`
2032
- }
2033
-
2034
- generateImportDefaultSpecifier(node) {
2035
- return this.generate(node.local)
2036
- }
2037
-
2038
- generateImportSpecifier(node) {
2039
- if (node.imported.name === node.local.name) {
2040
- return node.imported.name
2041
- }
2042
- return `${node.imported.name} as ${node.local.name}`
2043
- }
2044
-
2045
- generateImportNamespaceSpecifier(node) {
2046
- return `* as ${this.generate(node.local)}`
2047
- }
2048
-
2049
- generateExportNamedDeclaration(node) {
2050
- if (node.declaration) {
2051
- return `export ${this.generate(node.declaration)}`
2052
- }
2053
- const specifiers = node.specifiers.map(s => this.generate(s)).join(', ')
2054
- let code = `export { ${specifiers} }`
2055
- if (node.source) {
2056
- code += ` from ${this.generate(node.source)}`
2057
- }
2058
- return code + ';'
2059
- }
2060
-
2061
- generateExportDefaultDeclaration(node) {
2062
- return `export default ${this.generate(node.declaration)};`
2063
- }
2064
-
2065
- generateExportSpecifier(node) {
2066
- if (node.local.name === node.exported.name) {
2067
- return node.local.name
2068
- }
2069
- return `${node.local.name} as ${node.exported.name}`
2070
- }
2071
-
2072
- generateModuleExports(node) {
2073
- return `module.exports = ${this.generate(node.value)};`
2074
- }
2075
-
2076
- generateVariableDeclaration(node) {
2077
- const declarations = node.declarations.map(d => this.generate(d)).join(', ')
2078
- return `${node.kind} ${declarations};`
2079
- }
2080
-
2081
- generateVariableDeclarator(node) {
2082
- if (node.init) {
2083
- return `${this.generate(node.id)} = ${this.generate(node.init)}`
2084
- }
2085
- return this.generate(node.id)
2086
- }
2087
-
2088
- generateFunctionDeclaration(node) {
2089
- const async = node.async ? 'async ' : ''
2090
- const generator = node.generator ? '*' : ''
2091
- const params = node.params.map(p => this.generate(p)).join(', ')
2092
- const body = this.generate(node.body)
2093
- return `${async}function${generator} ${this.generate(node.id)}(${params}) ${body}`
2094
- }
2095
-
2096
- generateFunctionExpression(node) {
2097
- const async = node.async ? 'async ' : ''
2098
- const generator = node.generator ? '*' : ''
2099
- const id = node.id ? ` ${this.generate(node.id)}` : ''
2100
- const params = node.params.map(p => this.generate(p)).join(', ')
2101
- const body = this.generate(node.body)
2102
- return `${async}function${generator}${id}(${params}) ${body}`
2103
- }
2104
-
2105
- generateArrowFunctionExpression(node) {
2106
- const async = node.async ? 'async ' : ''
2107
- const params = node.params.length === 1 && node.params[0].type === 'Identifier'
2108
- ? this.generate(node.params[0])
2109
- : `(${node.params.map(p => this.generate(p)).join(', ')})`
2110
- const body = node.expression ? this.generate(node.body) : this.generate(node.body)
2111
- return `${async}${params} => ${body}`
2112
- }
2113
-
2114
- generateBlockStatement(node) {
2115
- this.indent++
2116
- const body = node.body.map(stmt => this.getIndent() + this.generate(stmt)).join('\n')
2117
- this.indent--
2118
- return `{\n${body}\n${this.getIndent()}}`
2119
- }
2120
-
2121
- generateReturnStatement(node) {
2122
- if (node.argument) {
2123
- return `return ${this.generate(node.argument)};`
2124
- }
2125
- return 'return;'
2126
- }
2127
-
2128
- generateIfStatement(node) {
2129
- let code = `if (${this.generate(node.test)}) ${this.generate(node.consequent)}`
2130
- if (node.alternate) {
2131
- if (node.alternate.type === 'IfStatement') {
2132
- code += ` else ${this.generate(node.alternate)}`
2133
- } else {
2134
- code += ` else ${this.generate(node.alternate)}`
2135
- }
2136
- }
2137
- return code
2138
- }
2139
-
2140
- generateForStatement(node) {
2141
- const init = node.init ? this.generate(node.init).replace(/;$/, '') : ''
2142
- const test = node.test ? this.generate(node.test) : ''
2143
- const update = node.update ? this.generate(node.update) : ''
2144
- return `for (${init}; ${test}; ${update}) ${this.generate(node.body)}`
2145
- }
2146
-
2147
- generateForInStatement(node) {
2148
- return `for (${this.generate(node.left)} in ${this.generate(node.right)}) ${this.generate(node.body)}`
2149
- }
2150
-
2151
- generateForOfStatement(node) {
2152
- const await_ = node.await ? 'await ' : ''
2153
- return `for ${await_}(${this.generate(node.left)} of ${this.generate(node.right)}) ${this.generate(node.body)}`
2154
- }
2155
-
2156
- generateWhileStatement(node) {
2157
- return `while (${this.generate(node.test)}) ${this.generate(node.body)}`
2158
- }
2159
-
2160
- generateDoWhileStatement(node) {
2161
- return `do ${this.generate(node.body)} while (${this.generate(node.test)});`
2162
- }
2163
-
2164
- generateSwitchStatement(node) {
2165
- this.indent++
2166
- const cases = node.cases.map(c => this.getIndent() + this.generate(c)).join('\n')
2167
- this.indent--
2168
- return `switch (${this.generate(node.discriminant)}) {\n${cases}\n${this.getIndent()}}`
2169
- }
2170
-
2171
- generateSwitchCase(node) {
2172
- const test = node.test ? `case ${this.generate(node.test)}:` : 'default:'
2173
- this.indent++
2174
- const consequent = node.consequent.map(s => this.getIndent() + this.generate(s)).join('\n')
2175
- this.indent--
2176
- return `${test}\n${consequent}`
2177
- }
2178
-
2179
- generateTryStatement(node) {
2180
- let code = `try ${this.generate(node.block)}`
2181
- if (node.handler) {
2182
- code += ` ${this.generate(node.handler)}`
2183
- }
2184
- if (node.finalizer) {
2185
- code += ` finally ${this.generate(node.finalizer)}`
2186
- }
2187
- return code
2188
- }
2189
-
2190
- generateCatchClause(node) {
2191
- const param = node.param ? `(${this.generate(node.param)})` : ''
2192
- return `catch ${param} ${this.generate(node.body)}`
2193
- }
2194
-
2195
- generateThrowStatement(node) {
2196
- return `throw ${this.generate(node.argument)};`
2197
- }
2198
-
2199
- generateBreakStatement(node) {
2200
- return node.label ? `break ${this.generate(node.label)};` : 'break;'
2201
- }
2202
-
2203
- generateContinueStatement(node) {
2204
- return node.label ? `continue ${this.generate(node.label)};` : 'continue;'
2205
- }
2206
-
2207
- generateDebuggerStatement() {
2208
- return 'debugger;'
2209
- }
2210
-
2211
- generateClassDeclaration(node) {
2212
- const extend = node.superClass ? ` extends ${this.generate(node.superClass)}` : ''
2213
- return `class ${this.generate(node.id)}${extend} ${this.generate(node.body)}`
2214
- }
2215
-
2216
- generateClassBody(node) {
2217
- this.indent++
2218
- const body = node.body.map(m => this.getIndent() + this.generate(m)).join('\n\n')
2219
- this.indent--
2220
- return `{\n${body}\n${this.getIndent()}}`
2221
- }
2222
-
2223
- generateMethodDefinition(node) {
2224
- const static_ = node.static ? 'static ' : ''
2225
- const kind = node.kind === 'get' ? 'get ' : node.kind === 'set' ? 'set ' : ''
2226
- const key = this.generate(node.key)
2227
- const value = this.generate(node.value)
2228
- const params = node.value.params.map(p => this.generate(p)).join(', ')
2229
- const body = this.generate(node.value.body)
2230
-
2231
- if (node.kind === 'constructor') {
2232
- return `constructor(${params}) ${body}`
2233
- }
2234
-
2235
- return `${static_}${kind}${key}(${params}) ${body}`
2236
- }
2237
-
2238
- generatePropertyDefinition(node) {
2239
- const static_ = node.static ? 'static ' : ''
2240
- const key = this.generate(node.key)
2241
- if (node.value) {
2242
- return `${static_}${key} = ${this.generate(node.value)};`
2243
- }
2244
- return `${static_}${key};`
2245
- }
2246
-
2247
- generateExpressionStatement(node) {
2248
- return this.generate(node.expression) + ';'
2249
- }
2250
-
2251
- generateCallExpression(node) {
2252
- const callee = this.generate(node.callee)
2253
- const args = node.arguments.map(a => this.generate(a)).join(', ')
2254
- const optional = node.optional ? '?.' : ''
2255
- return `${callee}${optional}(${args})`
2256
- }
2257
-
2258
- generateNewExpression(node) {
2259
- const callee = this.generate(node.callee)
2260
- const args = node.arguments.map(a => this.generate(a)).join(', ')
2261
- return `new ${callee}(${args})`
2262
- }
2263
-
2264
- generateMemberExpression(node) {
2265
- const object = this.generate(node.object)
2266
- const property = this.generate(node.property)
2267
- const optional = node.optional ? '?.' : ''
2268
- if (node.computed) {
2269
- return `${object}${optional}[${property}]`
2270
- }
2271
- return `${object}${optional}.${property}`
2272
- }
2273
-
2274
- generateBinaryExpression(node) {
2275
- return `${this.generate(node.left)} ${node.operator} ${this.generate(node.right)}`
2276
- }
2277
-
2278
- generateUnaryExpression(node) {
2279
- if (node.prefix) {
2280
- return `${node.operator}${this.generate(node.argument)}`
2281
- }
2282
- return `${this.generate(node.argument)}${node.operator}`
2283
- }
2284
-
2285
- generateUpdateExpression(node) {
2286
- if (node.prefix) {
2287
- return `${node.operator}${this.generate(node.argument)}`
2288
- }
2289
- return `${this.generate(node.argument)}${node.operator}`
2290
- }
2291
-
2292
- generateLogicalExpression(node) {
2293
- return `${this.generate(node.left)} ${node.operator} ${this.generate(node.right)}`
2294
- }
2295
-
2296
- generateConditionalExpression(node) {
2297
- return `${this.generate(node.test)} ? ${this.generate(node.consequent)} : ${this.generate(node.alternate)}`
2298
- }
2299
-
2300
- generateAssignmentExpression(node) {
2301
- return `${this.generate(node.left)} ${node.operator} ${this.generate(node.right)}`
2302
- }
2303
-
2304
- generateSequenceExpression(node) {
2305
- return node.expressions.map(e => this.generate(e)).join(', ')
2306
- }
2307
-
2308
- generateAwaitExpression(node) {
2309
- return `await ${this.generate(node.argument)}`
2310
- }
2311
-
2312
- generateYieldExpression(node) {
2313
- const delegate = node.delegate ? '*' : ''
2314
- if (node.argument) {
2315
- return `yield${delegate} ${this.generate(node.argument)}`
2316
- }
2317
- return `yield${delegate}`
2318
- }
2319
-
2320
- generateThisExpression() {
2321
- return 'this'
2322
- }
2323
-
2324
- generateSuper() {
2325
- return 'super'
2326
- }
2327
-
2328
- generateIdentifier(node) {
2329
- return node.name
2330
- }
2331
-
2332
- generateStringLiteral(node) {
2333
- return `"${node.value}"`
2334
- }
2335
-
2336
- generateNumericLiteral(node) {
2337
- return String(node.value)
2338
- }
2339
-
2340
- generateBooleanLiteral(node) {
2341
- return String(node.value)
2342
- }
2343
-
2344
- generateNullLiteral() {
2345
- return 'null'
2346
- }
2347
-
2348
- generateUndefinedLiteral() {
2349
- return 'undefined'
2350
- }
2351
-
2352
- generateArrayExpression(node) {
2353
- const elements = node.elements.map(e => e ? this.generate(e) : '').join(', ')
2354
- return `[${elements}]`
2355
- }
2356
-
2357
- generateObjectExpression(node) {
2358
- if (node.properties.length === 0) return '{}'
2359
- const props = node.properties.map(p => this.generate(p)).join(', ')
2360
- return `{ ${props} }`
2361
- }
2362
-
2363
- generateProperty(node) {
2364
- if (node.shorthand) {
2365
- return this.generate(node.key)
2366
- }
2367
- const key = node.computed ? `[${this.generate(node.key)}]` : this.generate(node.key)
2368
- return `${key}: ${this.generate(node.value)}`
2369
- }
2370
-
2371
- generateSpreadElement(node) {
2372
- return `...${this.generate(node.argument)}`
2373
- }
2374
-
2375
- generateRestElement(node) {
2376
- return `...${this.generate(node.argument)}`
2377
- }
2378
-
2379
- generateAssignmentPattern(node) {
2380
- return `${this.generate(node.left)} = ${this.generate(node.right)}`
2381
- }
2382
-
2383
- generateArrayPattern(node) {
2384
- const elements = node.elements.map(e => e ? this.generate(e) : '').join(', ')
2385
- return `[${elements}]`
2386
- }
2387
-
2388
- generateObjectPattern(node) {
2389
- const props = node.properties.map(p => this.generate(p)).join(', ')
2390
- return `{ ${props} }`
2391
- }
2392
-
2393
- generateTemplateLiteral(node) {
2394
- let code = '`'
2395
- for (let i = 0; i < node.quasis.length; i++) {
2396
- code += node.quasis[i].value.raw
2397
- if (i < node.expressions.length) {
2398
- code += '${' + this.generate(node.expressions[i]) + '}'
2399
- }
2400
- }
2401
- return code + '`'
2402
- }
2403
-
2404
- generateTemplateElement(node) {
2405
- return node.value.raw
2406
- }
2407
-
2408
- generateFSReadFile(node) {
2409
- const args = [this.generate(node.path)]
2410
- if (node.options) args.push(this.generate(node.options))
2411
- if (node.callback) args.push(this.generate(node.callback))
2412
- return `fs.readFile(${args.join(', ')})`
2413
- }
2414
-
2415
- generateFSReadFileSync(node) {
2416
- const args = [this.generate(node.path)]
2417
- if (node.options) args.push(this.generate(node.options))
2418
- return `fs.readFileSync(${args.join(', ')})`
2419
- }
2420
-
2421
- generateFSWriteFile(node) {
2422
- const args = [this.generate(node.path), this.generate(node.data)]
2423
- if (node.options) args.push(this.generate(node.options))
2424
- if (node.callback) args.push(this.generate(node.callback))
2425
- return `fs.writeFile(${args.join(', ')})`
2426
- }
2427
-
2428
- generateFSWriteFileSync(node) {
2429
- const args = [this.generate(node.path), this.generate(node.data)]
2430
- if (node.options) args.push(this.generate(node.options))
2431
- return `fs.writeFileSync(${args.join(', ')})`
2432
- }
2433
-
2434
- generatePathJoin(node) {
2435
- return `path.join(${node.paths.map(p => this.generate(p)).join(', ')})`
2436
- }
2437
-
2438
- generatePathResolve(node) {
2439
- return `path.resolve(${node.paths.map(p => this.generate(p)).join(', ')})`
2440
- }
2441
-
2442
- generatePathDirname(node) {
2443
- return `path.dirname(${this.generate(node.path)})`
2444
- }
2445
-
2446
- generatePathBasename(node) {
2447
- const args = [this.generate(node.path)]
2448
- if (node.ext) args.push(this.generate(node.ext))
2449
- return `path.basename(${args.join(', ')})`
2450
- }
2451
-
2452
- generatePathExtname(node) {
2453
- return `path.extname(${this.generate(node.path)})`
2454
- }
2455
-
2456
- generateHttpCreateServer(node) {
2457
- if (node.requestListener) {
2458
- return `http.createServer(${this.generate(node.requestListener)})`
2459
- }
2460
- return 'http.createServer()'
2461
- }
2462
-
2463
- generateServerListen(node) {
2464
- const args = [this.generate(node.port)]
2465
- if (node.hostname) args.push(this.generate(node.hostname))
2466
- if (node.callback) args.push(this.generate(node.callback))
2467
- return `server.listen(${args.join(', ')})`
2468
- }
2469
-
2470
- generateProcessCwd() {
2471
- return 'process.cwd()'
2472
- }
2473
-
2474
- generateProcessExit(node) {
2475
- if (node.code !== null && node.code !== undefined) {
2476
- return `process.exit(${this.generate(node.code)})`
2477
- }
2478
- return 'process.exit()'
2479
- }
2480
-
2481
- generateProcessEnv(node) {
2482
- if (node.variable) {
2483
- return `process.env.${node.variable}`
2484
- }
2485
- return 'process.env'
2486
- }
2487
-
2488
- generateConsoleLog(node) {
2489
- return `console.log(${node.args.map(a => this.generate(a)).join(', ')})`
2490
- }
2491
-
2492
- generateConsoleError(node) {
2493
- return `console.error(${node.args.map(a => this.generate(a)).join(', ')})`
2494
- }
2495
-
2496
- generateConsoleWarn(node) {
2497
- return `console.warn(${node.args.map(a => this.generate(a)).join(', ')})`
2498
- }
2499
-
2500
- generateSetTimeout(node) {
2501
- const args = [this.generate(node.callback), this.generate(node.delay)]
2502
- args.push(...node.args.map(a => this.generate(a)))
2503
- return `setTimeout(${args.join(', ')})`
2504
- }
2505
-
2506
- generateClearTimeout(node) {
2507
- return `clearTimeout(${this.generate(node.timeoutId)})`
2508
- }
2509
-
2510
- generateSetInterval(node) {
2511
- const args = [this.generate(node.callback), this.generate(node.delay)]
2512
- args.push(...node.args.map(a => this.generate(a)))
2513
- return `setInterval(${args.join(', ')})`
2514
- }
2515
-
2516
- generateClearInterval(node) {
2517
- return `clearInterval(${this.generate(node.intervalId)})`
2518
- }
2519
-
2520
- generateDirname() {
2521
- return '__dirname'
2522
- }
2523
-
2524
- generateFilename() {
2525
- return '__filename'
2526
- }
2527
-
2528
- generateCryptoRandomBytes(node) {
2529
- const args = [this.generate(node.size)]
2530
- if (node.callback) args.push(this.generate(node.callback))
2531
- return `crypto.randomBytes(${args.join(', ')})`
2532
- }
2533
-
2534
- generateCryptoRandomUUID() {
2535
- return 'crypto.randomUUID()'
2536
- }
2537
-
2538
- generateCryptoPbkdf2Sync(node) {
2539
- return `crypto.pbkdf2Sync(${this.generate(node.password)}, ${this.generate(node.salt)}, ${this.generate(node.iterations)}, ${this.generate(node.keylen)}, ${this.generate(node.digest)})`
2540
- }
2541
-
2542
- generateBufferFrom(node) {
2543
- const args = [this.generate(node.data)]
2544
- if (node.encodingOrOffset) args.push(this.generate(node.encodingOrOffset))
2545
- if (node.length) args.push(this.generate(node.length))
2546
- return `Buffer.from(${args.join(', ')})`
2547
- }
2548
-
2549
- generateBufferAlloc(node) {
2550
- const args = [this.generate(node.size)]
2551
- if (node.fill) args.push(this.generate(node.fill))
2552
- if (node.encoding) args.push(this.generate(node.encoding))
2553
- return `Buffer.alloc(${args.join(', ')})`
2554
- }
2555
-
2556
- generateOsType() {
2557
- return 'os.type()'
2558
- }
2559
-
2560
- generateOsPlatform() {
2561
- return 'os.platform()'
2562
- }
2563
-
2564
- generateOsArch() {
2565
- return 'os.arch()'
2566
- }
2567
-
2568
- generateOsHomedir() {
2569
- return 'os.homedir()'
2570
- }
2571
-
2572
- generateOsTmpdir() {
2573
- return 'os.tmpdir()'
2574
- }
2575
-
2576
- generateOsTotalmem() {
2577
- return 'os.totalmem()'
2578
- }
2579
-
2580
- generateOsFreemem() {
2581
- return 'os.freemem()'
2582
- }
2583
-
2584
- generateOsCpus() {
2585
- return 'os.cpus()'
2586
- }
2587
-
2588
- generateChildProcessExec(node) {
2589
- const args = [this.generate(node.command)]
2590
- if (node.options) args.push(this.generate(node.options))
2591
- if (node.callback) args.push(this.generate(node.callback))
2592
- return `child_process.exec(${args.join(', ')})`
2593
- }
2594
-
2595
- generateChildProcessSpawn(node) {
2596
- const args = [this.generate(node.command)]
2597
- if (node.args && node.args.length) args.push(this.generate(node.args))
2598
- if (node.options) args.push(this.generate(node.options))
2599
- return `child_process.spawn(${args.join(', ')})`
2600
- }
2601
-
2602
- generateUtilPromisify(node) {
2603
- return `util.promisify(${this.generate(node.original)})`
2604
- }
2605
-
2606
- generateDnsLookup(node) {
2607
- const args = [this.generate(node.hostname)]
2608
- if (node.options) args.push(this.generate(node.options))
2609
- if (node.callback) args.push(this.generate(node.callback))
2610
- return `dns.lookup(${args.join(', ')})`
2611
- }
2612
-
2613
- generatePromiseExpression(node) {
2614
- return `new Promise(${this.generate(node.executor)})`
2615
- }
2616
-
2617
- generatePromiseResolve(node) {
2618
- if (node.value) {
2619
- return `Promise.resolve(${this.generate(node.value)})`
2620
- }
2621
- return 'Promise.resolve()'
2622
- }
2623
-
2624
- generatePromiseReject(node) {
2625
- if (node.reason) {
2626
- return `Promise.reject(${this.generate(node.reason)})`
2627
- }
2628
- return 'Promise.reject()'
2629
- }
2630
-
2631
- generatePromiseAll(node) {
2632
- return `Promise.all(${this.generate(node.iterable)})`
2633
- }
2634
-
2635
- generatePromiseRace(node) {
2636
- return `Promise.race(${this.generate(node.iterable)})`
2637
- }
2638
-
2639
- generateEmptyStatement() {
2640
- return ';'
2641
- }
2642
- }
2643
-
2644
- module.exports = { NodeParser, NodeCodeGenerator }