ether-code 0.9.1 → 0.9.2
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.
- package/cli/ether.js +1 -1
- package/generators/php-generator.js +801 -738
- package/lexer/ether-lexer.js +5 -3
- package/package.json +1 -1
- package/parsers/ether-parser-php.js +14 -4
|
@@ -5,571 +5,778 @@ class PHPGenerator {
|
|
|
5
5
|
this.i18n = null
|
|
6
6
|
this.indent = 0
|
|
7
7
|
this.output = ''
|
|
8
|
-
this.translationMap = {}
|
|
9
|
-
this.functionMap = {}
|
|
10
|
-
this.supportedLanguages = ['fr', 'en', 'es', 'ru', 'zh', 'ja']
|
|
11
8
|
|
|
12
9
|
if (i18nPath) {
|
|
13
10
|
this.loadI18n(i18nPath)
|
|
14
11
|
}
|
|
12
|
+
|
|
13
|
+
this.buildFunctionMap()
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
loadI18n(filePath) {
|
|
18
17
|
const content = fs.readFileSync(filePath, 'utf-8')
|
|
19
18
|
this.i18n = JSON.parse(content)
|
|
20
|
-
this.buildTranslationMap()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
buildTranslationMap() {
|
|
24
|
-
this.translationMap = {}
|
|
25
|
-
this.functionMap = {}
|
|
26
|
-
|
|
27
|
-
if (!this.i18n) return
|
|
28
|
-
|
|
29
|
-
for (const [sectionName, section] of Object.entries(this.i18n)) {
|
|
30
|
-
if (sectionName === 'metadata' || typeof section !== 'object') continue
|
|
31
|
-
|
|
32
|
-
for (const lang of this.supportedLanguages) {
|
|
33
|
-
if (!section[lang]) continue
|
|
34
|
-
|
|
35
|
-
for (const [etherWord, phpCode] of Object.entries(section[lang])) {
|
|
36
|
-
const fixed = this.normalizeUTF8(etherWord)
|
|
37
|
-
const normalizedKey = fixed.toLowerCase().trim()
|
|
38
|
-
const cleanPhp = this.cleanPhpValue(phpCode)
|
|
39
|
-
|
|
40
|
-
if (phpCode.endsWith('()')) {
|
|
41
|
-
this.functionMap[normalizedKey] = cleanPhp
|
|
42
|
-
const withoutAccents = this.removeAccents(normalizedKey)
|
|
43
|
-
if (withoutAccents !== normalizedKey) {
|
|
44
|
-
this.functionMap[withoutAccents] = cleanPhp
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this.translationMap[normalizedKey] = cleanPhp
|
|
49
|
-
|
|
50
|
-
const withoutAccents = this.removeAccents(normalizedKey)
|
|
51
|
-
if (withoutAccents !== normalizedKey) {
|
|
52
|
-
this.translationMap[withoutAccents] = cleanPhp
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
19
|
}
|
|
58
20
|
|
|
59
|
-
|
|
21
|
+
normalizeAccents(str) {
|
|
60
22
|
if (typeof str !== 'string') return String(str)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
23
|
+
return str.toLowerCase()
|
|
24
|
+
.normalize('NFD')
|
|
25
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
26
|
+
.replace(/-/g, ' ')
|
|
27
|
+
.replace(/_/g, ' ')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
buildFunctionMap() {
|
|
31
|
+
this.functionMap = {
|
|
32
|
+
'est chaine': 'is_string',
|
|
33
|
+
'est entier': 'is_int',
|
|
34
|
+
'est flottant': 'is_float',
|
|
35
|
+
'est tableau': 'is_array',
|
|
36
|
+
'est booleen': 'is_bool',
|
|
37
|
+
'est nul': 'is_null',
|
|
38
|
+
'est null': 'is_null',
|
|
39
|
+
'est objet': 'is_object',
|
|
40
|
+
'est numerique': 'is_numeric',
|
|
41
|
+
'est callable': 'is_callable',
|
|
42
|
+
'est appelable': 'is_callable',
|
|
43
|
+
'est ressource': 'is_resource',
|
|
44
|
+
'est scalaire': 'is_scalar',
|
|
45
|
+
'est vide': 'empty',
|
|
46
|
+
'est iterable': 'is_iterable',
|
|
47
|
+
'est comptable': 'is_countable',
|
|
48
|
+
'obtenir type': 'gettype',
|
|
49
|
+
'definir type': 'settype',
|
|
50
|
+
'valeur entier': 'intval',
|
|
51
|
+
'valeur entiere': 'intval',
|
|
52
|
+
'valeur flottant': 'floatval',
|
|
53
|
+
'valeur chaine': 'strval',
|
|
54
|
+
'valeur booleen': 'boolval',
|
|
55
|
+
'longueur': 'strlen',
|
|
56
|
+
'sous chaine': 'substr',
|
|
57
|
+
'sous-chaine': 'substr',
|
|
58
|
+
'position': 'strpos',
|
|
59
|
+
'remplacer': 'str_replace',
|
|
60
|
+
'exploser': 'explode',
|
|
61
|
+
'imploser': 'implode',
|
|
62
|
+
'majuscules': 'strtoupper',
|
|
63
|
+
'minuscules': 'strtolower',
|
|
64
|
+
'couper espaces': 'trim',
|
|
65
|
+
'rogner': 'trim',
|
|
66
|
+
'rogner gauche': 'ltrim',
|
|
67
|
+
'rogner droite': 'rtrim',
|
|
68
|
+
'repeter': 'str_repeat',
|
|
69
|
+
'inverser chaine': 'strrev',
|
|
70
|
+
'remplir': 'str_pad',
|
|
71
|
+
'remplir gauche': 'str_pad',
|
|
72
|
+
'compter': 'count',
|
|
73
|
+
'trier': 'sort',
|
|
74
|
+
'trier inverse': 'rsort',
|
|
75
|
+
'trier associatif': 'asort',
|
|
76
|
+
'trier cles': 'ksort',
|
|
77
|
+
'inverser': 'array_reverse',
|
|
78
|
+
'fusionner': 'array_merge',
|
|
79
|
+
'fusionner tableaux': 'array_merge',
|
|
80
|
+
'filtrer': 'array_filter',
|
|
81
|
+
'filtrer tableau': 'array_filter',
|
|
82
|
+
'mapper': 'array_map',
|
|
83
|
+
'mapper tableau': 'array_map',
|
|
84
|
+
'transformer': 'array_map',
|
|
85
|
+
'reduire': 'array_reduce',
|
|
86
|
+
'reduire tableau': 'array_reduce',
|
|
87
|
+
'cles': 'array_keys',
|
|
88
|
+
'tableau cles': 'array_keys',
|
|
89
|
+
'valeurs': 'array_values',
|
|
90
|
+
'tableau valeurs': 'array_values',
|
|
91
|
+
'pousser': 'array_push',
|
|
92
|
+
'ajouter': 'array_push',
|
|
93
|
+
'retirer': 'array_pop',
|
|
94
|
+
'rechercher': 'array_search',
|
|
95
|
+
'existe': 'array_key_exists',
|
|
96
|
+
'cle existe': 'array_key_exists',
|
|
97
|
+
'dans tableau': 'in_array',
|
|
98
|
+
'somme': 'array_sum',
|
|
99
|
+
'somme tableau': 'array_sum',
|
|
100
|
+
'unique': 'array_unique',
|
|
101
|
+
'decouper': 'array_slice',
|
|
102
|
+
'epissure': 'array_splice',
|
|
103
|
+
'combiner': 'array_combine',
|
|
104
|
+
'remplir tableau': 'array_fill',
|
|
105
|
+
'colonne': 'array_column',
|
|
106
|
+
'compter valeurs': 'array_count_values',
|
|
107
|
+
'difference': 'array_diff',
|
|
108
|
+
'intersection': 'array_intersect',
|
|
109
|
+
'premier': 'reset',
|
|
110
|
+
'dernier': 'end',
|
|
111
|
+
'suivant': 'next',
|
|
112
|
+
'precedent': 'prev',
|
|
113
|
+
'courant': 'current',
|
|
114
|
+
'cle courante': 'key',
|
|
115
|
+
'melanger': 'shuffle',
|
|
116
|
+
'absolu': 'abs',
|
|
117
|
+
'plafond': 'ceil',
|
|
118
|
+
'plancher': 'floor',
|
|
119
|
+
'arrondir': 'round',
|
|
120
|
+
'arrondi': 'round',
|
|
121
|
+
'racine carree': 'sqrt',
|
|
122
|
+
'puissance': 'pow',
|
|
123
|
+
'aleatoire': 'rand',
|
|
124
|
+
'aleatoire entier': 'random_int',
|
|
125
|
+
'maximum': 'max',
|
|
126
|
+
'minimum': 'min',
|
|
127
|
+
'pi': 'pi',
|
|
128
|
+
'exponentielle': 'exp',
|
|
129
|
+
'logarithme': 'log',
|
|
130
|
+
'logarithme10': 'log10',
|
|
131
|
+
'sinus': 'sin',
|
|
132
|
+
'cosinus': 'cos',
|
|
133
|
+
'tangente': 'tan',
|
|
134
|
+
'formater nombre': 'number_format',
|
|
135
|
+
'date': 'date',
|
|
136
|
+
'temps': 'time',
|
|
137
|
+
'maintenant': 'time',
|
|
138
|
+
'creer date': 'mktime',
|
|
139
|
+
'date vers temps': 'strtotime',
|
|
140
|
+
'formater date': 'date_format',
|
|
141
|
+
'fichier existe': 'file_exists',
|
|
142
|
+
'lire fichier': 'file_get_contents',
|
|
143
|
+
'ecrire fichier': 'file_put_contents',
|
|
144
|
+
'ouvrir fichier': 'fopen',
|
|
145
|
+
'fermer fichier': 'fclose',
|
|
146
|
+
'lire ligne': 'fgets',
|
|
147
|
+
'ecrire ligne': 'fputs',
|
|
148
|
+
'est fichier': 'is_file',
|
|
149
|
+
'est repertoire': 'is_dir',
|
|
150
|
+
'creer repertoire': 'mkdir',
|
|
151
|
+
'supprimer fichier': 'unlink',
|
|
152
|
+
'renommer': 'rename',
|
|
153
|
+
'copier': 'copy',
|
|
154
|
+
'taille fichier': 'filesize',
|
|
155
|
+
'encoder json': 'json_encode',
|
|
156
|
+
'decoder json': 'json_decode',
|
|
157
|
+
'json encoder': 'json_encode',
|
|
158
|
+
'json decoder': 'json_decode',
|
|
159
|
+
'correspondre': 'preg_match',
|
|
160
|
+
'regex correspondance': 'preg_match',
|
|
161
|
+
'regex toutes': 'preg_match_all',
|
|
162
|
+
'regex remplacer': 'preg_replace',
|
|
163
|
+
'demarrer session': 'session_start',
|
|
164
|
+
'detruire session': 'session_destroy',
|
|
165
|
+
'definir cookie': 'setcookie',
|
|
166
|
+
'hacher': 'hash',
|
|
167
|
+
'hacher mot de passe': 'password_hash',
|
|
168
|
+
'verifier mot de passe': 'password_verify',
|
|
169
|
+
'md5': 'md5',
|
|
170
|
+
'sha1': 'sha1',
|
|
171
|
+
'base64 encoder': 'base64_encode',
|
|
172
|
+
'base64 decoder': 'base64_decode',
|
|
173
|
+
'url encoder': 'urlencode',
|
|
174
|
+
'url decoder': 'urldecode',
|
|
175
|
+
'htmlentites': 'htmlentities',
|
|
176
|
+
'html special': 'htmlspecialchars',
|
|
177
|
+
'enlever balises': 'strip_tags',
|
|
178
|
+
'echapper': 'addslashes',
|
|
179
|
+
'preparer': 'prepare',
|
|
180
|
+
'executer': 'execute',
|
|
181
|
+
'recuperer': 'fetch',
|
|
182
|
+
'recuperer tout': 'fetchAll',
|
|
183
|
+
'nombre lignes': 'rowCount',
|
|
184
|
+
'dernier id': 'lastInsertId',
|
|
185
|
+
'afficher info': 'var_dump',
|
|
186
|
+
'imprimer r': 'print_r',
|
|
187
|
+
'exporter': 'var_export',
|
|
188
|
+
'vide': 'empty',
|
|
189
|
+
'defini': 'isset',
|
|
190
|
+
'supprimer': 'unset',
|
|
191
|
+
'sortie': 'exit',
|
|
192
|
+
'mourir': 'die',
|
|
193
|
+
'dormir': 'sleep',
|
|
194
|
+
'micro dormir': 'usleep',
|
|
195
|
+
'entete': 'header',
|
|
196
|
+
'en tete': 'header',
|
|
197
|
+
'rediriger': 'header',
|
|
198
|
+
'serialiser': 'serialize',
|
|
199
|
+
'deserialiser': 'unserialize',
|
|
200
|
+
'formater': 'format',
|
|
201
|
+
'getmessage': 'getMessage'
|
|
70
202
|
}
|
|
71
|
-
}
|
|
72
203
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
204
|
+
this.keywordMap = {
|
|
205
|
+
'variable': '',
|
|
206
|
+
'constante': 'const',
|
|
207
|
+
'fonction': 'function',
|
|
208
|
+
'retourner': 'return',
|
|
209
|
+
'si': 'if',
|
|
210
|
+
'sinon': 'else',
|
|
211
|
+
'sinon si': 'elseif',
|
|
212
|
+
'pour': 'for',
|
|
213
|
+
'pour chaque': 'foreach',
|
|
214
|
+
'tant que': 'while',
|
|
215
|
+
'faire': 'do',
|
|
216
|
+
'selon': 'switch',
|
|
217
|
+
'cas': 'case',
|
|
218
|
+
'defaut': 'default',
|
|
219
|
+
'sortir': 'break',
|
|
220
|
+
'continuer': 'continue',
|
|
221
|
+
'essayer': 'try',
|
|
222
|
+
'attraper': 'catch',
|
|
223
|
+
'finalement': 'finally',
|
|
224
|
+
'lancer': 'throw',
|
|
225
|
+
'nouveau': 'new',
|
|
226
|
+
'nouvelle': 'new',
|
|
227
|
+
'classe': 'class',
|
|
228
|
+
'interface': 'interface',
|
|
229
|
+
'trait': 'trait',
|
|
230
|
+
'etend': 'extends',
|
|
231
|
+
'etendre': 'extends',
|
|
232
|
+
'implemente': 'implements',
|
|
233
|
+
'implementer': 'implements',
|
|
234
|
+
'utiliser': 'use',
|
|
235
|
+
'public': 'public',
|
|
236
|
+
'publique': 'public',
|
|
237
|
+
'prive': 'private',
|
|
238
|
+
'privee': 'private',
|
|
239
|
+
'protege': 'protected',
|
|
240
|
+
'protegee': 'protected',
|
|
241
|
+
'statique': 'static',
|
|
242
|
+
'final': 'final',
|
|
243
|
+
'finale': 'final',
|
|
244
|
+
'abstrait': 'abstract',
|
|
245
|
+
'abstraite': 'abstract',
|
|
246
|
+
'constructeur': '__construct',
|
|
247
|
+
'destructeur': '__destruct',
|
|
248
|
+
'obtenir': '__get',
|
|
249
|
+
'definir': '__set',
|
|
250
|
+
'appeler': '__call',
|
|
251
|
+
'vers chaine': '__toString',
|
|
252
|
+
'espace de noms': 'namespace',
|
|
253
|
+
'comme': 'as',
|
|
254
|
+
'vrai': 'true',
|
|
255
|
+
'faux': 'false',
|
|
256
|
+
'nul': 'null',
|
|
257
|
+
'rien': 'null',
|
|
258
|
+
'ceci': '$this',
|
|
259
|
+
'parent': 'parent',
|
|
260
|
+
'self': 'self',
|
|
261
|
+
'soi': 'self',
|
|
262
|
+
'et': '&&',
|
|
263
|
+
'ou': '||',
|
|
264
|
+
'non': '!',
|
|
265
|
+
'egal': '===',
|
|
266
|
+
'different': '!==',
|
|
267
|
+
'concatener': '.',
|
|
268
|
+
'tableau': 'array',
|
|
269
|
+
'chaine': 'string',
|
|
270
|
+
'entier': 'int',
|
|
271
|
+
'flottant': 'float',
|
|
272
|
+
'booleen': 'bool',
|
|
273
|
+
'objet': 'object',
|
|
274
|
+
'vide type': 'void',
|
|
275
|
+
'void': 'void',
|
|
276
|
+
'mixte': 'mixed',
|
|
277
|
+
'afficher': 'echo',
|
|
278
|
+
'imprimer': 'print',
|
|
279
|
+
'inclure': 'include',
|
|
280
|
+
'inclure une fois': 'include_once',
|
|
281
|
+
'requiert': 'require',
|
|
282
|
+
'requerir': 'require',
|
|
283
|
+
'requiert une fois': 'require_once',
|
|
284
|
+
'requerir une fois': 'require_once',
|
|
285
|
+
'rendement': 'yield',
|
|
286
|
+
'rendement de': 'yield from'
|
|
287
|
+
}
|
|
77
288
|
}
|
|
78
289
|
|
|
79
290
|
translate(word) {
|
|
80
|
-
if (!word
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (this.translationMap[normalized]) {
|
|
85
|
-
return this.translationMap[normalized]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const withoutAccents = this.removeAccents(normalized)
|
|
89
|
-
if (this.translationMap[withoutAccents]) {
|
|
90
|
-
return this.translationMap[withoutAccents]
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return word
|
|
291
|
+
if (!word) return word
|
|
292
|
+
const normalized = this.normalizeAccents(word)
|
|
293
|
+
return this.functionMap[normalized] || this.keywordMap[normalized] || word
|
|
94
294
|
}
|
|
95
295
|
|
|
96
296
|
translateFunction(word) {
|
|
97
|
-
if (!word
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const withoutAccents = this.removeAccents(normalized)
|
|
101
|
-
|
|
102
|
-
if (this.functionMap[normalized]) {
|
|
103
|
-
return this.functionMap[normalized]
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (this.functionMap[withoutAccents]) {
|
|
107
|
-
return this.functionMap[withoutAccents]
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (this.translationMap[normalized]) {
|
|
111
|
-
return this.translationMap[normalized]
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (this.translationMap[withoutAccents]) {
|
|
115
|
-
return this.translationMap[withoutAccents]
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return word
|
|
297
|
+
if (!word) return word
|
|
298
|
+
const normalized = this.normalizeAccents(word)
|
|
299
|
+
return this.functionMap[normalized] || word
|
|
119
300
|
}
|
|
120
301
|
|
|
121
|
-
|
|
122
|
-
|
|
302
|
+
translateKeyword(word) {
|
|
303
|
+
if (!word) return word
|
|
304
|
+
const normalized = this.normalizeAccents(word)
|
|
305
|
+
return this.keywordMap[normalized] || word
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
extractTypeName(typeNode) {
|
|
309
|
+
if (!typeNode) return ''
|
|
310
|
+
if (typeof typeNode === 'string') return this.translateKeyword(typeNode)
|
|
311
|
+
if (typeNode.name) return this.translateKeyword(typeNode.name)
|
|
312
|
+
if (typeNode.type === 'Identifier') return this.translateKeyword(typeNode.name || typeNode.value || '')
|
|
313
|
+
if (typeNode.value) return this.translateKeyword(typeNode.value)
|
|
314
|
+
return ''
|
|
123
315
|
}
|
|
124
316
|
|
|
125
317
|
generate(ast) {
|
|
126
|
-
this.output = '
|
|
318
|
+
this.output = ''
|
|
127
319
|
this.indent = 0
|
|
128
|
-
|
|
129
|
-
if (ast.
|
|
130
|
-
this.
|
|
131
|
-
this.writeLine('')
|
|
320
|
+
|
|
321
|
+
if (ast.phpTag !== false) {
|
|
322
|
+
this.output = '<?php\n'
|
|
132
323
|
}
|
|
133
324
|
|
|
134
|
-
if (Array.isArray(ast
|
|
135
|
-
for (const node of ast
|
|
325
|
+
if (Array.isArray(ast)) {
|
|
326
|
+
for (const node of ast) {
|
|
136
327
|
this.generateNode(node)
|
|
137
328
|
}
|
|
138
|
-
} else if (ast.
|
|
139
|
-
|
|
140
|
-
|
|
329
|
+
} else if (ast && ast.type === 'Program') {
|
|
330
|
+
for (const node of ast.body || []) {
|
|
331
|
+
this.generateNode(node)
|
|
332
|
+
}
|
|
333
|
+
} else if (ast && ast.type) {
|
|
141
334
|
this.generateNode(ast)
|
|
335
|
+
} else if (ast && ast.body) {
|
|
336
|
+
for (const node of ast.body) {
|
|
337
|
+
this.generateNode(node)
|
|
338
|
+
}
|
|
142
339
|
}
|
|
143
340
|
|
|
144
|
-
return this.output
|
|
341
|
+
return this.output.trim()
|
|
145
342
|
}
|
|
146
343
|
|
|
147
344
|
generateNode(node) {
|
|
148
345
|
if (!node) return ''
|
|
149
346
|
|
|
150
|
-
|
|
151
|
-
|
|
347
|
+
switch (node.type) {
|
|
348
|
+
case 'Program':
|
|
349
|
+
for (const stmt of node.body || []) {
|
|
350
|
+
this.generateNode(stmt)
|
|
351
|
+
}
|
|
352
|
+
return ''
|
|
353
|
+
case 'DeclareStatement':
|
|
354
|
+
return this.generateDeclareStatement(node)
|
|
355
|
+
case 'NamespaceDeclaration':
|
|
356
|
+
return this.generateNamespace(node)
|
|
357
|
+
case 'UseStatement':
|
|
358
|
+
return this.generateUseStatement(node)
|
|
359
|
+
case 'ConstantDeclaration':
|
|
360
|
+
return this.generateConstantDeclaration(node)
|
|
361
|
+
case 'VariableDeclaration':
|
|
362
|
+
return this.generateVariableDeclaration(node)
|
|
363
|
+
case 'FunctionDeclaration':
|
|
364
|
+
return this.generateFunctionDeclaration(node)
|
|
365
|
+
case 'ClassDeclaration':
|
|
366
|
+
return this.generateClassDeclaration(node)
|
|
367
|
+
case 'InterfaceDeclaration':
|
|
368
|
+
return this.generateInterfaceDeclaration(node)
|
|
369
|
+
case 'TraitDeclaration':
|
|
370
|
+
return this.generateTraitDeclaration(node)
|
|
371
|
+
case 'EnumDeclaration':
|
|
372
|
+
return this.generateEnumDeclaration(node)
|
|
373
|
+
case 'IfStatement':
|
|
374
|
+
return this.generateIfStatement(node)
|
|
375
|
+
case 'ForStatement':
|
|
376
|
+
return this.generateForStatement(node)
|
|
377
|
+
case 'ForEachStatement':
|
|
378
|
+
return this.generateForEachStatement(node)
|
|
379
|
+
case 'WhileStatement':
|
|
380
|
+
return this.generateWhileStatement(node)
|
|
381
|
+
case 'DoWhileStatement':
|
|
382
|
+
return this.generateDoWhileStatement(node)
|
|
383
|
+
case 'SwitchStatement':
|
|
384
|
+
return this.generateSwitchStatement(node)
|
|
385
|
+
case 'TryStatement':
|
|
386
|
+
return this.generateTryStatement(node)
|
|
387
|
+
case 'ReturnStatement':
|
|
388
|
+
return this.generateReturnStatement(node)
|
|
389
|
+
case 'ThrowStatement':
|
|
390
|
+
return this.generateThrowStatement(node)
|
|
391
|
+
case 'BreakStatement':
|
|
392
|
+
this.writeLine('break;')
|
|
393
|
+
return ''
|
|
394
|
+
case 'ContinueStatement':
|
|
395
|
+
this.writeLine('continue;')
|
|
396
|
+
return ''
|
|
397
|
+
case 'ExpressionStatement':
|
|
398
|
+
return this.generateExpressionStatement(node)
|
|
399
|
+
case 'EchoStatement':
|
|
400
|
+
return this.generateEchoStatement(node)
|
|
401
|
+
case 'BlockStatement':
|
|
402
|
+
return this.generateBlockStatement(node)
|
|
403
|
+
case 'CallExpression':
|
|
404
|
+
return this.generateCallExpression(node)
|
|
405
|
+
case 'MemberExpression':
|
|
406
|
+
return this.generateMemberExpression(node)
|
|
407
|
+
case 'StaticMemberExpression':
|
|
408
|
+
return this.generateStaticMemberExpression(node)
|
|
409
|
+
case 'BinaryExpression':
|
|
410
|
+
return this.generateBinaryExpression(node)
|
|
411
|
+
case 'LogicalExpression':
|
|
412
|
+
return this.generateBinaryExpression(node)
|
|
413
|
+
case 'AssignmentExpression':
|
|
414
|
+
return this.generateAssignmentExpression(node)
|
|
415
|
+
case 'UnaryExpression':
|
|
416
|
+
return this.generateUnaryExpression(node)
|
|
417
|
+
case 'UpdateExpression':
|
|
418
|
+
return this.generateUpdateExpression(node)
|
|
419
|
+
case 'ConditionalExpression':
|
|
420
|
+
return this.generateConditionalExpression(node)
|
|
421
|
+
case 'ArrayExpression':
|
|
422
|
+
return this.generateArrayExpression(node)
|
|
423
|
+
case 'ObjectExpression':
|
|
424
|
+
return this.generateObjectExpression(node)
|
|
425
|
+
case 'Identifier':
|
|
426
|
+
return this.generateIdentifier(node)
|
|
427
|
+
case 'Variable':
|
|
428
|
+
return this.generateVariable(node)
|
|
429
|
+
case 'Literal':
|
|
430
|
+
return this.generateLiteral(node)
|
|
431
|
+
case 'StringLiteral':
|
|
432
|
+
return this.generateStringLiteral(node)
|
|
433
|
+
case 'NewExpression':
|
|
434
|
+
return this.generateNewExpression(node)
|
|
435
|
+
case 'ThisExpression':
|
|
436
|
+
return '$this'
|
|
437
|
+
case 'FunctionExpression':
|
|
438
|
+
return this.generateFunctionExpression(node)
|
|
439
|
+
case 'ArrowFunctionExpression':
|
|
440
|
+
return this.generateArrowFunctionExpression(node)
|
|
441
|
+
case 'IndexExpression':
|
|
442
|
+
return this.generateIndexExpression(node)
|
|
443
|
+
case 'NullCoalesceExpression':
|
|
444
|
+
return this.generateNullCoalesceExpression(node)
|
|
445
|
+
case 'YieldExpression':
|
|
446
|
+
return this.generateYieldExpression(node)
|
|
447
|
+
default:
|
|
448
|
+
return ''
|
|
152
449
|
}
|
|
450
|
+
}
|
|
153
451
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
'
|
|
158
|
-
'FunctionDeclaration': () => this.generateFunctionDeclaration(node),
|
|
159
|
-
'ClassDeclaration': () => this.generateClassDeclaration(node),
|
|
160
|
-
'InterfaceDeclaration': () => this.generateInterfaceDeclaration(node),
|
|
161
|
-
'TraitDeclaration': () => this.generateTraitDeclaration(node),
|
|
162
|
-
'EnumDeclaration': () => this.generateEnumDeclaration(node),
|
|
163
|
-
'MethodDefinition': () => this.generateMethodDefinition(node),
|
|
164
|
-
'MethodDeclaration': () => this.generateMethodDefinition(node),
|
|
165
|
-
'PropertyDeclaration': () => this.generatePropertyDeclaration(node),
|
|
166
|
-
'VariableDeclaration': () => this.generateVariableDeclaration(node),
|
|
167
|
-
'ConstantDeclaration': () => this.generateConstantDeclaration(node),
|
|
168
|
-
'IfStatement': () => this.generateIfStatement(node),
|
|
169
|
-
'ForStatement': () => this.generateForStatement(node),
|
|
170
|
-
'ForEachStatement': () => this.generateForEachStatement(node),
|
|
171
|
-
'ForeachStatement': () => this.generateForEachStatement(node),
|
|
172
|
-
'WhileStatement': () => this.generateWhileStatement(node),
|
|
173
|
-
'DoWhileStatement': () => this.generateDoWhileStatement(node),
|
|
174
|
-
'SwitchStatement': () => this.generateSwitchStatement(node),
|
|
175
|
-
'MatchExpression': () => this.generateMatchExpression(node),
|
|
176
|
-
'TryStatement': () => this.generateTryStatement(node),
|
|
177
|
-
'ReturnStatement': () => this.generateReturnStatement(node),
|
|
178
|
-
'YieldExpression': () => this.generateYieldExpression(node),
|
|
179
|
-
'ThrowStatement': () => this.generateThrowStatement(node),
|
|
180
|
-
'BreakStatement': () => this.writeLine('break;'),
|
|
181
|
-
'ContinueStatement': () => this.writeLine('continue;'),
|
|
182
|
-
'ExpressionStatement': () => this.generateExpressionStatement(node),
|
|
183
|
-
'EchoStatement': () => this.generateEchoStatement(node),
|
|
184
|
-
'PrintStatement': () => this.generatePrintStatement(node),
|
|
185
|
-
'Namespace': () => this.generateNamespace(node),
|
|
186
|
-
'UseStatement': () => this.generateUseStatement(node),
|
|
187
|
-
'DeclareStatement': () => this.generateDeclareStatement(node),
|
|
188
|
-
'IncludeStatement': () => this.generateIncludeStatement(node),
|
|
189
|
-
'Include': () => this.generateInclude(node),
|
|
190
|
-
'CallExpression': () => this.generateCallExpression(node),
|
|
191
|
-
'MemberExpression': () => this.generateMemberExpression(node),
|
|
192
|
-
'StaticMemberExpression': () => this.generateStaticMemberExpression(node),
|
|
193
|
-
'IndexExpression': () => this.generateIndexExpression(node),
|
|
194
|
-
'BinaryExpression': () => this.generateBinaryExpression(node),
|
|
195
|
-
'LogicalExpression': () => this.generateBinaryExpression(node),
|
|
196
|
-
'UnaryExpression': () => this.generateUnaryExpression(node),
|
|
197
|
-
'AssignmentExpression': () => this.generateAssignmentExpression(node),
|
|
198
|
-
'UpdateExpression': () => this.generateUpdateExpression(node),
|
|
199
|
-
'ConditionalExpression': () => this.generateConditionalExpression(node),
|
|
200
|
-
'NullCoalescing': () => this.generateNullCoalescing(node),
|
|
201
|
-
'ArrayExpression': () => this.generateArrayExpression(node),
|
|
202
|
-
'ObjectExpression': () => this.generateObjectExpression(node),
|
|
203
|
-
'ArrowFunction': () => this.generateArrowFunction(node),
|
|
204
|
-
'ArrowFunctionExpression': () => this.generateArrowFunction(node),
|
|
205
|
-
'FunctionExpression': () => this.generateFunctionExpression(node),
|
|
206
|
-
'Closure': () => this.generateClosure(node),
|
|
207
|
-
'Identifier': () => this.generateIdentifier(node),
|
|
208
|
-
'ThisExpression': () => '$this',
|
|
209
|
-
'Literal': () => this.generateLiteral(node),
|
|
210
|
-
'StringLiteral': () => this.generateLiteral(node),
|
|
211
|
-
'NumericLiteral': () => this.generateLiteral(node),
|
|
212
|
-
'BooleanLiteral': () => this.generateLiteral(node),
|
|
213
|
-
'NullLiteral': () => 'null',
|
|
214
|
-
'NewExpression': () => this.generateNewExpression(node),
|
|
215
|
-
'InstanceOf': () => this.generateInstanceOf(node),
|
|
216
|
-
'BlockStatement': () => this.generateBlockStatement(node),
|
|
217
|
-
'NamespaceDeclaration': () => this.generateNamespace(node),
|
|
218
|
-
'EmptyStatement': () => '',
|
|
219
|
-
'Comment': () => ''
|
|
452
|
+
generateDeclareStatement(node) {
|
|
453
|
+
const directives = []
|
|
454
|
+
if (node.strictTypes) {
|
|
455
|
+
directives.push('strict_types=1')
|
|
220
456
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return generators[type]()
|
|
457
|
+
if (node.ticks) {
|
|
458
|
+
directives.push(`ticks=${node.ticks}`)
|
|
224
459
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
460
|
+
if (node.encoding) {
|
|
461
|
+
directives.push(`encoding='${node.encoding}'`)
|
|
462
|
+
}
|
|
463
|
+
if (directives.length > 0) {
|
|
464
|
+
this.writeLine(`declare(${directives.join(', ')});`)
|
|
228
465
|
}
|
|
466
|
+
return ''
|
|
467
|
+
}
|
|
229
468
|
|
|
469
|
+
generateNamespace(node) {
|
|
470
|
+
const name = node.name || node.path
|
|
471
|
+
this.writeLine(`namespace ${name};`)
|
|
472
|
+
this.writeLine('')
|
|
230
473
|
return ''
|
|
231
474
|
}
|
|
232
475
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
476
|
+
generateUseStatement(node) {
|
|
477
|
+
const name = node.name || node.source
|
|
478
|
+
const alias = node.alias ? ` as ${node.alias}` : ''
|
|
479
|
+
this.writeLine(`use ${name}${alias};`)
|
|
480
|
+
return ''
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
generateConstantDeclaration(node) {
|
|
484
|
+
const name = node.name || node.id?.name
|
|
485
|
+
const value = this.generateNode(node.value || node.init)
|
|
486
|
+
this.writeLine(`define('${name}', ${value});`)
|
|
487
|
+
return ''
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
generateVariableDeclaration(node) {
|
|
491
|
+
const declarations = node.declarations || [node]
|
|
492
|
+
|
|
493
|
+
for (const decl of declarations) {
|
|
494
|
+
const name = this.generateVariable(decl.id || decl)
|
|
495
|
+
if (decl.init) {
|
|
496
|
+
const init = this.generateNode(decl.init)
|
|
497
|
+
this.writeLine(`${name} = ${init};`)
|
|
498
|
+
}
|
|
236
499
|
}
|
|
500
|
+
return ''
|
|
237
501
|
}
|
|
238
502
|
|
|
239
503
|
generateFunctionDeclaration(node) {
|
|
240
|
-
const name = node.name || node.id?.name || '
|
|
241
|
-
const params =
|
|
242
|
-
|
|
504
|
+
const name = node.name || node.id?.name || ''
|
|
505
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
506
|
+
let returnType = ''
|
|
243
507
|
|
|
508
|
+
if (node.returnType) {
|
|
509
|
+
const type = this.extractTypeName(node.returnType)
|
|
510
|
+
if (type) returnType = ': ' + type
|
|
511
|
+
}
|
|
512
|
+
|
|
244
513
|
this.writeLine(`function ${name}(${params})${returnType} {`)
|
|
245
514
|
this.indent++
|
|
246
|
-
|
|
515
|
+
|
|
516
|
+
if (node.body) {
|
|
517
|
+
this.generateBody(node.body)
|
|
518
|
+
}
|
|
519
|
+
|
|
247
520
|
this.indent--
|
|
248
521
|
this.writeLine('}')
|
|
249
522
|
this.writeLine('')
|
|
523
|
+
return ''
|
|
250
524
|
}
|
|
251
525
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
let result = ''
|
|
255
|
-
|
|
256
|
-
if (p.visibility) {
|
|
257
|
-
result += this.translate(p.visibility) + ' '
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (p.typeHint) {
|
|
261
|
-
result += this.translateType(p.typeHint) + ' '
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (p.variadic) {
|
|
265
|
-
result += '...'
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (p.reference || p.byReference) {
|
|
269
|
-
result += '&'
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const name = p.name || p.id?.name || p
|
|
273
|
-
result += '$' + (typeof name === 'string' ? name : name.name || 'param')
|
|
274
|
-
|
|
275
|
-
if (p.default !== undefined && p.default !== null) {
|
|
276
|
-
result += ' = ' + this.generateNode(p.default)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return result
|
|
280
|
-
}).join(', ')
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
translateType(type) {
|
|
284
|
-
if (!type) return ''
|
|
526
|
+
generateParam(param) {
|
|
527
|
+
let result = ''
|
|
285
528
|
|
|
286
|
-
if (
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
'booléen': 'bool', 'booleen': 'bool', 'boolean': 'bool', 'bool': 'bool',
|
|
293
|
-
'tableau': 'array', 'array': 'array',
|
|
294
|
-
'objet': 'object', 'object': 'object',
|
|
295
|
-
'nul': 'null', 'null': 'null',
|
|
296
|
-
'vide': 'void', 'void': 'void',
|
|
297
|
-
'mixte': 'mixed', 'mixed': 'mixed',
|
|
298
|
-
'appelable': 'callable', 'callable': 'callable',
|
|
299
|
-
'itérable': 'iterable', 'iterable': 'iterable',
|
|
300
|
-
'jamais': 'never', 'never': 'never'
|
|
529
|
+
if (param.typeHint || (param.type && param.type !== 'Parameter' && param.type !== 'Identifier')) {
|
|
530
|
+
const type = param.typeHint || param.type
|
|
531
|
+
if (typeof type === 'string' && type !== 'Parameter' && type !== 'Identifier') {
|
|
532
|
+
result += this.translateKeyword(type) + ' '
|
|
533
|
+
} else if (type && type.name) {
|
|
534
|
+
result += this.translateKeyword(type.name) + ' '
|
|
301
535
|
}
|
|
302
|
-
return typeMap[translated.toLowerCase()] || typeMap[type.toLowerCase()] || type
|
|
303
536
|
}
|
|
304
537
|
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
if (type.union || type.types.length > 1) {
|
|
308
|
-
return prefix + type.types.map(t => this.translateType(t)).join('|')
|
|
309
|
-
}
|
|
310
|
-
return prefix + this.translateType(type.types[0])
|
|
538
|
+
if (param.reference) {
|
|
539
|
+
result += '&'
|
|
311
540
|
}
|
|
312
541
|
|
|
313
|
-
if (
|
|
314
|
-
|
|
542
|
+
if (param.variadic) {
|
|
543
|
+
result += '...'
|
|
315
544
|
}
|
|
316
545
|
|
|
317
|
-
|
|
318
|
-
return type.types.map(t => this.translateType(t)).join('&')
|
|
319
|
-
}
|
|
546
|
+
result += this.generateVariable(param)
|
|
320
547
|
|
|
321
|
-
if (
|
|
322
|
-
|
|
548
|
+
if (param.default !== undefined && param.default !== null) {
|
|
549
|
+
result += ' = ' + this.generateNode(param.default)
|
|
323
550
|
}
|
|
324
551
|
|
|
325
|
-
return
|
|
552
|
+
return result
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
generateBody(body) {
|
|
556
|
+
if (Array.isArray(body)) {
|
|
557
|
+
for (const stmt of body) {
|
|
558
|
+
this.generateNode(stmt)
|
|
559
|
+
}
|
|
560
|
+
} else if (body && body.body) {
|
|
561
|
+
for (const stmt of body.body) {
|
|
562
|
+
this.generateNode(stmt)
|
|
563
|
+
}
|
|
564
|
+
} else if (body) {
|
|
565
|
+
this.generateNode(body)
|
|
566
|
+
}
|
|
326
567
|
}
|
|
327
568
|
|
|
328
569
|
generateClassDeclaration(node) {
|
|
329
570
|
let declaration = ''
|
|
330
571
|
|
|
331
|
-
|
|
332
|
-
if (
|
|
333
|
-
if (
|
|
334
|
-
if (modifiers.includes('readonly') || node.readonly) declaration += 'readonly '
|
|
335
|
-
|
|
336
|
-
declaration += 'class ' + (node.name || node.id?.name)
|
|
572
|
+
if (node.abstract) declaration += 'abstract '
|
|
573
|
+
if (node.final) declaration += 'final '
|
|
574
|
+
if (node.readonly) declaration += 'readonly '
|
|
337
575
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
declaration += ' extends ' + (typeof node.extends === 'string' ? node.extends : node.extends.name)
|
|
576
|
+
declaration += 'class ' + (node.name || node.id?.name || '')
|
|
577
|
+
|
|
578
|
+
if (node.extends || node.superClass) {
|
|
579
|
+
declaration += ' extends ' + (node.extends || node.superClass)
|
|
343
580
|
}
|
|
344
|
-
|
|
345
|
-
if (node.
|
|
346
|
-
declaration += ' implements ' + node.
|
|
347
|
-
} else if (node.implements && node.implements.length > 0) {
|
|
348
|
-
declaration += ' implements ' + node.implements.map(i => typeof i === 'string' ? i : i.name).join(', ')
|
|
581
|
+
|
|
582
|
+
if (node.implements && node.implements.length > 0) {
|
|
583
|
+
declaration += ' implements ' + node.implements.join(', ')
|
|
349
584
|
}
|
|
350
|
-
|
|
585
|
+
|
|
351
586
|
this.writeLine(declaration + ' {')
|
|
352
587
|
this.indent++
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
588
|
+
|
|
589
|
+
const members = node.body?.body || node.members || node.body || []
|
|
590
|
+
for (const member of members) {
|
|
591
|
+
this.generateClassMember(member)
|
|
356
592
|
}
|
|
357
|
-
|
|
593
|
+
|
|
358
594
|
this.indent--
|
|
359
595
|
this.writeLine('}')
|
|
360
596
|
this.writeLine('')
|
|
597
|
+
return ''
|
|
361
598
|
}
|
|
362
599
|
|
|
363
|
-
|
|
364
|
-
|
|
600
|
+
generateClassMember(node) {
|
|
601
|
+
if (!node) return
|
|
602
|
+
|
|
603
|
+
if (node.type === 'UseTraitStatement') {
|
|
604
|
+
this.writeLine(`use ${node.traits.join(', ')};`)
|
|
605
|
+
return
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const visibility = node.visibility || 'public'
|
|
609
|
+
const isStatic = node.static ? 'static ' : ''
|
|
610
|
+
const isReadonly = node.readonly ? 'readonly ' : ''
|
|
365
611
|
|
|
612
|
+
if (node.type === 'Property' || node.kind === 'property' || node.type === 'PropertyDeclaration') {
|
|
613
|
+
const name = '$' + (node.name || node.key?.name || node.id?.name || '')
|
|
614
|
+
let typeHint = ''
|
|
615
|
+
if (node.typeHint) {
|
|
616
|
+
typeHint = this.translateKeyword(node.typeHint) + ' '
|
|
617
|
+
}
|
|
618
|
+
const value = node.value ? ' = ' + this.generateNode(node.value) : ''
|
|
619
|
+
this.writeLine(`${visibility} ${isStatic}${isReadonly}${typeHint}${name}${value};`)
|
|
620
|
+
} else if (node.type === 'Method' || node.kind === 'method' || node.type === 'MethodDeclaration') {
|
|
621
|
+
const name = node.name || node.key?.name || ''
|
|
622
|
+
const translatedName = this.translateKeyword(name)
|
|
623
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
624
|
+
let returnType = ''
|
|
625
|
+
|
|
626
|
+
if (node.returnType) {
|
|
627
|
+
const type = this.extractTypeName(node.returnType)
|
|
628
|
+
if (type) returnType = ': ' + type
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const abstractMod = node.abstract ? 'abstract ' : ''
|
|
632
|
+
|
|
633
|
+
if (node.abstract) {
|
|
634
|
+
this.writeLine(`${abstractMod}${visibility} ${isStatic}function ${translatedName}(${params})${returnType};`)
|
|
635
|
+
} else {
|
|
636
|
+
this.writeLine(`${visibility} ${isStatic}function ${translatedName}(${params})${returnType} {`)
|
|
637
|
+
this.indent++
|
|
638
|
+
|
|
639
|
+
if (node.body) {
|
|
640
|
+
this.generateBody(node.body)
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
this.indent--
|
|
644
|
+
this.writeLine('}')
|
|
645
|
+
}
|
|
646
|
+
this.writeLine('')
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
generateInterfaceDeclaration(node) {
|
|
651
|
+
let declaration = 'interface ' + (node.name || '')
|
|
652
|
+
|
|
366
653
|
if (node.extends && node.extends.length > 0) {
|
|
367
|
-
declaration += ' extends ' + node.extends.
|
|
654
|
+
declaration += ' extends ' + node.extends.join(', ')
|
|
368
655
|
}
|
|
369
|
-
|
|
656
|
+
|
|
370
657
|
this.writeLine(declaration + ' {')
|
|
371
658
|
this.indent++
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
659
|
+
|
|
660
|
+
const members = node.body?.body || node.members || node.body || []
|
|
661
|
+
for (const member of members) {
|
|
662
|
+
this.generateInterfaceMember(member)
|
|
375
663
|
}
|
|
376
|
-
|
|
664
|
+
|
|
377
665
|
this.indent--
|
|
378
666
|
this.writeLine('}')
|
|
379
667
|
this.writeLine('')
|
|
668
|
+
return ''
|
|
380
669
|
}
|
|
381
670
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
671
|
+
generateInterfaceMember(node) {
|
|
672
|
+
if (!node) return
|
|
673
|
+
|
|
674
|
+
const visibility = 'public'
|
|
675
|
+
const name = node.name || node.key?.name || ''
|
|
676
|
+
const translatedName = this.translateKeyword(name)
|
|
677
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
678
|
+
let returnType = ''
|
|
385
679
|
|
|
386
|
-
|
|
387
|
-
this.
|
|
680
|
+
if (node.returnType) {
|
|
681
|
+
const type = this.extractTypeName(node.returnType)
|
|
682
|
+
if (type) returnType = ': ' + type
|
|
388
683
|
}
|
|
389
684
|
|
|
390
|
-
this.
|
|
391
|
-
this.writeLine('}')
|
|
685
|
+
this.writeLine(`${visibility} function ${translatedName}(${params})${returnType};`)
|
|
392
686
|
this.writeLine('')
|
|
393
687
|
}
|
|
394
688
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (node.backingType) {
|
|
399
|
-
declaration += ': ' + this.translateType(node.backingType)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
this.writeLine(declaration + ' {')
|
|
689
|
+
generateTraitDeclaration(node) {
|
|
690
|
+
this.writeLine('trait ' + (node.name || '') + ' {')
|
|
403
691
|
this.indent++
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
} else {
|
|
409
|
-
this.writeLine(`case ${member.name};`)
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
for (const method of node.methods || []) {
|
|
414
|
-
this.generateNode(method)
|
|
692
|
+
|
|
693
|
+
const members = node.body?.body || node.members || node.body || []
|
|
694
|
+
for (const member of members) {
|
|
695
|
+
this.generateClassMember(member)
|
|
415
696
|
}
|
|
416
|
-
|
|
697
|
+
|
|
417
698
|
this.indent--
|
|
418
699
|
this.writeLine('}')
|
|
419
700
|
this.writeLine('')
|
|
701
|
+
return ''
|
|
420
702
|
}
|
|
421
703
|
|
|
422
|
-
|
|
423
|
-
let declaration = ''
|
|
424
|
-
|
|
425
|
-
const visibility = node.visibility || node.access || 'public'
|
|
426
|
-
declaration += this.translate(visibility) + ' '
|
|
427
|
-
|
|
428
|
-
if (node.static) declaration += 'static '
|
|
429
|
-
if (node.final) declaration += 'final '
|
|
430
|
-
if (node.abstract) declaration += 'abstract '
|
|
431
|
-
|
|
432
|
-
const name = this.translateMethodName(node.name || node.key?.name)
|
|
433
|
-
const params = this.generateParams(node.params || node.value?.params || [])
|
|
434
|
-
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
435
|
-
|
|
436
|
-
const body = node.body || node.value?.body
|
|
437
|
-
const hasEmptyBody = !body || (body.type === 'BlockStatement' && (!body.body || body.body.length === 0))
|
|
438
|
-
|
|
439
|
-
if (node.abstract || hasEmptyBody) {
|
|
440
|
-
this.writeLine(`${declaration}function ${name}(${params})${returnType};`)
|
|
441
|
-
} else {
|
|
442
|
-
this.writeLine(`${declaration}function ${name}(${params})${returnType} {`)
|
|
443
|
-
this.indent++
|
|
444
|
-
this.generateNode(body)
|
|
445
|
-
this.indent--
|
|
446
|
-
this.writeLine('}')
|
|
447
|
-
}
|
|
448
|
-
this.writeLine('')
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
translateMethodName(name) {
|
|
452
|
-
if (!name) return 'method'
|
|
704
|
+
generateEnumDeclaration(node) {
|
|
705
|
+
let declaration = 'enum ' + (node.name || '')
|
|
453
706
|
|
|
454
|
-
|
|
455
|
-
'
|
|
456
|
-
'constructor': '__construct',
|
|
457
|
-
'destructeur': '__destruct',
|
|
458
|
-
'destructor': '__destruct',
|
|
459
|
-
'obtenir': '__get',
|
|
460
|
-
'get': '__get',
|
|
461
|
-
'définir': '__set',
|
|
462
|
-
'definir': '__set',
|
|
463
|
-
'set': '__set',
|
|
464
|
-
'appeler': '__call',
|
|
465
|
-
'call': '__call',
|
|
466
|
-
'appeler statique': '__callStatic',
|
|
467
|
-
'call static': '__callStatic',
|
|
468
|
-
'vers chaîne': '__toString',
|
|
469
|
-
'vers chaine': '__toString',
|
|
470
|
-
'to string': '__toString',
|
|
471
|
-
'invoquer': '__invoke',
|
|
472
|
-
'invoke': '__invoke',
|
|
473
|
-
'cloner': '__clone',
|
|
474
|
-
'clone': '__clone',
|
|
475
|
-
'dormir': '__sleep',
|
|
476
|
-
'sleep': '__sleep',
|
|
477
|
-
'réveiller': '__wakeup',
|
|
478
|
-
'reveiller': '__wakeup',
|
|
479
|
-
'wakeup': '__wakeup',
|
|
480
|
-
'sérialiser': '__serialize',
|
|
481
|
-
'serialiser': '__serialize',
|
|
482
|
-
'serialize': '__serialize',
|
|
483
|
-
'désérialiser': '__unserialize',
|
|
484
|
-
'deserialiser': '__unserialize',
|
|
485
|
-
'unserialize': '__unserialize',
|
|
486
|
-
'isset': '__isset',
|
|
487
|
-
'existe propriété': '__isset',
|
|
488
|
-
'existe propriete': '__isset',
|
|
489
|
-
'unset': '__unset',
|
|
490
|
-
'détruire propriété': '__unset',
|
|
491
|
-
'detruire propriete': '__unset',
|
|
492
|
-
'déboguer info': '__debugInfo',
|
|
493
|
-
'deboguer info': '__debugInfo',
|
|
494
|
-
'debug info': '__debugInfo'
|
|
707
|
+
if (node.backingType) {
|
|
708
|
+
declaration += ': ' + this.translateKeyword(node.backingType)
|
|
495
709
|
}
|
|
496
|
-
|
|
497
|
-
const normalized = name.toLowerCase().trim()
|
|
498
|
-
return magicMethods[normalized] || name
|
|
499
|
-
}
|
|
500
710
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const visibility = node.visibility || node.access || 'public'
|
|
505
|
-
declaration += this.translate(visibility) + ' '
|
|
506
|
-
|
|
507
|
-
if (node.static) declaration += 'static '
|
|
508
|
-
if (node.readonly) declaration += 'readonly '
|
|
509
|
-
|
|
510
|
-
if (node.typeHint) {
|
|
511
|
-
declaration += this.translateType(node.typeHint) + ' '
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
const name = node.name || node.key?.name
|
|
515
|
-
declaration += '$' + name
|
|
516
|
-
|
|
517
|
-
if (node.default !== undefined && node.default !== null) {
|
|
518
|
-
declaration += ' = ' + this.generateNode(node.default)
|
|
519
|
-
} else if (node.value !== undefined && node.value !== null) {
|
|
520
|
-
declaration += ' = ' + this.generateNode(node.value)
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
this.writeLine(declaration + ';')
|
|
524
|
-
}
|
|
711
|
+
this.writeLine(declaration + ' {')
|
|
712
|
+
this.indent++
|
|
525
713
|
|
|
526
|
-
|
|
527
|
-
for (const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
if (decl.init !== undefined) {
|
|
532
|
-
const value = this.generateNode(decl.init)
|
|
533
|
-
this.writeLine(`${varName} = ${value};`)
|
|
714
|
+
const cases = node.cases || node.members || []
|
|
715
|
+
for (const caseNode of cases) {
|
|
716
|
+
if (caseNode.value !== undefined) {
|
|
717
|
+
this.writeLine(`case ${caseNode.name} = ${this.generateNode(caseNode.value)};`)
|
|
534
718
|
} else {
|
|
535
|
-
this.writeLine(
|
|
719
|
+
this.writeLine(`case ${caseNode.name};`)
|
|
536
720
|
}
|
|
537
721
|
}
|
|
538
|
-
}
|
|
539
722
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (node.classLevel) {
|
|
545
|
-
const visibility = node.visibility ? this.translate(node.visibility) + ' ' : ''
|
|
546
|
-
this.writeLine(`${visibility}const ${name.toUpperCase()} = ${value};`)
|
|
547
|
-
} else {
|
|
548
|
-
this.writeLine(`define('${name.toUpperCase()}', ${value});`)
|
|
549
|
-
}
|
|
723
|
+
this.indent--
|
|
724
|
+
this.writeLine('}')
|
|
725
|
+
this.writeLine('')
|
|
726
|
+
return ''
|
|
550
727
|
}
|
|
551
728
|
|
|
552
729
|
generateIfStatement(node) {
|
|
553
|
-
const test = this.generateNode(node.test
|
|
730
|
+
const test = this.generateNode(node.test)
|
|
554
731
|
this.writeLine(`if (${test}) {`)
|
|
555
732
|
this.indent++
|
|
556
|
-
this.
|
|
733
|
+
this.generateBody(node.consequent)
|
|
557
734
|
this.indent--
|
|
558
|
-
|
|
735
|
+
|
|
559
736
|
if (node.alternate) {
|
|
560
|
-
if (node.alternate.type === 'IfStatement'
|
|
561
|
-
this.
|
|
562
|
-
this.
|
|
737
|
+
if (node.alternate.type === 'IfStatement') {
|
|
738
|
+
const altTest = this.generateNode(node.alternate.test)
|
|
739
|
+
this.writeLine(`} elseif (${altTest}) {`)
|
|
740
|
+
this.indent++
|
|
741
|
+
this.generateBody(node.alternate.consequent)
|
|
742
|
+
this.indent--
|
|
743
|
+
if (node.alternate.alternate) {
|
|
744
|
+
this.generateElse(node.alternate.alternate)
|
|
745
|
+
} else {
|
|
746
|
+
this.writeLine('}')
|
|
747
|
+
}
|
|
563
748
|
} else {
|
|
564
749
|
this.writeLine('} else {')
|
|
565
750
|
this.indent++
|
|
566
|
-
this.
|
|
751
|
+
this.generateBody(node.alternate)
|
|
567
752
|
this.indent--
|
|
568
753
|
this.writeLine('}')
|
|
569
754
|
}
|
|
570
755
|
} else {
|
|
571
756
|
this.writeLine('}')
|
|
572
757
|
}
|
|
758
|
+
return ''
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
generateElse(node) {
|
|
762
|
+
if (node.type === 'IfStatement') {
|
|
763
|
+
const altTest = this.generateNode(node.test)
|
|
764
|
+
this.writeLine(`} elseif (${altTest}) {`)
|
|
765
|
+
this.indent++
|
|
766
|
+
this.generateBody(node.consequent)
|
|
767
|
+
this.indent--
|
|
768
|
+
if (node.alternate) {
|
|
769
|
+
this.generateElse(node.alternate)
|
|
770
|
+
} else {
|
|
771
|
+
this.writeLine('}')
|
|
772
|
+
}
|
|
773
|
+
} else {
|
|
774
|
+
this.writeLine('} else {')
|
|
775
|
+
this.indent++
|
|
776
|
+
this.generateBody(node)
|
|
777
|
+
this.indent--
|
|
778
|
+
this.writeLine('}')
|
|
779
|
+
}
|
|
573
780
|
}
|
|
574
781
|
|
|
575
782
|
generateForStatement(node) {
|
|
@@ -579,48 +786,43 @@ class PHPGenerator {
|
|
|
579
786
|
|
|
580
787
|
this.writeLine(`for (${init}; ${test}; ${update}) {`)
|
|
581
788
|
this.indent++
|
|
582
|
-
this.
|
|
789
|
+
this.generateBody(node.body)
|
|
583
790
|
this.indent--
|
|
584
791
|
this.writeLine('}')
|
|
792
|
+
return ''
|
|
585
793
|
}
|
|
586
794
|
|
|
587
795
|
generateForEachStatement(node) {
|
|
588
|
-
const array = this.generateNode(node.array || node.right
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
const value = typeof valueNode === 'string'
|
|
592
|
-
? '$' + valueNode
|
|
593
|
-
: this.generateIdentifier(valueNode)
|
|
594
|
-
|
|
595
|
-
let key = ''
|
|
596
|
-
const keyNode = node.key || node.keyVar
|
|
597
|
-
if (keyNode) {
|
|
598
|
-
key = (typeof keyNode === 'string' ? '$' + keyNode : this.generateIdentifier(keyNode)) + ' => '
|
|
599
|
-
}
|
|
796
|
+
const array = this.generateNode(node.array || node.right)
|
|
797
|
+
const value = this.generateVariable(node.value || node.left)
|
|
798
|
+
const key = node.key ? this.generateVariable(node.key) + ' => ' : ''
|
|
600
799
|
|
|
601
800
|
this.writeLine(`foreach (${array} as ${key}${value}) {`)
|
|
602
801
|
this.indent++
|
|
603
|
-
this.
|
|
802
|
+
this.generateBody(node.body)
|
|
604
803
|
this.indent--
|
|
605
804
|
this.writeLine('}')
|
|
805
|
+
return ''
|
|
606
806
|
}
|
|
607
807
|
|
|
608
808
|
generateWhileStatement(node) {
|
|
609
|
-
const test = this.generateNode(node.test
|
|
809
|
+
const test = this.generateNode(node.test)
|
|
610
810
|
this.writeLine(`while (${test}) {`)
|
|
611
811
|
this.indent++
|
|
612
|
-
this.
|
|
812
|
+
this.generateBody(node.body)
|
|
613
813
|
this.indent--
|
|
614
814
|
this.writeLine('}')
|
|
815
|
+
return ''
|
|
615
816
|
}
|
|
616
817
|
|
|
617
818
|
generateDoWhileStatement(node) {
|
|
618
819
|
this.writeLine('do {')
|
|
619
820
|
this.indent++
|
|
620
|
-
this.
|
|
821
|
+
this.generateBody(node.body)
|
|
621
822
|
this.indent--
|
|
622
|
-
const test = this.generateNode(node.test
|
|
823
|
+
const test = this.generateNode(node.test)
|
|
623
824
|
this.writeLine(`} while (${test});`)
|
|
825
|
+
return ''
|
|
624
826
|
}
|
|
625
827
|
|
|
626
828
|
generateSwitchStatement(node) {
|
|
@@ -644,56 +846,35 @@ class PHPGenerator {
|
|
|
644
846
|
|
|
645
847
|
this.indent--
|
|
646
848
|
this.writeLine('}')
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
generateMatchExpression(node) {
|
|
650
|
-
const subject = this.generateNode(node.subject || node.discriminant)
|
|
651
|
-
let result = `match (${subject}) {\n`
|
|
652
|
-
|
|
653
|
-
for (const arm of node.arms || node.cases || []) {
|
|
654
|
-
this.indent++
|
|
655
|
-
if (arm.conditions) {
|
|
656
|
-
const conditions = arm.conditions.map(c => this.generateNode(c)).join(', ')
|
|
657
|
-
result += this.getIndent() + `${conditions} => ${this.generateNode(arm.body)},\n`
|
|
658
|
-
} else if (arm.default) {
|
|
659
|
-
result += this.getIndent() + `default => ${this.generateNode(arm.body)},\n`
|
|
660
|
-
}
|
|
661
|
-
this.indent--
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
result += this.getIndent() + '}'
|
|
665
|
-
return result
|
|
849
|
+
return ''
|
|
666
850
|
}
|
|
667
851
|
|
|
668
852
|
generateTryStatement(node) {
|
|
669
853
|
this.writeLine('try {')
|
|
670
854
|
this.indent++
|
|
671
|
-
this.
|
|
855
|
+
this.generateBody(node.block)
|
|
672
856
|
this.indent--
|
|
673
857
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
const
|
|
677
|
-
? handler.
|
|
678
|
-
: (handler.type || 'Exception')
|
|
679
|
-
const param = handler.param
|
|
680
|
-
? (typeof handler.param === 'string' ? '$' + handler.param : this.generateIdentifier(handler.param))
|
|
858
|
+
if (node.handler) {
|
|
859
|
+
const exceptionType = node.handler.exceptionType || node.handler.type || 'Exception'
|
|
860
|
+
const param = node.handler.param
|
|
861
|
+
? this.generateVariable(node.handler.param)
|
|
681
862
|
: '$e'
|
|
682
|
-
this.writeLine(`} catch (${
|
|
863
|
+
this.writeLine(`} catch (${exceptionType} ${param}) {`)
|
|
683
864
|
this.indent++
|
|
684
|
-
this.
|
|
865
|
+
this.generateBody(node.handler.body)
|
|
685
866
|
this.indent--
|
|
686
867
|
}
|
|
687
868
|
|
|
688
|
-
|
|
689
|
-
if (finallyBlock) {
|
|
869
|
+
if (node.finalizer) {
|
|
690
870
|
this.writeLine('} finally {')
|
|
691
871
|
this.indent++
|
|
692
|
-
this.
|
|
872
|
+
this.generateBody(node.finalizer)
|
|
693
873
|
this.indent--
|
|
694
874
|
}
|
|
695
875
|
|
|
696
876
|
this.writeLine('}')
|
|
877
|
+
return ''
|
|
697
878
|
}
|
|
698
879
|
|
|
699
880
|
generateReturnStatement(node) {
|
|
@@ -703,80 +884,34 @@ class PHPGenerator {
|
|
|
703
884
|
} else {
|
|
704
885
|
this.writeLine('return;')
|
|
705
886
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
generateYieldExpression(node) {
|
|
709
|
-
const arg = node.argument ? this.generateNode(node.argument) : ''
|
|
710
|
-
if (node.delegate) {
|
|
711
|
-
return `yield from ${arg}`
|
|
712
|
-
}
|
|
713
|
-
return `yield ${arg}`
|
|
887
|
+
return ''
|
|
714
888
|
}
|
|
715
889
|
|
|
716
890
|
generateThrowStatement(node) {
|
|
717
891
|
const arg = this.generateNode(node.argument)
|
|
718
892
|
this.writeLine(`throw ${arg};`)
|
|
893
|
+
return ''
|
|
719
894
|
}
|
|
720
895
|
|
|
721
896
|
generateExpressionStatement(node) {
|
|
722
897
|
const expr = this.generateNode(node.expression)
|
|
723
|
-
|
|
898
|
+
if (expr) {
|
|
899
|
+
this.writeLine(`${expr};`)
|
|
900
|
+
}
|
|
901
|
+
return ''
|
|
724
902
|
}
|
|
725
903
|
|
|
726
904
|
generateEchoStatement(node) {
|
|
727
|
-
const
|
|
728
|
-
const args = exprs.filter(Boolean).map(a => this.generateNode(a)).join(', ')
|
|
905
|
+
const args = (node.expressions || node.arguments || [node.argument]).filter(Boolean).map(a => this.generateNode(a)).join(', ')
|
|
729
906
|
this.writeLine(`echo ${args};`)
|
|
907
|
+
return ''
|
|
730
908
|
}
|
|
731
909
|
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
generateNamespace(node) {
|
|
738
|
-
this.writeLine(`namespace ${node.name};`)
|
|
739
|
-
this.writeLine('')
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
generateUseStatement(node) {
|
|
743
|
-
const typePrefix = node.useType === 'function' ? 'function ' : (node.useType === 'const' ? 'const ' : '')
|
|
744
|
-
|
|
745
|
-
if (node.imports && node.imports.length > 0) {
|
|
746
|
-
for (const imp of node.imports) {
|
|
747
|
-
const path = imp.path || imp.name || imp
|
|
748
|
-
const alias = imp.alias ? ' as ' + imp.alias : ''
|
|
749
|
-
this.writeLine(`use ${typePrefix}${path}${alias};`)
|
|
750
|
-
}
|
|
751
|
-
} else {
|
|
752
|
-
const name = node.name || node.source || 'undefined'
|
|
753
|
-
const alias = node.alias ? ' as ' + node.alias : ''
|
|
754
|
-
this.writeLine(`use ${typePrefix}${name}${alias};`)
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
generateDeclareStatement(node) {
|
|
759
|
-
const directives = (node.directives || []).map(d => {
|
|
760
|
-
const value = typeof d.value === 'object' ? this.generateNode(d.value) : d.value
|
|
761
|
-
return `${d.name}=${value}`
|
|
762
|
-
}).join(', ')
|
|
763
|
-
this.writeLine(`declare(${directives});`)
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
generateIncludeStatement(node) {
|
|
767
|
-
const type = node.once
|
|
768
|
-
? (node.required ? 'require_once' : 'include_once')
|
|
769
|
-
: (node.required ? 'require' : 'include')
|
|
770
|
-
const path = typeof node.path === 'string' ? `'${node.path}'` : this.generateNode(node.path)
|
|
771
|
-
this.writeLine(`${type} ${path};`)
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
generateInclude(node) {
|
|
775
|
-
if (node.resolved && node.children) {
|
|
776
|
-
for (const child of node.children) {
|
|
777
|
-
this.generateNode(child)
|
|
778
|
-
}
|
|
910
|
+
generateBlockStatement(node) {
|
|
911
|
+
for (const stmt of node.body || []) {
|
|
912
|
+
this.generateNode(stmt)
|
|
779
913
|
}
|
|
914
|
+
return ''
|
|
780
915
|
}
|
|
781
916
|
|
|
782
917
|
generateCallExpression(node) {
|
|
@@ -784,34 +919,15 @@ class PHPGenerator {
|
|
|
784
919
|
|
|
785
920
|
if (typeof node.callee === 'string') {
|
|
786
921
|
callee = this.translateFunction(node.callee)
|
|
787
|
-
} else if (node.callee.type === 'MemberExpression') {
|
|
788
|
-
callee = this.generateMemberExpression(node.callee)
|
|
789
|
-
} else if (node.callee.type === 'StaticMemberExpression') {
|
|
790
|
-
callee = this.generateStaticMemberExpression(node.callee)
|
|
791
922
|
} else if (node.callee.type === 'Identifier') {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
callee = translated
|
|
796
|
-
} else if (name.includes(' ')) {
|
|
797
|
-
callee = name.replace(/ /g, '_')
|
|
798
|
-
} else {
|
|
799
|
-
callee = name
|
|
800
|
-
}
|
|
923
|
+
callee = this.translateFunction(node.callee.name)
|
|
924
|
+
} else if (node.callee.type === 'MemberExpression' || node.callee.type === 'StaticMemberExpression') {
|
|
925
|
+
callee = this.generateNode(node.callee)
|
|
801
926
|
} else {
|
|
802
927
|
callee = this.generateNode(node.callee)
|
|
803
928
|
}
|
|
804
929
|
|
|
805
|
-
const args = (node.arguments || []).map(a =>
|
|
806
|
-
if (a.spread) {
|
|
807
|
-
return '...' + this.generateNode(a.argument || a)
|
|
808
|
-
}
|
|
809
|
-
if (a.name && a.value) {
|
|
810
|
-
return `${a.name}: ${this.generateNode(a.value)}`
|
|
811
|
-
}
|
|
812
|
-
return this.generateNode(a)
|
|
813
|
-
}).join(', ')
|
|
814
|
-
|
|
930
|
+
const args = (node.arguments || []).map(a => this.generateNode(a)).join(', ')
|
|
815
931
|
return `${callee}(${args})`
|
|
816
932
|
}
|
|
817
933
|
|
|
@@ -822,53 +938,24 @@ class PHPGenerator {
|
|
|
822
938
|
if (typeof node.property === 'string') {
|
|
823
939
|
property = node.property
|
|
824
940
|
} else if (node.property.type === 'Identifier') {
|
|
825
|
-
|
|
826
|
-
let translated = this.translateFunction(propName)
|
|
827
|
-
if (translated.includes('->')) {
|
|
828
|
-
translated = translated.split('->').pop()
|
|
829
|
-
} else if (translated.includes('::')) {
|
|
830
|
-
translated = translated.split('::').pop()
|
|
831
|
-
} else if (translated !== propName && !translated.includes('(')) {
|
|
832
|
-
translated = propName
|
|
833
|
-
}
|
|
834
|
-
property = translated
|
|
941
|
+
property = this.translateFunction(node.property.name)
|
|
835
942
|
} else {
|
|
836
943
|
property = this.generateNode(node.property)
|
|
837
944
|
}
|
|
838
945
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
}
|
|
946
|
+
const operator = node.nullsafe ? '?->' : '->'
|
|
947
|
+
|
|
842
948
|
if (node.computed) {
|
|
843
949
|
return `${object}[${property}]`
|
|
844
950
|
}
|
|
845
|
-
|
|
846
|
-
return `${object}?->${property}`
|
|
847
|
-
}
|
|
848
|
-
return `${object}->${property}`
|
|
951
|
+
return `${object}${operator}${property}`
|
|
849
952
|
}
|
|
850
953
|
|
|
851
954
|
generateStaticMemberExpression(node) {
|
|
852
|
-
const
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
let memberName
|
|
857
|
-
if (typeof memberNode === 'string') {
|
|
858
|
-
memberName = memberNode
|
|
859
|
-
} else if (memberNode.type === 'Identifier') {
|
|
860
|
-
memberName = this.translateMethodName(memberNode.name)
|
|
861
|
-
} else {
|
|
862
|
-
memberName = this.generateNode(memberNode)
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
return `${className}::${memberName}`
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
generateIndexExpression(node) {
|
|
869
|
-
const object = this.generateNode(node.object)
|
|
870
|
-
const index = this.generateNode(node.index)
|
|
871
|
-
return `${object}[${index}]`
|
|
955
|
+
const cls = node.class?.name || this.generateNode(node.class)
|
|
956
|
+
let member = node.member?.name || this.generateNode(node.member)
|
|
957
|
+
member = this.translateKeyword(member)
|
|
958
|
+
return `${cls}::${member}`
|
|
872
959
|
}
|
|
873
960
|
|
|
874
961
|
generateBinaryExpression(node) {
|
|
@@ -877,47 +964,41 @@ class PHPGenerator {
|
|
|
877
964
|
let op = node.operator
|
|
878
965
|
|
|
879
966
|
const opMap = {
|
|
880
|
-
'et': '&&',
|
|
881
|
-
'ou': '||',
|
|
882
|
-
'
|
|
883
|
-
'
|
|
884
|
-
'différent': '!==', 'different': '!==', 'not equal': '!==',
|
|
885
|
-
'concaténer': '.', 'concatener': '.', 'concatenate': '.',
|
|
886
|
-
'vaisseau spatial': '<=>', 'spaceship': '<=>',
|
|
887
|
-
'fusion null': '??', 'null coalescing': '??'
|
|
967
|
+
'et': '&&',
|
|
968
|
+
'ou': '||',
|
|
969
|
+
'concatener': '.',
|
|
970
|
+
'concat': '.'
|
|
888
971
|
}
|
|
889
|
-
|
|
890
|
-
|
|
972
|
+
op = opMap[this.normalizeAccents(op)] || op
|
|
973
|
+
|
|
974
|
+
return `${left} ${op} ${right}`
|
|
975
|
+
}
|
|
891
976
|
|
|
892
|
-
|
|
893
|
-
|
|
977
|
+
generateAssignmentExpression(node) {
|
|
978
|
+
const left = this.generateNode(node.left)
|
|
979
|
+
const right = this.generateNode(node.right)
|
|
980
|
+
const op = node.operator || '='
|
|
981
|
+
return `${left} ${op} ${right}`
|
|
894
982
|
}
|
|
895
983
|
|
|
896
984
|
generateUnaryExpression(node) {
|
|
897
|
-
const
|
|
898
|
-
const op = node.operator === 'non'
|
|
985
|
+
const operand = this.generateNode(node.operand || node.argument)
|
|
986
|
+
const op = node.operator === 'non' ? '!' : node.operator
|
|
899
987
|
|
|
900
988
|
if (node.prefix !== false) {
|
|
901
|
-
return `${op}${
|
|
989
|
+
return `${op}${operand}`
|
|
902
990
|
}
|
|
903
|
-
return `${
|
|
991
|
+
return `${operand}${op}`
|
|
904
992
|
}
|
|
905
993
|
|
|
906
994
|
generateUpdateExpression(node) {
|
|
907
|
-
const
|
|
995
|
+
const operand = this.generateNode(node.operand || node.argument)
|
|
908
996
|
const op = node.operator
|
|
909
997
|
|
|
910
998
|
if (node.prefix) {
|
|
911
|
-
return `${op}${
|
|
999
|
+
return `${op}${operand}`
|
|
912
1000
|
}
|
|
913
|
-
return `${
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
generateAssignmentExpression(node) {
|
|
917
|
-
const left = this.generateNode(node.left)
|
|
918
|
-
const right = this.generateNode(node.right)
|
|
919
|
-
const op = node.operator || '='
|
|
920
|
-
return `${left} ${op} ${right}`
|
|
1001
|
+
return `${operand}${op}`
|
|
921
1002
|
}
|
|
922
1003
|
|
|
923
1004
|
generateConditionalExpression(node) {
|
|
@@ -927,31 +1008,24 @@ class PHPGenerator {
|
|
|
927
1008
|
return `${test} ? ${consequent} : ${alternate}`
|
|
928
1009
|
}
|
|
929
1010
|
|
|
930
|
-
generateNullCoalescing(node) {
|
|
931
|
-
const left = this.generateNode(node.left)
|
|
932
|
-
const right = this.generateNode(node.right)
|
|
933
|
-
return `${left} ?? ${right}`
|
|
934
|
-
}
|
|
935
|
-
|
|
936
1011
|
generateArrayExpression(node) {
|
|
937
1012
|
const elements = (node.elements || []).map(e => {
|
|
938
|
-
if (!e) return 'null'
|
|
939
1013
|
if (e.type === 'ArrayElement') {
|
|
940
|
-
if (e.key
|
|
1014
|
+
if (e.key) {
|
|
941
1015
|
const key = this.generateNode(e.key)
|
|
942
1016
|
const value = this.generateNode(e.value)
|
|
943
1017
|
return `${key} => ${value}`
|
|
944
1018
|
}
|
|
945
1019
|
return this.generateNode(e.value)
|
|
946
1020
|
}
|
|
947
|
-
if (e.
|
|
1021
|
+
if (e.type === 'SpreadElement') {
|
|
1022
|
+
return '...' + this.generateNode(e.argument)
|
|
1023
|
+
}
|
|
1024
|
+
if (e.key) {
|
|
948
1025
|
const key = this.generateNode(e.key)
|
|
949
1026
|
const value = this.generateNode(e.value || e)
|
|
950
1027
|
return `${key} => ${value}`
|
|
951
1028
|
}
|
|
952
|
-
if (e.spread) {
|
|
953
|
-
return '...' + this.generateNode(e.argument || e)
|
|
954
|
-
}
|
|
955
1029
|
return this.generateNode(e)
|
|
956
1030
|
})
|
|
957
1031
|
|
|
@@ -966,112 +1040,44 @@ class PHPGenerator {
|
|
|
966
1040
|
return this.generateArrayExpression(node)
|
|
967
1041
|
}
|
|
968
1042
|
|
|
969
|
-
|
|
970
|
-
const
|
|
971
|
-
|
|
972
|
-
return `fn(${params}) => ${body}`
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
generateFunctionExpression(node) {
|
|
976
|
-
const params = this.generateParams(node.params || [])
|
|
977
|
-
const uses = node.uses || node.use || []
|
|
978
|
-
const useVars = uses.length > 0
|
|
979
|
-
? ` use (${uses.map(u => (u.byReference || u.byRef ? '&' : '') + '$' + (u.name || u)).join(', ')})`
|
|
980
|
-
: ''
|
|
981
|
-
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
982
|
-
|
|
983
|
-
let result = `function(${params})${useVars}${returnType} {\n`
|
|
1043
|
+
generateIdentifier(node) {
|
|
1044
|
+
const name = node.name || node
|
|
1045
|
+
if (typeof name !== 'string') return '$var'
|
|
984
1046
|
|
|
985
|
-
const
|
|
986
|
-
const savedIndent = this.indent
|
|
987
|
-
this.output = ''
|
|
988
|
-
this.indent++
|
|
1047
|
+
const normalized = this.normalizeAccents(name)
|
|
989
1048
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
for (const stmt of body.body) {
|
|
993
|
-
this.generateNode(stmt)
|
|
994
|
-
}
|
|
995
|
-
} else if (body) {
|
|
996
|
-
this.writeLine('return ' + this.generateNode(body) + ';')
|
|
1049
|
+
if (this.functionMap[normalized]) {
|
|
1050
|
+
return this.functionMap[normalized]
|
|
997
1051
|
}
|
|
998
1052
|
|
|
999
|
-
const
|
|
1000
|
-
this.output = savedOutput
|
|
1001
|
-
this.indent = savedIndent
|
|
1002
|
-
|
|
1003
|
-
result += bodyOutput
|
|
1004
|
-
result += this.getIndent() + '}'
|
|
1005
|
-
return result
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
generateClosure(node) {
|
|
1009
|
-
const params = this.generateParams(node.params || [])
|
|
1010
|
-
const useVars = node.use && node.use.length > 0
|
|
1011
|
-
? ` use (${node.use.map(u => (u.byRef ? '&' : '') + '$' + this.translate(u.name || u)).join(', ')})`
|
|
1012
|
-
: ''
|
|
1013
|
-
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
1014
|
-
|
|
1015
|
-
let result = `function(${params})${useVars}${returnType} {\n`
|
|
1016
|
-
this.indent++
|
|
1053
|
+
const translated = this.translateKeyword(name)
|
|
1017
1054
|
|
|
1018
|
-
if (
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1055
|
+
if (translated.startsWith('$')) return translated
|
|
1056
|
+
if (['true', 'false', 'null', 'self', 'parent', 'static'].includes(translated)) {
|
|
1057
|
+
return translated
|
|
1058
|
+
}
|
|
1059
|
+
if (/^[A-Z]/.test(translated)) return translated
|
|
1060
|
+
if (translated === name && !name.startsWith('$')) {
|
|
1061
|
+
return '$' + name
|
|
1024
1062
|
}
|
|
1025
1063
|
|
|
1026
|
-
|
|
1027
|
-
result += this.getIndent() + '}'
|
|
1028
|
-
return result
|
|
1064
|
+
return translated.startsWith('$') ? translated : '$' + translated
|
|
1029
1065
|
}
|
|
1030
1066
|
|
|
1031
|
-
|
|
1067
|
+
generateVariable(node) {
|
|
1068
|
+
if (!node) return '$var'
|
|
1069
|
+
|
|
1032
1070
|
const name = node.name || node.id?.name || node
|
|
1033
1071
|
if (typeof name !== 'string') return '$var'
|
|
1034
1072
|
|
|
1035
|
-
const keywords = [
|
|
1036
|
-
'true', 'false', 'null',
|
|
1037
|
-
'self', 'parent', 'static',
|
|
1038
|
-
'this', '$this', 'vrai', 'faux', 'nul', 'ceci'
|
|
1039
|
-
]
|
|
1040
|
-
const lowerName = name.toLowerCase()
|
|
1041
|
-
|
|
1042
|
-
if (lowerName === 'vrai') return 'true'
|
|
1043
|
-
if (lowerName === 'faux') return 'false'
|
|
1044
|
-
if (lowerName === 'nul') return 'null'
|
|
1045
|
-
if (lowerName === 'ceci' || lowerName === 'this') return '$this'
|
|
1046
|
-
|
|
1047
|
-
if (keywords.includes(lowerName)) {
|
|
1048
|
-
return name
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
1073
|
if (name.startsWith('$')) return name
|
|
1052
|
-
|
|
1053
|
-
if (/^[A-Z]/.test(name)) return name
|
|
1054
|
-
|
|
1055
|
-
if (name.includes('(') || name.includes('::') || name.includes('->')) return name
|
|
1056
|
-
|
|
1057
|
-
const superglobals = ['_GET', '_POST', '_SERVER', '_SESSION', '_COOKIE', '_FILES', '_REQUEST', '_ENV', 'GLOBALS']
|
|
1058
|
-
if (superglobals.includes(name) || superglobals.includes(name.toUpperCase())) {
|
|
1059
|
-
return '$' + name.toUpperCase()
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
1074
|
return '$' + name
|
|
1063
1075
|
}
|
|
1064
1076
|
|
|
1065
1077
|
generateLiteral(node) {
|
|
1066
|
-
if (node.raw
|
|
1078
|
+
if (node.raw) return node.raw
|
|
1067
1079
|
if (typeof node.value === 'string') {
|
|
1068
|
-
|
|
1069
|
-
.replace(/\\/g, '\\\\')
|
|
1070
|
-
.replace(/"/g, '\\"')
|
|
1071
|
-
.replace(/\n/g, '\\n')
|
|
1072
|
-
.replace(/\r/g, '\\r')
|
|
1073
|
-
.replace(/\t/g, '\\t')
|
|
1074
|
-
return `"${escaped}"`
|
|
1080
|
+
return `"${node.value.replace(/"/g, '\\"')}"`
|
|
1075
1081
|
}
|
|
1076
1082
|
if (node.value === null) return 'null'
|
|
1077
1083
|
if (node.value === true) return 'true'
|
|
@@ -1079,28 +1085,83 @@ class PHPGenerator {
|
|
|
1079
1085
|
return String(node.value)
|
|
1080
1086
|
}
|
|
1081
1087
|
|
|
1088
|
+
generateStringLiteral(node) {
|
|
1089
|
+
const quote = node.doubleQuoted ? '"' : "'"
|
|
1090
|
+
const value = node.value.replace(new RegExp(quote, 'g'), '\\' + quote)
|
|
1091
|
+
return `${quote}${value}${quote}`
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1082
1094
|
generateNewExpression(node) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1095
|
+
let callee
|
|
1096
|
+
if (typeof node.callee === 'string') {
|
|
1097
|
+
callee = node.callee
|
|
1098
|
+
} else if (node.callee.type === 'Identifier') {
|
|
1099
|
+
callee = node.callee.name
|
|
1100
|
+
} else {
|
|
1101
|
+
callee = this.generateNode(node.callee)
|
|
1102
|
+
}
|
|
1086
1103
|
const args = (node.arguments || []).map(a => this.generateNode(a)).join(', ')
|
|
1087
1104
|
return `new ${callee}(${args})`
|
|
1088
1105
|
}
|
|
1089
1106
|
|
|
1090
|
-
|
|
1107
|
+
generateFunctionExpression(node) {
|
|
1108
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
1109
|
+
|
|
1110
|
+
let uses = ''
|
|
1111
|
+
if (node.uses && node.uses.length > 0) {
|
|
1112
|
+
const useVars = node.uses.map(u => {
|
|
1113
|
+
const ref = u.byRef ? '&' : ''
|
|
1114
|
+
return ref + this.generateVariable(u)
|
|
1115
|
+
}).join(', ')
|
|
1116
|
+
uses = ` use (${useVars})`
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
let returnType = ''
|
|
1120
|
+
if (node.returnType) {
|
|
1121
|
+
returnType = ': ' + this.translateKeyword(node.returnType)
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
let body = ''
|
|
1125
|
+
if (node.body) {
|
|
1126
|
+
const savedOutput = this.output
|
|
1127
|
+
const savedIndent = this.indent
|
|
1128
|
+
this.output = ''
|
|
1129
|
+
this.indent = 0
|
|
1130
|
+
this.generateBody(node.body)
|
|
1131
|
+
body = this.output
|
|
1132
|
+
this.output = savedOutput
|
|
1133
|
+
this.indent = savedIndent
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
return `function(${params})${uses}${returnType} {\n${body}}`
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
generateArrowFunctionExpression(node) {
|
|
1140
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
1141
|
+
const body = this.generateNode(node.body)
|
|
1142
|
+
return `fn(${params}) => ${body}`
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
generateIndexExpression(node) {
|
|
1146
|
+
const object = this.generateNode(node.object)
|
|
1147
|
+
const index = node.index ? this.generateNode(node.index) : ''
|
|
1148
|
+
return `${object}[${index}]`
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
generateNullCoalesceExpression(node) {
|
|
1091
1152
|
const left = this.generateNode(node.left)
|
|
1092
1153
|
const right = this.generateNode(node.right)
|
|
1093
|
-
return `${left}
|
|
1154
|
+
return `${left} ?? ${right}`
|
|
1094
1155
|
}
|
|
1095
1156
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
this.generateNode(
|
|
1157
|
+
generateYieldExpression(node) {
|
|
1158
|
+
if (node.delegate) {
|
|
1159
|
+
return `yield from ${this.generateNode(node.argument)}`
|
|
1099
1160
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1161
|
+
if (node.argument) {
|
|
1162
|
+
return `yield ${this.generateNode(node.argument)}`
|
|
1163
|
+
}
|
|
1164
|
+
return 'yield'
|
|
1104
1165
|
}
|
|
1105
1166
|
|
|
1106
1167
|
writeLine(text) {
|
|
@@ -1112,4 +1173,6 @@ class PHPGenerator {
|
|
|
1112
1173
|
}
|
|
1113
1174
|
}
|
|
1114
1175
|
|
|
1115
|
-
module.exports = {
|
|
1176
|
+
module.exports = {
|
|
1177
|
+
PHPGenerator
|
|
1178
|
+
}
|