ether-code 0.9.4 → 0.9.5
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 +155 -24
- package/package.json +1 -1
- package/parsers/ether-parser-php.js +0 -1
package/cli/ether.js
CHANGED
|
@@ -134,7 +134,6 @@ class PHPGenerator {
|
|
|
134
134
|
'formater nombre': 'number_format',
|
|
135
135
|
'date': 'date',
|
|
136
136
|
'temps': 'time',
|
|
137
|
-
'maintenant': 'time',
|
|
138
137
|
'creer date': 'mktime',
|
|
139
138
|
'date vers temps': 'strtotime',
|
|
140
139
|
'formater date': 'date_format',
|
|
@@ -305,6 +304,25 @@ class PHPGenerator {
|
|
|
305
304
|
return this.keywordMap[normalized] || word
|
|
306
305
|
}
|
|
307
306
|
|
|
307
|
+
translateMethodName(word) {
|
|
308
|
+
if (!word) return word
|
|
309
|
+
const normalized = this.normalizeAccents(word)
|
|
310
|
+
const magicMethods = {
|
|
311
|
+
'constructeur': '__construct',
|
|
312
|
+
'destructeur': '__destruct',
|
|
313
|
+
'obtenir': '__get',
|
|
314
|
+
'definir': '__set',
|
|
315
|
+
'appeler': '__call',
|
|
316
|
+
'vers chaine': '__toString',
|
|
317
|
+
'invoquer': '__invoke',
|
|
318
|
+
'cloner': '__clone',
|
|
319
|
+
'serialiser': '__serialize',
|
|
320
|
+
'deserialiser': '__unserialize',
|
|
321
|
+
'deboguer': '__debugInfo'
|
|
322
|
+
}
|
|
323
|
+
return magicMethods[normalized] || word
|
|
324
|
+
}
|
|
325
|
+
|
|
308
326
|
extractTypeName(typeNode) {
|
|
309
327
|
if (!typeNode) return ''
|
|
310
328
|
if (typeof typeNode === 'string') return this.translateKeyword(typeNode)
|
|
@@ -322,6 +340,9 @@ class PHPGenerator {
|
|
|
322
340
|
generate(ast) {
|
|
323
341
|
this.output = ''
|
|
324
342
|
this.indent = 0
|
|
343
|
+
this.closureVariables = new Set()
|
|
344
|
+
|
|
345
|
+
this.collectClosureVariables(ast)
|
|
325
346
|
|
|
326
347
|
if (ast.phpTag !== false) {
|
|
327
348
|
this.output = '<?php\n'
|
|
@@ -346,6 +367,32 @@ class PHPGenerator {
|
|
|
346
367
|
return this.output.trim()
|
|
347
368
|
}
|
|
348
369
|
|
|
370
|
+
collectClosureVariables(ast) {
|
|
371
|
+
const nodes = Array.isArray(ast) ? ast : (ast?.body || [ast])
|
|
372
|
+
|
|
373
|
+
for (const node of nodes) {
|
|
374
|
+
if (!node) continue
|
|
375
|
+
|
|
376
|
+
if (node.type === 'VariableDeclaration') {
|
|
377
|
+
const init = node.init || node.value
|
|
378
|
+
if (init && (init.type === 'ArrowFunctionExpression' || init.type === 'FunctionExpression' || init.type === 'ClosureExpression')) {
|
|
379
|
+
const name = node.name || node.id?.name
|
|
380
|
+
if (name) this.closureVariables.add(name)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (node.body) {
|
|
385
|
+
this.collectClosureVariables(node.body)
|
|
386
|
+
}
|
|
387
|
+
if (node.consequent) {
|
|
388
|
+
this.collectClosureVariables(Array.isArray(node.consequent) ? node.consequent : [node.consequent])
|
|
389
|
+
}
|
|
390
|
+
if (node.alternate) {
|
|
391
|
+
this.collectClosureVariables(Array.isArray(node.alternate) ? node.alternate : [node.alternate])
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
349
396
|
generateNode(node) {
|
|
350
397
|
if (!node) return ''
|
|
351
398
|
|
|
@@ -381,6 +428,8 @@ class PHPGenerator {
|
|
|
381
428
|
return this.generateForStatement(node)
|
|
382
429
|
case 'ForEachStatement':
|
|
383
430
|
return this.generateForEachStatement(node)
|
|
431
|
+
case 'ForeachStatement':
|
|
432
|
+
return this.generateForEachStatement(node)
|
|
384
433
|
case 'WhileStatement':
|
|
385
434
|
return this.generateWhileStatement(node)
|
|
386
435
|
case 'DoWhileStatement':
|
|
@@ -634,7 +683,7 @@ class PHPGenerator {
|
|
|
634
683
|
this.writeLine(`${visibility} ${isStatic}${isReadonly}${typeHint}${name}${value};`)
|
|
635
684
|
} else if (node.type === 'Method' || node.kind === 'method' || node.type === 'MethodDeclaration') {
|
|
636
685
|
const name = node.name || node.key?.name || ''
|
|
637
|
-
const translatedName = this.
|
|
686
|
+
const translatedName = this.translateMethodName(name)
|
|
638
687
|
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
639
688
|
let returnType = ''
|
|
640
689
|
|
|
@@ -688,7 +737,7 @@ class PHPGenerator {
|
|
|
688
737
|
|
|
689
738
|
const visibility = 'public'
|
|
690
739
|
const name = node.name || node.key?.name || ''
|
|
691
|
-
const translatedName = this.
|
|
740
|
+
const translatedName = this.translateMethodName(name)
|
|
692
741
|
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
693
742
|
let returnType = ''
|
|
694
743
|
|
|
@@ -871,21 +920,26 @@ class PHPGenerator {
|
|
|
871
920
|
this.generateBody(node.block)
|
|
872
921
|
this.indent--
|
|
873
922
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
const
|
|
877
|
-
|
|
923
|
+
const catches = node.catches || (node.handler ? [node.handler] : [])
|
|
924
|
+
for (const catchClause of catches) {
|
|
925
|
+
const types = catchClause.types || []
|
|
926
|
+
const exceptionType = types.length > 0
|
|
927
|
+
? types.join('|')
|
|
928
|
+
: (catchClause.exceptionType || catchClause.type || 'Exception')
|
|
929
|
+
const param = catchClause.param
|
|
930
|
+
? this.generateVariable(catchClause.param)
|
|
878
931
|
: '$e'
|
|
879
932
|
this.writeLine(`} catch (${exceptionType} ${param}) {`)
|
|
880
933
|
this.indent++
|
|
881
|
-
this.generateBody(
|
|
934
|
+
this.generateBody(catchClause.body)
|
|
882
935
|
this.indent--
|
|
883
936
|
}
|
|
884
937
|
|
|
885
|
-
|
|
938
|
+
const finallyBlock = node.finally || node.finalizer
|
|
939
|
+
if (finallyBlock) {
|
|
886
940
|
this.writeLine('} finally {')
|
|
887
941
|
this.indent++
|
|
888
|
-
this.generateBody(
|
|
942
|
+
this.generateBody(finallyBlock)
|
|
889
943
|
this.indent--
|
|
890
944
|
}
|
|
891
945
|
|
|
@@ -932,19 +986,82 @@ class PHPGenerator {
|
|
|
932
986
|
|
|
933
987
|
generateCallExpression(node) {
|
|
934
988
|
let callee
|
|
989
|
+
let originalName = ''
|
|
935
990
|
|
|
936
991
|
if (typeof node.callee === 'string') {
|
|
937
|
-
|
|
992
|
+
originalName = node.callee
|
|
993
|
+
if (this.closureVariables && this.closureVariables.has(node.callee)) {
|
|
994
|
+
callee = '$' + node.callee
|
|
995
|
+
} else {
|
|
996
|
+
callee = this.translateFunction(node.callee)
|
|
997
|
+
}
|
|
938
998
|
} else if (node.callee.type === 'Identifier') {
|
|
939
|
-
|
|
999
|
+
originalName = node.callee.name
|
|
1000
|
+
if (this.closureVariables && this.closureVariables.has(node.callee.name)) {
|
|
1001
|
+
callee = '$' + node.callee.name
|
|
1002
|
+
} else {
|
|
1003
|
+
callee = this.translateFunction(node.callee.name)
|
|
1004
|
+
}
|
|
1005
|
+
} else if (node.callee.type === 'Variable') {
|
|
1006
|
+
callee = this.generateVariable(node.callee)
|
|
940
1007
|
} else if (node.callee.type === 'MemberExpression' || node.callee.type === 'StaticMemberExpression') {
|
|
941
1008
|
callee = this.generateNode(node.callee)
|
|
942
1009
|
} else {
|
|
943
1010
|
callee = this.generateNode(node.callee)
|
|
944
1011
|
}
|
|
945
1012
|
|
|
946
|
-
|
|
947
|
-
|
|
1013
|
+
let args = (node.arguments || []).map(a => this.generateNode(a))
|
|
1014
|
+
|
|
1015
|
+
args = this.reorderArguments(callee, args, originalName)
|
|
1016
|
+
args = this.addDefaultArguments(callee, args)
|
|
1017
|
+
|
|
1018
|
+
return `${callee}(${args.join(', ')})`
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
reorderArguments(func, args, originalName) {
|
|
1022
|
+
const normalized = this.normalizeAccents(originalName)
|
|
1023
|
+
|
|
1024
|
+
if ((func === 'str_replace' || normalized === 'remplacer') && args.length === 3) {
|
|
1025
|
+
return [args[1], args[2], args[0]]
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if ((func === 'array_map' || normalized === 'mapper' || normalized === 'mapper tableau' || normalized === 'transformer') && args.length === 2) {
|
|
1029
|
+
return [args[1], args[0]]
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return args
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
addDefaultArguments(func, args) {
|
|
1036
|
+
if (func === 'password_hash' && args.length === 1) {
|
|
1037
|
+
return [...args, 'PASSWORD_DEFAULT']
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
return args
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
isNativeFunction(name) {
|
|
1044
|
+
const natives = [
|
|
1045
|
+
'echo', 'print', 'var_dump', 'print_r', 'die', 'exit',
|
|
1046
|
+
'strlen', 'substr', 'strpos', 'str_replace', 'strtoupper', 'strtolower',
|
|
1047
|
+
'trim', 'ltrim', 'rtrim', 'explode', 'implode', 'sprintf', 'printf',
|
|
1048
|
+
'count', 'array_push', 'array_pop', 'array_shift', 'array_unshift',
|
|
1049
|
+
'array_merge', 'array_filter', 'array_map', 'array_reduce', 'array_keys',
|
|
1050
|
+
'array_values', 'array_sum', 'array_unique', 'array_reverse', 'sort',
|
|
1051
|
+
'in_array', 'array_key_exists', 'array_search',
|
|
1052
|
+
'is_array', 'is_string', 'is_int', 'is_float', 'is_bool', 'is_null',
|
|
1053
|
+
'is_numeric', 'is_object', 'is_callable', 'isset', 'empty', 'gettype',
|
|
1054
|
+
'intval', 'floatval', 'strval', 'boolval', 'settype',
|
|
1055
|
+
'abs', 'ceil', 'floor', 'round', 'sqrt', 'pow', 'rand', 'max', 'min', 'pi',
|
|
1056
|
+
'date', 'time', 'strtotime', 'mktime',
|
|
1057
|
+
'file_exists', 'file_get_contents', 'file_put_contents', 'fopen', 'fclose', 'fread', 'fwrite',
|
|
1058
|
+
'json_encode', 'json_decode', 'preg_match', 'preg_match_all', 'preg_replace',
|
|
1059
|
+
'header', 'session_start', 'session_destroy', 'password_hash', 'password_verify',
|
|
1060
|
+
'include', 'include_once', 'require', 'require_once',
|
|
1061
|
+
'class_exists', 'function_exists', 'method_exists', 'defined', 'define', 'constant',
|
|
1062
|
+
'new', 'throw'
|
|
1063
|
+
]
|
|
1064
|
+
return natives.includes(name)
|
|
948
1065
|
}
|
|
949
1066
|
|
|
950
1067
|
generateMemberExpression(node) {
|
|
@@ -952,9 +1069,9 @@ class PHPGenerator {
|
|
|
952
1069
|
let property
|
|
953
1070
|
|
|
954
1071
|
if (typeof node.property === 'string') {
|
|
955
|
-
property = node.property
|
|
1072
|
+
property = this.translateMemberProperty(node.property)
|
|
956
1073
|
} else if (node.property.type === 'Identifier') {
|
|
957
|
-
property = this.
|
|
1074
|
+
property = this.translateMemberProperty(node.property.name)
|
|
958
1075
|
} else {
|
|
959
1076
|
property = this.generateNode(node.property)
|
|
960
1077
|
}
|
|
@@ -967,6 +1084,26 @@ class PHPGenerator {
|
|
|
967
1084
|
return `${object}${operator}${property}`
|
|
968
1085
|
}
|
|
969
1086
|
|
|
1087
|
+
translateMemberProperty(name) {
|
|
1088
|
+
const translations = {
|
|
1089
|
+
'valeur': 'value',
|
|
1090
|
+
'nom': 'name',
|
|
1091
|
+
'message': 'message',
|
|
1092
|
+
'code': 'code',
|
|
1093
|
+
'fichier': 'file',
|
|
1094
|
+
'ligne': 'line',
|
|
1095
|
+
'precedent': 'previous',
|
|
1096
|
+
'trace': 'trace',
|
|
1097
|
+
'formater': 'format',
|
|
1098
|
+
'ajouter': 'add',
|
|
1099
|
+
'modifier': 'modify',
|
|
1100
|
+
'obtenir': 'get',
|
|
1101
|
+
'definir': 'set'
|
|
1102
|
+
}
|
|
1103
|
+
const normalized = this.normalizeAccents(name)
|
|
1104
|
+
return translations[normalized] || name
|
|
1105
|
+
}
|
|
1106
|
+
|
|
970
1107
|
generateStaticMemberExpression(node) {
|
|
971
1108
|
const cls = node.class?.name || this.generateNode(node.class)
|
|
972
1109
|
let member = node.member?.name || this.generateNode(node.member)
|
|
@@ -1060,12 +1197,6 @@ class PHPGenerator {
|
|
|
1060
1197
|
const name = node.name || node
|
|
1061
1198
|
if (typeof name !== 'string') return '$var'
|
|
1062
1199
|
|
|
1063
|
-
const normalized = this.normalizeAccents(name)
|
|
1064
|
-
|
|
1065
|
-
if (this.functionMap[normalized]) {
|
|
1066
|
-
return this.functionMap[normalized]
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
1200
|
const translated = this.translateKeyword(name)
|
|
1070
1201
|
|
|
1071
1202
|
if (translated.startsWith('$')) return translated
|
|
@@ -1073,11 +1204,11 @@ class PHPGenerator {
|
|
|
1073
1204
|
return translated
|
|
1074
1205
|
}
|
|
1075
1206
|
if (/^[A-Z]/.test(translated)) return translated
|
|
1076
|
-
if (
|
|
1207
|
+
if (!name.startsWith('$')) {
|
|
1077
1208
|
return '$' + name
|
|
1078
1209
|
}
|
|
1079
1210
|
|
|
1080
|
-
return
|
|
1211
|
+
return name
|
|
1081
1212
|
}
|
|
1082
1213
|
|
|
1083
1214
|
generateVariable(node) {
|
package/package.json
CHANGED
|
@@ -159,7 +159,6 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
159
159
|
'json decoder': 'json_decode',
|
|
160
160
|
'date': 'date',
|
|
161
161
|
'temps': 'time',
|
|
162
|
-
'maintenant': 'time',
|
|
163
162
|
'demarrer session': 'session_start',
|
|
164
163
|
'detruire session': 'session_destroy',
|
|
165
164
|
'definir cookie': 'setcookie',
|