ether-code 0.8.1 → 0.8.3
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 +154 -60
- package/package.json +1 -1
- package/parsers/ether-parser-php.js +19 -13
- package/parsers/ether-parser.js +15 -5
package/cli/ether.js
CHANGED
|
@@ -46,7 +46,8 @@ class PHPGenerator {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
translate(word) {
|
|
49
|
-
if (!word
|
|
49
|
+
if (!word) return word
|
|
50
|
+
if (typeof word !== 'string') return String(word)
|
|
50
51
|
|
|
51
52
|
const normalized = word.toLowerCase().trim()
|
|
52
53
|
|
|
@@ -63,6 +64,7 @@ class PHPGenerator {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
removeAccents(str) {
|
|
67
|
+
if (typeof str !== 'string') return String(str)
|
|
66
68
|
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -140,12 +142,19 @@ class PHPGenerator {
|
|
|
140
142
|
'ArrayExpression': () => this.generateArrayExpression(node),
|
|
141
143
|
'ObjectExpression': () => this.generateObjectExpression(node),
|
|
142
144
|
'ArrowFunction': () => this.generateArrowFunction(node),
|
|
145
|
+
'ArrowFunctionExpression': () => this.generateArrowFunction(node),
|
|
143
146
|
'Closure': () => this.generateClosure(node),
|
|
147
|
+
'FunctionExpression': () => this.generateClosure(node),
|
|
144
148
|
'Identifier': () => this.generateIdentifier(node),
|
|
149
|
+
'Variable': () => this.generateVariable(node),
|
|
145
150
|
'Literal': () => this.generateLiteral(node),
|
|
151
|
+
'StringLiteral': () => this.generateStringLiteral(node),
|
|
146
152
|
'NewExpression': () => this.generateNewExpression(node),
|
|
147
153
|
'InstanceOf': () => this.generateInstanceOf(node),
|
|
148
154
|
'BlockStatement': () => this.generateBlockStatement(node),
|
|
155
|
+
'ThisExpression': () => '$this',
|
|
156
|
+
'StaticMemberExpression': () => this.generateStaticMemberExpression(node),
|
|
157
|
+
'IndexExpression': () => this.generateIndexExpression(node),
|
|
149
158
|
'EmptyStatement': () => '',
|
|
150
159
|
'Comment': () => ''
|
|
151
160
|
}
|
|
@@ -168,11 +177,12 @@ class PHPGenerator {
|
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
generateFunctionDeclaration(node) {
|
|
171
|
-
const name = this.
|
|
180
|
+
const name = this.safeString(node.name || node.id?.name || 'anonymous')
|
|
181
|
+
const translatedName = this.translate(name)
|
|
172
182
|
const params = this.generateParams(node.params || [])
|
|
173
183
|
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
174
184
|
|
|
175
|
-
this.writeLine(`function ${
|
|
185
|
+
this.writeLine(`function ${translatedName}(${params})${returnType} {`)
|
|
176
186
|
this.indent++
|
|
177
187
|
this.generateNode(node.body)
|
|
178
188
|
this.indent--
|
|
@@ -200,8 +210,8 @@ class PHPGenerator {
|
|
|
200
210
|
result += '&'
|
|
201
211
|
}
|
|
202
212
|
|
|
203
|
-
const name = p.name || p.id?.name || p
|
|
204
|
-
result += '$' + this.translate(
|
|
213
|
+
const name = this.safeString(p.name || p.id?.name || p)
|
|
214
|
+
result += '$' + this.translate(name)
|
|
205
215
|
|
|
206
216
|
if (p.default !== undefined) {
|
|
207
217
|
result += ' = ' + this.generateNode(p.default)
|
|
@@ -211,6 +221,14 @@ class PHPGenerator {
|
|
|
211
221
|
}).join(', ')
|
|
212
222
|
}
|
|
213
223
|
|
|
224
|
+
safeString(value) {
|
|
225
|
+
if (typeof value === 'string') return value
|
|
226
|
+
if (value && typeof value === 'object') {
|
|
227
|
+
return value.name || value.value || 'unknown'
|
|
228
|
+
}
|
|
229
|
+
return String(value || 'unknown')
|
|
230
|
+
}
|
|
231
|
+
|
|
214
232
|
translateType(type) {
|
|
215
233
|
if (!type) return ''
|
|
216
234
|
|
|
@@ -230,7 +248,8 @@ class PHPGenerator {
|
|
|
230
248
|
'itérable': 'iterable', 'iterable': 'iterable',
|
|
231
249
|
'jamais': 'never', 'never': 'never'
|
|
232
250
|
}
|
|
233
|
-
|
|
251
|
+
const lower = translated.toLowerCase()
|
|
252
|
+
return typeMap[lower] || typeMap[type.toLowerCase()] || type
|
|
234
253
|
}
|
|
235
254
|
|
|
236
255
|
if (type.union) {
|
|
@@ -245,7 +264,11 @@ class PHPGenerator {
|
|
|
245
264
|
return '?' + this.translateType(type.type)
|
|
246
265
|
}
|
|
247
266
|
|
|
248
|
-
|
|
267
|
+
if (type.name) {
|
|
268
|
+
return this.translateType(type.name)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return String(type)
|
|
249
272
|
}
|
|
250
273
|
|
|
251
274
|
generateClassDeclaration(node) {
|
|
@@ -255,14 +278,15 @@ class PHPGenerator {
|
|
|
255
278
|
if (node.final) declaration += 'final '
|
|
256
279
|
if (node.readonly) declaration += 'readonly '
|
|
257
280
|
|
|
258
|
-
|
|
281
|
+
const className = this.safeString(node.name || node.id?.name)
|
|
282
|
+
declaration += 'class ' + this.translate(className)
|
|
259
283
|
|
|
260
284
|
if (node.extends) {
|
|
261
|
-
declaration += ' extends ' + this.translate(node.extends)
|
|
285
|
+
declaration += ' extends ' + this.translate(this.safeString(node.extends))
|
|
262
286
|
}
|
|
263
287
|
|
|
264
288
|
if (node.implements && node.implements.length > 0) {
|
|
265
|
-
declaration += ' implements ' + node.implements.map(i => this.translate(i)).join(', ')
|
|
289
|
+
declaration += ' implements ' + node.implements.map(i => this.translate(this.safeString(i))).join(', ')
|
|
266
290
|
}
|
|
267
291
|
|
|
268
292
|
this.writeLine(declaration + ' {')
|
|
@@ -278,10 +302,11 @@ class PHPGenerator {
|
|
|
278
302
|
}
|
|
279
303
|
|
|
280
304
|
generateInterfaceDeclaration(node) {
|
|
281
|
-
|
|
305
|
+
const name = this.safeString(node.name || node.id?.name)
|
|
306
|
+
let declaration = 'interface ' + this.translate(name)
|
|
282
307
|
|
|
283
308
|
if (node.extends && node.extends.length > 0) {
|
|
284
|
-
declaration += ' extends ' + node.extends.map(e => this.translate(e)).join(', ')
|
|
309
|
+
declaration += ' extends ' + node.extends.map(e => this.translate(this.safeString(e))).join(', ')
|
|
285
310
|
}
|
|
286
311
|
|
|
287
312
|
this.writeLine(declaration + ' {')
|
|
@@ -297,7 +322,8 @@ class PHPGenerator {
|
|
|
297
322
|
}
|
|
298
323
|
|
|
299
324
|
generateTraitDeclaration(node) {
|
|
300
|
-
|
|
325
|
+
const name = this.safeString(node.name || node.id?.name)
|
|
326
|
+
this.writeLine('trait ' + this.translate(name) + ' {')
|
|
301
327
|
this.indent++
|
|
302
328
|
|
|
303
329
|
for (const member of node.body || node.members || []) {
|
|
@@ -310,7 +336,8 @@ class PHPGenerator {
|
|
|
310
336
|
}
|
|
311
337
|
|
|
312
338
|
generateEnumDeclaration(node) {
|
|
313
|
-
|
|
339
|
+
const name = this.safeString(node.name || node.id?.name)
|
|
340
|
+
let declaration = 'enum ' + this.translate(name)
|
|
314
341
|
|
|
315
342
|
if (node.backingType) {
|
|
316
343
|
declaration += ': ' + this.translateType(node.backingType)
|
|
@@ -346,7 +373,7 @@ class PHPGenerator {
|
|
|
346
373
|
if (node.final) declaration += 'final '
|
|
347
374
|
if (node.abstract) declaration += 'abstract '
|
|
348
375
|
|
|
349
|
-
const name = this.translateMethodName(node.name || node.key?.name)
|
|
376
|
+
const name = this.translateMethodName(this.safeString(node.name || node.key?.name))
|
|
350
377
|
const params = this.generateParams(node.params || node.value?.params || [])
|
|
351
378
|
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
352
379
|
|
|
@@ -425,8 +452,8 @@ class PHPGenerator {
|
|
|
425
452
|
declaration += this.translateType(node.type) + ' '
|
|
426
453
|
}
|
|
427
454
|
|
|
428
|
-
const name = this.
|
|
429
|
-
declaration += '$' + name
|
|
455
|
+
const name = this.safeString(node.name || node.key?.name)
|
|
456
|
+
declaration += '$' + this.translate(name)
|
|
430
457
|
|
|
431
458
|
if (node.value !== undefined) {
|
|
432
459
|
declaration += ' = ' + this.generateNode(node.value)
|
|
@@ -437,8 +464,8 @@ class PHPGenerator {
|
|
|
437
464
|
|
|
438
465
|
generateVariableDeclaration(node) {
|
|
439
466
|
for (const decl of node.declarations || [node]) {
|
|
440
|
-
const name = decl.name || decl.id?.name || decl.id
|
|
441
|
-
const varName = '$' + this.translate(
|
|
467
|
+
const name = this.safeString(decl.name || decl.id?.name || decl.id)
|
|
468
|
+
const varName = '$' + this.translate(name)
|
|
442
469
|
|
|
443
470
|
if (decl.init !== undefined) {
|
|
444
471
|
const value = this.generateNode(decl.init)
|
|
@@ -450,7 +477,7 @@ class PHPGenerator {
|
|
|
450
477
|
}
|
|
451
478
|
|
|
452
479
|
generateConstantDeclaration(node) {
|
|
453
|
-
const name = node.name || node.id?.name
|
|
480
|
+
const name = this.safeString(node.name || node.id?.name)
|
|
454
481
|
const value = this.generateNode(node.value || node.init)
|
|
455
482
|
|
|
456
483
|
if (node.classLevel) {
|
|
@@ -498,8 +525,8 @@ class PHPGenerator {
|
|
|
498
525
|
|
|
499
526
|
generateForEachStatement(node) {
|
|
500
527
|
const array = this.generateNode(node.array || node.right || node.iterable)
|
|
501
|
-
const value = this.
|
|
502
|
-
const key = node.key || node.keyVar ? this.
|
|
528
|
+
const value = this.generateVariable(node.value || node.left || node.valueVar)
|
|
529
|
+
const key = node.key || node.keyVar ? this.generateVariable(node.key || node.keyVar) + ' => ' : ''
|
|
503
530
|
|
|
504
531
|
this.writeLine(`foreach (${array} as ${key}${value}) {`)
|
|
505
532
|
this.indent++
|
|
@@ -576,7 +603,7 @@ class PHPGenerator {
|
|
|
576
603
|
|
|
577
604
|
for (const handler of node.handlers || (node.handler ? [node.handler] : [])) {
|
|
578
605
|
const exceptionType = handler.type || handler.param?.type || 'Exception'
|
|
579
|
-
const param = handler.param ? this.
|
|
606
|
+
const param = handler.param ? this.generateVariable(handler.param) : '$e'
|
|
580
607
|
this.writeLine(`} catch (${exceptionType} ${param}) {`)
|
|
581
608
|
this.indent++
|
|
582
609
|
this.generateNode(handler.body)
|
|
@@ -623,12 +650,13 @@ class PHPGenerator {
|
|
|
623
650
|
}
|
|
624
651
|
|
|
625
652
|
generateNamespace(node) {
|
|
626
|
-
this.
|
|
653
|
+
const name = this.safeString(node.name)
|
|
654
|
+
this.writeLine(`namespace ${name};`)
|
|
627
655
|
this.writeLine('')
|
|
628
656
|
}
|
|
629
657
|
|
|
630
658
|
generateUseStatement(node) {
|
|
631
|
-
const name = node.name || node.source
|
|
659
|
+
const name = this.safeString(node.name || node.source)
|
|
632
660
|
const alias = node.alias ? ' as ' + node.alias : ''
|
|
633
661
|
const type = node.type === 'function' ? 'function ' : (node.type === 'const' ? 'const ' : '')
|
|
634
662
|
this.writeLine(`use ${type}${name}${alias};`)
|
|
@@ -655,17 +683,19 @@ class PHPGenerator {
|
|
|
655
683
|
|
|
656
684
|
if (typeof node.callee === 'string') {
|
|
657
685
|
callee = this.translate(node.callee)
|
|
658
|
-
} else if (node.callee.type === 'MemberExpression') {
|
|
686
|
+
} else if (node.callee && node.callee.type === 'MemberExpression') {
|
|
659
687
|
callee = this.generateMemberExpression(node.callee)
|
|
688
|
+
} else if (node.callee && node.callee.type === 'StaticMemberExpression') {
|
|
689
|
+
callee = this.generateStaticMemberExpression(node.callee)
|
|
660
690
|
} else {
|
|
661
691
|
callee = this.generateNode(node.callee)
|
|
662
692
|
}
|
|
663
693
|
|
|
664
694
|
const args = (node.arguments || []).map(a => {
|
|
665
|
-
if (a.
|
|
695
|
+
if (a && a.type === 'SpreadElement') {
|
|
666
696
|
return '...' + this.generateNode(a.argument || a)
|
|
667
697
|
}
|
|
668
|
-
if (a
|
|
698
|
+
if (a && a.type === 'NamedArgument') {
|
|
669
699
|
return `${a.name}: ${this.generateNode(a.value)}`
|
|
670
700
|
}
|
|
671
701
|
return this.generateNode(a)
|
|
@@ -676,9 +706,15 @@ class PHPGenerator {
|
|
|
676
706
|
|
|
677
707
|
generateMemberExpression(node) {
|
|
678
708
|
const object = this.generateNode(node.object)
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
709
|
+
let property
|
|
710
|
+
|
|
711
|
+
if (typeof node.property === 'string') {
|
|
712
|
+
property = node.property
|
|
713
|
+
} else if (node.property && node.property.name) {
|
|
714
|
+
property = node.property.name
|
|
715
|
+
} else {
|
|
716
|
+
property = this.generateNode(node.property)
|
|
717
|
+
}
|
|
682
718
|
|
|
683
719
|
if (node.static) {
|
|
684
720
|
return `${object}::${property}`
|
|
@@ -686,12 +722,33 @@ class PHPGenerator {
|
|
|
686
722
|
if (node.computed) {
|
|
687
723
|
return `${object}[${property}]`
|
|
688
724
|
}
|
|
689
|
-
if (node.
|
|
725
|
+
if (node.nullsafe || node.operator === '?->') {
|
|
690
726
|
return `${object}?->${property}`
|
|
691
727
|
}
|
|
692
728
|
return `${object}->${property}`
|
|
693
729
|
}
|
|
694
730
|
|
|
731
|
+
generateStaticMemberExpression(node) {
|
|
732
|
+
const cls = this.generateNode(node.class)
|
|
733
|
+
let member
|
|
734
|
+
|
|
735
|
+
if (typeof node.member === 'string') {
|
|
736
|
+
member = node.member
|
|
737
|
+
} else if (node.member && node.member.name) {
|
|
738
|
+
member = node.member.name
|
|
739
|
+
} else {
|
|
740
|
+
member = this.generateNode(node.member)
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
return `${cls}::${member}`
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
generateIndexExpression(node) {
|
|
747
|
+
const object = this.generateNode(node.object)
|
|
748
|
+
const index = node.index ? this.generateNode(node.index) : ''
|
|
749
|
+
return `${object}[${index}]`
|
|
750
|
+
}
|
|
751
|
+
|
|
695
752
|
generateBinaryExpression(node) {
|
|
696
753
|
const left = this.generateNode(node.left)
|
|
697
754
|
const right = this.generateNode(node.right)
|
|
@@ -708,14 +765,16 @@ class PHPGenerator {
|
|
|
708
765
|
'fusion null': '??', 'null coalescing': '??'
|
|
709
766
|
}
|
|
710
767
|
|
|
711
|
-
|
|
768
|
+
const opLower = op ? op.toLowerCase() : op
|
|
769
|
+
op = opMap[opLower] || op
|
|
712
770
|
|
|
713
771
|
return `${left} ${op} ${right}`
|
|
714
772
|
}
|
|
715
773
|
|
|
716
774
|
generateUnaryExpression(node) {
|
|
717
775
|
const argument = this.generateNode(node.argument)
|
|
718
|
-
|
|
776
|
+
let op = node.operator
|
|
777
|
+
if (op === 'non' || op === 'not') op = '!'
|
|
719
778
|
|
|
720
779
|
if (node.prefix) {
|
|
721
780
|
return `${op}${argument}`
|
|
@@ -756,14 +815,22 @@ class PHPGenerator {
|
|
|
756
815
|
generateArrayExpression(node) {
|
|
757
816
|
const elements = (node.elements || []).map(e => {
|
|
758
817
|
if (!e) return 'null'
|
|
759
|
-
if (e.
|
|
818
|
+
if (e.type === 'SpreadElement') {
|
|
819
|
+
return '...' + this.generateNode(e.argument || e)
|
|
820
|
+
}
|
|
821
|
+
if (e.type === 'ArrayElement') {
|
|
822
|
+
if (e.key !== null && e.key !== undefined) {
|
|
823
|
+
const key = this.generateNode(e.key)
|
|
824
|
+
const value = this.generateNode(e.value)
|
|
825
|
+
return `${key} => ${value}`
|
|
826
|
+
}
|
|
827
|
+
return this.generateNode(e.value)
|
|
828
|
+
}
|
|
829
|
+
if (e.key !== undefined && e.key !== null) {
|
|
760
830
|
const key = this.generateNode(e.key)
|
|
761
831
|
const value = this.generateNode(e.value || e)
|
|
762
832
|
return `${key} => ${value}`
|
|
763
833
|
}
|
|
764
|
-
if (e.spread) {
|
|
765
|
-
return '...' + this.generateNode(e.argument || e)
|
|
766
|
-
}
|
|
767
834
|
return this.generateNode(e)
|
|
768
835
|
})
|
|
769
836
|
|
|
@@ -786,19 +853,19 @@ class PHPGenerator {
|
|
|
786
853
|
|
|
787
854
|
generateClosure(node) {
|
|
788
855
|
const params = this.generateParams(node.params || [])
|
|
789
|
-
const useVars = node.
|
|
790
|
-
? ` use (${node.
|
|
856
|
+
const useVars = node.uses && node.uses.length > 0
|
|
857
|
+
? ` use (${node.uses.map(u => (u.byRef ? '&' : '') + '$' + this.translate(this.safeString(u.name || u))).join(', ')})`
|
|
791
858
|
: ''
|
|
792
859
|
const returnType = node.returnType ? ': ' + this.translateType(node.returnType) : ''
|
|
793
860
|
|
|
794
861
|
let result = `function(${params})${useVars}${returnType} {\n`
|
|
795
862
|
this.indent++
|
|
796
863
|
|
|
797
|
-
if (Array.isArray(node.body)) {
|
|
798
|
-
for (const stmt of node.body) {
|
|
864
|
+
if (node.body && Array.isArray(node.body.body)) {
|
|
865
|
+
for (const stmt of node.body.body) {
|
|
799
866
|
result += this.getIndent() + this.generateNode(stmt)
|
|
800
867
|
}
|
|
801
|
-
} else {
|
|
868
|
+
} else if (node.body) {
|
|
802
869
|
result += this.getIndent() + 'return ' + this.generateNode(node.body) + ';\n'
|
|
803
870
|
}
|
|
804
871
|
|
|
@@ -807,34 +874,47 @@ class PHPGenerator {
|
|
|
807
874
|
return result
|
|
808
875
|
}
|
|
809
876
|
|
|
877
|
+
generateVariable(node) {
|
|
878
|
+
if (!node) return '$var'
|
|
879
|
+
|
|
880
|
+
const name = this.safeString(node.name || node.id?.name || node)
|
|
881
|
+
const translated = this.translate(name)
|
|
882
|
+
const translatedStr = String(translated)
|
|
883
|
+
|
|
884
|
+
if (translatedStr.startsWith('$')) return translatedStr
|
|
885
|
+
return '$' + translatedStr
|
|
886
|
+
}
|
|
887
|
+
|
|
810
888
|
generateIdentifier(node) {
|
|
811
|
-
|
|
812
|
-
if (typeof name !== 'string') return '$var'
|
|
889
|
+
if (!node) return '$var'
|
|
813
890
|
|
|
891
|
+
const name = this.safeString(node.name || node.id?.name || node)
|
|
814
892
|
const translated = this.translate(name)
|
|
893
|
+
const translatedStr = String(translated)
|
|
815
894
|
|
|
816
|
-
if (
|
|
895
|
+
if (translatedStr.startsWith('$')) return translatedStr
|
|
817
896
|
|
|
818
897
|
const keywords = [
|
|
819
898
|
'true', 'false', 'null',
|
|
820
899
|
'self', 'parent', 'static',
|
|
821
900
|
'this', '$this'
|
|
822
901
|
]
|
|
823
|
-
if (keywords.includes(
|
|
824
|
-
if (
|
|
825
|
-
return
|
|
902
|
+
if (keywords.includes(translatedStr.toLowerCase())) {
|
|
903
|
+
if (translatedStr.toLowerCase() === 'this') return '$this'
|
|
904
|
+
return translatedStr
|
|
826
905
|
}
|
|
827
906
|
|
|
828
|
-
if (/^[A-Z]/.test(
|
|
907
|
+
if (/^[A-Z]/.test(translatedStr)) return translatedStr
|
|
829
908
|
|
|
830
|
-
if (
|
|
909
|
+
if (translatedStr.includes('(') || translatedStr.includes('::')) return translatedStr
|
|
831
910
|
|
|
832
911
|
const superglobals = ['_GET', '_POST', '_SERVER', '_SESSION', '_COOKIE', '_FILES', '_REQUEST', '_ENV', 'GLOBALS']
|
|
833
|
-
|
|
834
|
-
|
|
912
|
+
const upper = translatedStr.toUpperCase()
|
|
913
|
+
if (superglobals.includes(translatedStr) || superglobals.includes(upper)) {
|
|
914
|
+
return '$' + upper
|
|
835
915
|
}
|
|
836
916
|
|
|
837
|
-
return '$' +
|
|
917
|
+
return '$' + translatedStr
|
|
838
918
|
}
|
|
839
919
|
|
|
840
920
|
generateLiteral(node) {
|
|
@@ -854,10 +934,26 @@ class PHPGenerator {
|
|
|
854
934
|
return String(node.value)
|
|
855
935
|
}
|
|
856
936
|
|
|
937
|
+
generateStringLiteral(node) {
|
|
938
|
+
const value = node.value || ''
|
|
939
|
+
const escaped = value
|
|
940
|
+
.replace(/\\/g, '\\\\')
|
|
941
|
+
.replace(/"/g, '\\"')
|
|
942
|
+
.replace(/\n/g, '\\n')
|
|
943
|
+
.replace(/\r/g, '\\r')
|
|
944
|
+
.replace(/\t/g, '\\t')
|
|
945
|
+
return node.doubleQuoted !== false ? `"${escaped}"` : `'${escaped}'`
|
|
946
|
+
}
|
|
947
|
+
|
|
857
948
|
generateNewExpression(node) {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
949
|
+
let callee
|
|
950
|
+
if (typeof node.callee === 'string') {
|
|
951
|
+
callee = this.translate(node.callee)
|
|
952
|
+
} else if (node.callee && node.callee.name) {
|
|
953
|
+
callee = this.translate(node.callee.name)
|
|
954
|
+
} else {
|
|
955
|
+
callee = this.generateNode(node.callee)
|
|
956
|
+
}
|
|
861
957
|
const args = (node.arguments || []).map(a => this.generateNode(a)).join(', ')
|
|
862
958
|
return `new ${callee}(${args})`
|
|
863
959
|
}
|
|
@@ -887,6 +983,4 @@ class PHPGenerator {
|
|
|
887
983
|
}
|
|
888
984
|
}
|
|
889
985
|
|
|
890
|
-
module.exports = {
|
|
891
|
-
PHPGenerator
|
|
892
|
-
}
|
|
986
|
+
module.exports = { PHPGenerator }
|
package/package.json
CHANGED
|
@@ -226,6 +226,12 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
226
226
|
this.phpModifiers = ['statique', 'static', 'final', 'finale', 'abstrait', 'abstraite', 'abstract', 'readonly', 'lecture seule']
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
safeStr(val) {
|
|
230
|
+
if (typeof val === 'string') return val
|
|
231
|
+
if (val && typeof val === 'object') return String(val.name || val.value || '')
|
|
232
|
+
return String(val || '')
|
|
233
|
+
}
|
|
234
|
+
|
|
229
235
|
translatePHP(word) {
|
|
230
236
|
if (!word) return word
|
|
231
237
|
const lower = this.normalizeAccents(String(word))
|
|
@@ -736,7 +742,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
736
742
|
}
|
|
737
743
|
|
|
738
744
|
const nameToken = this.current()
|
|
739
|
-
let name = nameToken ? nameToken.value : 'property'
|
|
745
|
+
let name = this.safeStr(nameToken ? nameToken.value : 'property')
|
|
740
746
|
|
|
741
747
|
if (name.startsWith('$')) {
|
|
742
748
|
name = name.substring(1)
|
|
@@ -1047,7 +1053,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1047
1053
|
}
|
|
1048
1054
|
|
|
1049
1055
|
const varToken = this.current()
|
|
1050
|
-
let varName = varToken ? varToken.value : ''
|
|
1056
|
+
let varName = this.safeStr(varToken ? varToken.value : '')
|
|
1051
1057
|
if (varName.startsWith('$')) {
|
|
1052
1058
|
varName = varName.substring(1)
|
|
1053
1059
|
}
|
|
@@ -1126,7 +1132,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1126
1132
|
const nameToken = this.current()
|
|
1127
1133
|
if (!nameToken) return null
|
|
1128
1134
|
|
|
1129
|
-
let name = nameToken.value
|
|
1135
|
+
let name = this.safeStr(nameToken.value)
|
|
1130
1136
|
if (name.startsWith('$')) {
|
|
1131
1137
|
name = name.substring(1)
|
|
1132
1138
|
}
|
|
@@ -1218,7 +1224,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1218
1224
|
}
|
|
1219
1225
|
|
|
1220
1226
|
const nameToken = this.current()
|
|
1221
|
-
let name = nameToken ? nameToken.value : 'variable'
|
|
1227
|
+
let name = this.safeStr(nameToken ? nameToken.value : 'variable')
|
|
1222
1228
|
if (name.startsWith('$')) {
|
|
1223
1229
|
name = name.substring(1)
|
|
1224
1230
|
}
|
|
@@ -1372,7 +1378,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1372
1378
|
}
|
|
1373
1379
|
|
|
1374
1380
|
const firstVar = this.current()
|
|
1375
|
-
let firstName = firstVar ? firstVar.value : 'item'
|
|
1381
|
+
let firstName = this.safeStr(firstVar ? firstVar.value : 'item')
|
|
1376
1382
|
if (firstName.startsWith('$')) firstName = firstName.substring(1)
|
|
1377
1383
|
this.advance()
|
|
1378
1384
|
|
|
@@ -1384,7 +1390,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1384
1390
|
}
|
|
1385
1391
|
|
|
1386
1392
|
const valueVar = this.current()
|
|
1387
|
-
value = valueVar ? valueVar.value : 'value'
|
|
1393
|
+
let value = this.safeStr(valueVar ? valueVar.value : 'value')
|
|
1388
1394
|
if (value.startsWith('$')) value = value.substring(1)
|
|
1389
1395
|
this.advance()
|
|
1390
1396
|
} else {
|
|
@@ -1632,7 +1638,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1632
1638
|
do {
|
|
1633
1639
|
const typeToken = this.current()
|
|
1634
1640
|
if (typeToken && typeToken.type === TokenType.IDENTIFIER) {
|
|
1635
|
-
const typeName = typeToken.value
|
|
1641
|
+
const typeName = this.safeStr(typeToken.value)
|
|
1636
1642
|
if (typeName.startsWith('$')) {
|
|
1637
1643
|
param = typeName.substring(1)
|
|
1638
1644
|
} else {
|
|
@@ -1645,7 +1651,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1645
1651
|
if (!param) {
|
|
1646
1652
|
const paramToken = this.current()
|
|
1647
1653
|
if (paramToken && paramToken.type === TokenType.IDENTIFIER) {
|
|
1648
|
-
param = paramToken.value
|
|
1654
|
+
param = this.safeStr(paramToken.value)
|
|
1649
1655
|
if (param.startsWith('$')) param = param.substring(1)
|
|
1650
1656
|
this.advance()
|
|
1651
1657
|
}
|
|
@@ -1759,7 +1765,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
1759
1765
|
const variables = []
|
|
1760
1766
|
do {
|
|
1761
1767
|
const varToken = this.current()
|
|
1762
|
-
let varName = varToken ? varToken.value : ''
|
|
1768
|
+
let varName = this.safeStr(varToken ? varToken.value : '')
|
|
1763
1769
|
if (varName.startsWith('$')) varName = varName.substring(1)
|
|
1764
1770
|
this.advance()
|
|
1765
1771
|
variables.push(varName)
|
|
@@ -2209,11 +2215,11 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2209
2215
|
|
|
2210
2216
|
if (token.type === TokenType.STRING) {
|
|
2211
2217
|
this.advance()
|
|
2212
|
-
let value = token.value
|
|
2218
|
+
let value = this.safeStr(token.value)
|
|
2213
2219
|
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
2214
2220
|
value = value.slice(1, -1)
|
|
2215
2221
|
}
|
|
2216
|
-
const isDouble = token.value.startsWith('"')
|
|
2222
|
+
const isDouble = value.startsWith('"') || this.safeStr(token.value).startsWith('"')
|
|
2217
2223
|
return { type: 'StringLiteral', value, doubleQuoted: isDouble }
|
|
2218
2224
|
}
|
|
2219
2225
|
|
|
@@ -2223,7 +2229,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2223
2229
|
}
|
|
2224
2230
|
|
|
2225
2231
|
if (token.type === TokenType.IDENTIFIER) {
|
|
2226
|
-
const value = token.value
|
|
2232
|
+
const value = this.safeStr(token.value)
|
|
2227
2233
|
const valueLower = this.normalizeAccents(value.toLowerCase())
|
|
2228
2234
|
|
|
2229
2235
|
if (valueLower === 'vrai' || valueLower === 'true') {
|
|
@@ -2285,7 +2291,7 @@ class EtherParserPHP extends EtherParserBase {
|
|
|
2285
2291
|
|
|
2286
2292
|
if (token.type === TokenType.VARIABLE) {
|
|
2287
2293
|
this.advance()
|
|
2288
|
-
let name = token.value
|
|
2294
|
+
let name = this.safeStr(token.value)
|
|
2289
2295
|
if (name.startsWith('$')) name = name.substring(1)
|
|
2290
2296
|
return { type: 'Variable', name }
|
|
2291
2297
|
}
|
package/parsers/ether-parser.js
CHANGED
|
@@ -30,13 +30,23 @@ class EtherParser {
|
|
|
30
30
|
if (!this.parsers[lang]) {
|
|
31
31
|
switch (lang) {
|
|
32
32
|
case 'js':
|
|
33
|
+
this.parsers[lang] = new EtherParserJS(this.options)
|
|
34
|
+
break
|
|
33
35
|
case 'ts':
|
|
36
|
+
this.parsers[lang] = new EtherParserJS(this.options)
|
|
37
|
+
break
|
|
34
38
|
case 'react':
|
|
39
|
+
this.parsers[lang] = new EtherParserJS(this.options)
|
|
40
|
+
break
|
|
35
41
|
case 'node':
|
|
42
|
+
this.parsers[lang] = new EtherParserJS(this.options)
|
|
43
|
+
break
|
|
36
44
|
case 'php':
|
|
37
45
|
this.parsers[lang] = new EtherParserPHP(this.options)
|
|
38
46
|
break
|
|
39
47
|
case 'python':
|
|
48
|
+
this.parsers[lang] = new EtherParserJS(this.options)
|
|
49
|
+
break
|
|
40
50
|
case 'ruby':
|
|
41
51
|
this.parsers[lang] = new EtherParserJS(this.options)
|
|
42
52
|
break
|
|
@@ -53,15 +63,13 @@ class EtherParser {
|
|
|
53
63
|
this.parsers[lang] = new EtherParserGraphQL(this.options)
|
|
54
64
|
break
|
|
55
65
|
default:
|
|
56
|
-
this.parsers[lang] = new
|
|
66
|
+
this.parsers[lang] = new EtherParserHTML(this.options)
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
return this.parsers[lang]
|
|
60
70
|
}
|
|
61
71
|
|
|
62
72
|
detectTargetLanguage(source) {
|
|
63
|
-
const lower = source.toLowerCase()
|
|
64
|
-
|
|
65
73
|
const targetMatch = source.match(/\/\/\s*cible\s*:\s*(\w+)/i)
|
|
66
74
|
if (targetMatch) {
|
|
67
75
|
const target = targetMatch[1].toLowerCase()
|
|
@@ -83,6 +91,8 @@ class EtherParser {
|
|
|
83
91
|
}
|
|
84
92
|
}
|
|
85
93
|
|
|
94
|
+
const lower = source.toLowerCase()
|
|
95
|
+
|
|
86
96
|
if (/^\s*(document|page|<!doctype|<html|tete|corps|entete|navigation|section|article)/m.test(lower)) {
|
|
87
97
|
return 'html'
|
|
88
98
|
}
|
|
@@ -133,7 +143,7 @@ class EtherParser {
|
|
|
133
143
|
return 'js'
|
|
134
144
|
}
|
|
135
145
|
|
|
136
|
-
return '
|
|
146
|
+
return 'html'
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
parse(source, targetLang = null) {
|
|
@@ -145,4 +155,4 @@ class EtherParser {
|
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
|
|
148
|
-
module.exports = { EtherParser, TokenType }
|
|
158
|
+
module.exports = { EtherParser, TokenType }
|