ether-code 0.6.9 → 0.7.1
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/js-generator.js +192 -41
- package/package.json +1 -1
package/cli/ether.js
CHANGED
|
@@ -32,11 +32,15 @@ class JSGenerator {
|
|
|
32
32
|
return
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const normalize = (str) => {
|
|
36
|
+
return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
const addToMap = (map, section, prefix = '') => {
|
|
36
40
|
if (!section) return
|
|
37
41
|
for (const [key, translations] of Object.entries(section)) {
|
|
38
42
|
if (translations && translations.fr && translations.en) {
|
|
39
|
-
const frKey = translations.fr
|
|
43
|
+
const frKey = normalize(translations.fr)
|
|
40
44
|
const enValue = translations.en
|
|
41
45
|
if (prefix) {
|
|
42
46
|
if (!this.contextualMap[frKey]) {
|
|
@@ -266,7 +270,9 @@ class JSGenerator {
|
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
buildDefaultMaps() {
|
|
269
|
-
|
|
273
|
+
const norm = (str) => str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
274
|
+
|
|
275
|
+
const rawKeywords = {
|
|
270
276
|
'variable': 'let',
|
|
271
277
|
'constante': 'const',
|
|
272
278
|
'variable globale': 'var',
|
|
@@ -377,7 +383,7 @@ class JSGenerator {
|
|
|
377
383
|
'gabarit étiqueté': 'tagged template'
|
|
378
384
|
}
|
|
379
385
|
|
|
380
|
-
|
|
386
|
+
const rawOperators = {
|
|
381
387
|
'plus': '+',
|
|
382
388
|
'moins': '-',
|
|
383
389
|
'fois': '*',
|
|
@@ -414,7 +420,7 @@ class JSGenerator {
|
|
|
414
420
|
'décomposition': '...'
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
|
|
423
|
+
const rawMethods = {
|
|
418
424
|
'afficher': 'console.log',
|
|
419
425
|
'journal': 'console.log',
|
|
420
426
|
'erreur': 'console.error',
|
|
@@ -776,7 +782,23 @@ class JSGenerator {
|
|
|
776
782
|
'décoder URI': 'decodeURI',
|
|
777
783
|
'décoder composant URI': 'decodeURIComponent',
|
|
778
784
|
'encoder URI': 'encodeURI',
|
|
779
|
-
'encoder composant URI': 'encodeURIComponent'
|
|
785
|
+
'encoder composant URI': 'encodeURIComponent',
|
|
786
|
+
'selecteur': 'querySelector',
|
|
787
|
+
'selecteurs': 'querySelectorAll'
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
this.keywordMap = {}
|
|
791
|
+
this.operatorMap = {}
|
|
792
|
+
this.methodMap = {}
|
|
793
|
+
|
|
794
|
+
for (const [key, value] of Object.entries(rawKeywords)) {
|
|
795
|
+
this.keywordMap[norm(key)] = value
|
|
796
|
+
}
|
|
797
|
+
for (const [key, value] of Object.entries(rawOperators)) {
|
|
798
|
+
this.operatorMap[norm(key)] = value
|
|
799
|
+
}
|
|
800
|
+
for (const [key, value] of Object.entries(rawMethods)) {
|
|
801
|
+
this.methodMap[norm(key)] = value
|
|
780
802
|
}
|
|
781
803
|
|
|
782
804
|
this.buildConflictResolution()
|
|
@@ -795,7 +817,7 @@ class JSGenerator {
|
|
|
795
817
|
}
|
|
796
818
|
|
|
797
819
|
translateWithContext(word, explicitContext = null) {
|
|
798
|
-
const lower =
|
|
820
|
+
const lower = this.normalize(word)
|
|
799
821
|
const ctx = explicitContext || this.getCurrentContext()
|
|
800
822
|
|
|
801
823
|
if (this.conflicts[lower] && ctx) {
|
|
@@ -814,8 +836,12 @@ class JSGenerator {
|
|
|
814
836
|
word
|
|
815
837
|
}
|
|
816
838
|
|
|
817
|
-
|
|
818
|
-
|
|
839
|
+
normalize(str) {
|
|
840
|
+
return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
translate(word, isMethod = false) {
|
|
844
|
+
const lower = this.normalize(word)
|
|
819
845
|
|
|
820
846
|
if (this.keywordMap[lower]) {
|
|
821
847
|
return this.keywordMap[lower]
|
|
@@ -823,13 +849,17 @@ class JSGenerator {
|
|
|
823
849
|
if (this.operatorMap[lower]) {
|
|
824
850
|
return this.operatorMap[lower]
|
|
825
851
|
}
|
|
826
|
-
if (this.methodMap[lower]) {
|
|
852
|
+
if (isMethod && this.methodMap[lower]) {
|
|
827
853
|
return this.methodMap[lower]
|
|
828
854
|
}
|
|
829
855
|
|
|
830
856
|
return word
|
|
831
857
|
}
|
|
832
858
|
|
|
859
|
+
translateMethod(word) {
|
|
860
|
+
return this.translate(word, true)
|
|
861
|
+
}
|
|
862
|
+
|
|
833
863
|
translateOperator(op) {
|
|
834
864
|
const lower = op.toLowerCase()
|
|
835
865
|
return this.operatorMap[lower] || op
|
|
@@ -953,8 +983,10 @@ class JSGenerator {
|
|
|
953
983
|
return this.generateSpreadElement(node)
|
|
954
984
|
case 'RestElement':
|
|
955
985
|
return this.generateRestElement(node)
|
|
986
|
+
case 'Parameter':
|
|
987
|
+
return this.generateParam(node)
|
|
956
988
|
case 'Identifier':
|
|
957
|
-
return
|
|
989
|
+
return node.name
|
|
958
990
|
case 'PrivateIdentifier':
|
|
959
991
|
return this.generatePrivateIdentifier(node)
|
|
960
992
|
case 'Literal':
|
|
@@ -1013,12 +1045,20 @@ class JSGenerator {
|
|
|
1013
1045
|
}
|
|
1014
1046
|
kind = kindTranslations[kind.toLowerCase()] || this.translate(kind)
|
|
1015
1047
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1048
|
+
if (node.declarations && node.declarations.length > 0) {
|
|
1049
|
+
for (const decl of node.declarations) {
|
|
1050
|
+
const name = this.generateNode(decl.id || decl.name)
|
|
1051
|
+
if (decl.init) {
|
|
1052
|
+
const init = this.generateNode(decl.init)
|
|
1053
|
+
this.writeLine(`${kind} ${name} = ${init};`)
|
|
1054
|
+
} else {
|
|
1055
|
+
this.writeLine(`${kind} ${name};`)
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
} else if (node.name) {
|
|
1059
|
+
const name = typeof node.name === 'string' ? node.name : this.generateNode(node.name)
|
|
1060
|
+
if (node.init) {
|
|
1061
|
+
const init = this.generateNode(node.init)
|
|
1022
1062
|
this.writeLine(`${kind} ${name} = ${init};`)
|
|
1023
1063
|
} else {
|
|
1024
1064
|
this.writeLine(`${kind} ${name};`)
|
|
@@ -1029,8 +1069,8 @@ class JSGenerator {
|
|
|
1029
1069
|
generateFunctionDeclaration(node) {
|
|
1030
1070
|
const async = node.async ? 'async ' : ''
|
|
1031
1071
|
const generator = node.generator ? '*' : ''
|
|
1032
|
-
const name = node.id ?
|
|
1033
|
-
const params = (node.params || []).map(p => this.
|
|
1072
|
+
const name = node.name || (node.id ? (node.id.name || node.id) : '')
|
|
1073
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
1034
1074
|
|
|
1035
1075
|
this.writeLine(`${async}function${generator} ${name}(${params}) {`)
|
|
1036
1076
|
this.indent++
|
|
@@ -1043,8 +1083,8 @@ class JSGenerator {
|
|
|
1043
1083
|
generateFunctionExpression(node) {
|
|
1044
1084
|
const async = node.async ? 'async ' : ''
|
|
1045
1085
|
const generator = node.generator ? '*' : ''
|
|
1046
|
-
const name = node.id ?
|
|
1047
|
-
const params = (node.params || []).map(p => this.
|
|
1086
|
+
const name = node.name || (node.id ? (node.id.name || node.id) : '')
|
|
1087
|
+
const params = (node.params || []).map(p => this.generateParam(p)).join(', ')
|
|
1048
1088
|
|
|
1049
1089
|
let body = ''
|
|
1050
1090
|
const savedOutput = this.output
|
|
@@ -1058,6 +1098,26 @@ class JSGenerator {
|
|
|
1058
1098
|
return `${async}function${generator} ${name}(${params}) {\n${body}\n${this.getIndent()}}`
|
|
1059
1099
|
}
|
|
1060
1100
|
|
|
1101
|
+
generateParam(param) {
|
|
1102
|
+
if (!param) return ''
|
|
1103
|
+
if (typeof param === 'string') return param
|
|
1104
|
+
if (param.type === 'Identifier') return param.name
|
|
1105
|
+
if (param.type === 'Parameter') {
|
|
1106
|
+
let result = param.name
|
|
1107
|
+
if (param.default) {
|
|
1108
|
+
result += ' = ' + this.generateNode(param.default)
|
|
1109
|
+
}
|
|
1110
|
+
return result
|
|
1111
|
+
}
|
|
1112
|
+
if (param.type === 'RestElement') {
|
|
1113
|
+
return '...' + this.generateParam(param.argument)
|
|
1114
|
+
}
|
|
1115
|
+
if (param.type === 'AssignmentPattern') {
|
|
1116
|
+
return this.generateNode(param.left) + ' = ' + this.generateNode(param.right)
|
|
1117
|
+
}
|
|
1118
|
+
return param.name || this.generateNode(param)
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1061
1121
|
generateClassDeclaration(node) {
|
|
1062
1122
|
const name = node.id ? (node.id.name || node.id) : ''
|
|
1063
1123
|
const extend = node.superClass ? ` extends ${this.generateNode(node.superClass)}` : ''
|
|
@@ -1172,7 +1232,7 @@ class JSGenerator {
|
|
|
1172
1232
|
}
|
|
1173
1233
|
|
|
1174
1234
|
generateIfStatement(node) {
|
|
1175
|
-
const test = this.generateNode(node.test)
|
|
1235
|
+
const test = this.generateNode(node.test || node.condition)
|
|
1176
1236
|
this.writeLine(`if (${test}) {`)
|
|
1177
1237
|
this.indent++
|
|
1178
1238
|
this.generateNode(node.consequent)
|
|
@@ -1180,8 +1240,46 @@ class JSGenerator {
|
|
|
1180
1240
|
|
|
1181
1241
|
if (node.alternate) {
|
|
1182
1242
|
if (node.alternate.type === 'IfStatement') {
|
|
1183
|
-
|
|
1184
|
-
this.
|
|
1243
|
+
const altTest = this.generateNode(node.alternate.test || node.alternate.condition)
|
|
1244
|
+
this.writeLine(`} else if (${altTest}) {`)
|
|
1245
|
+
this.indent++
|
|
1246
|
+
this.generateNode(node.alternate.consequent)
|
|
1247
|
+
this.indent--
|
|
1248
|
+
if (node.alternate.alternate) {
|
|
1249
|
+
if (node.alternate.alternate.type === 'IfStatement') {
|
|
1250
|
+
this.generateElseIfChain(node.alternate.alternate)
|
|
1251
|
+
} else {
|
|
1252
|
+
this.writeLine('} else {')
|
|
1253
|
+
this.indent++
|
|
1254
|
+
this.generateNode(node.alternate.alternate)
|
|
1255
|
+
this.indent--
|
|
1256
|
+
this.writeLine('}')
|
|
1257
|
+
}
|
|
1258
|
+
} else {
|
|
1259
|
+
this.writeLine('}')
|
|
1260
|
+
}
|
|
1261
|
+
} else {
|
|
1262
|
+
this.writeLine('} else {')
|
|
1263
|
+
this.indent++
|
|
1264
|
+
this.generateNode(node.alternate)
|
|
1265
|
+
this.indent--
|
|
1266
|
+
this.writeLine('}')
|
|
1267
|
+
}
|
|
1268
|
+
} else {
|
|
1269
|
+
this.writeLine('}')
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
generateElseIfChain(node) {
|
|
1274
|
+
const test = this.generateNode(node.test || node.condition)
|
|
1275
|
+
this.writeLine(`} else if (${test}) {`)
|
|
1276
|
+
this.indent++
|
|
1277
|
+
this.generateNode(node.consequent)
|
|
1278
|
+
this.indent--
|
|
1279
|
+
|
|
1280
|
+
if (node.alternate) {
|
|
1281
|
+
if (node.alternate.type === 'IfStatement') {
|
|
1282
|
+
this.generateElseIfChain(node.alternate)
|
|
1185
1283
|
} else {
|
|
1186
1284
|
this.writeLine('} else {')
|
|
1187
1285
|
this.indent++
|
|
@@ -1195,15 +1293,44 @@ class JSGenerator {
|
|
|
1195
1293
|
}
|
|
1196
1294
|
|
|
1197
1295
|
generateForStatement(node) {
|
|
1296
|
+
if (node.iterable || node.variable) {
|
|
1297
|
+
const varName = node.variable || 'item'
|
|
1298
|
+
const iterable = this.generateNode(node.iterable)
|
|
1299
|
+
this.writeLine(`for (const ${varName} of ${iterable}) {`)
|
|
1300
|
+
this.indent++
|
|
1301
|
+
this.generateNode(node.body)
|
|
1302
|
+
this.indent--
|
|
1303
|
+
this.writeLine('}')
|
|
1304
|
+
return
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if (node.start !== undefined && node.end !== undefined) {
|
|
1308
|
+
const varName = node.variable || 'i'
|
|
1309
|
+
const start = this.generateNode(node.start)
|
|
1310
|
+
const end = this.generateNode(node.end)
|
|
1311
|
+
const step = node.step ? this.generateNode(node.step) : '1'
|
|
1312
|
+
this.writeLine(`for (let ${varName} = ${start}; ${varName} < ${end}; ${varName} += ${step}) {`)
|
|
1313
|
+
this.indent++
|
|
1314
|
+
this.generateNode(node.body)
|
|
1315
|
+
this.indent--
|
|
1316
|
+
this.writeLine('}')
|
|
1317
|
+
return
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1198
1320
|
let init = ''
|
|
1199
1321
|
if (node.init) {
|
|
1200
1322
|
if (node.init.type === 'VariableDeclaration') {
|
|
1201
1323
|
const kind = this.translate(node.init.kind || 'let')
|
|
1202
|
-
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1324
|
+
if (node.init.declarations && node.init.declarations.length > 0) {
|
|
1325
|
+
const decls = node.init.declarations.map(d => {
|
|
1326
|
+
const name = this.generateNode(d.id || d.name)
|
|
1327
|
+
return d.init ? `${name} = ${this.generateNode(d.init)}` : name
|
|
1328
|
+
}).join(', ')
|
|
1329
|
+
init = `${kind} ${decls}`
|
|
1330
|
+
} else if (node.init.name) {
|
|
1331
|
+
const name = node.init.name
|
|
1332
|
+
init = node.init.init ? `${kind} ${name} = ${this.generateNode(node.init.init)}` : `${kind} ${name}`
|
|
1333
|
+
}
|
|
1207
1334
|
} else {
|
|
1208
1335
|
init = this.generateNode(node.init)
|
|
1209
1336
|
}
|
|
@@ -1221,14 +1348,26 @@ class JSGenerator {
|
|
|
1221
1348
|
generateForOfStatement(node) {
|
|
1222
1349
|
this.pushContext('loop')
|
|
1223
1350
|
let left
|
|
1224
|
-
if (node.left
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1351
|
+
if (node.left) {
|
|
1352
|
+
if (node.left.type === 'VariableDeclaration') {
|
|
1353
|
+
const kind = this.translate(node.left.kind || 'const')
|
|
1354
|
+
if (node.left.declarations && node.left.declarations.length > 0) {
|
|
1355
|
+
const name = this.generateNode(node.left.declarations[0].id || node.left.declarations[0].name)
|
|
1356
|
+
left = `${kind} ${name}`
|
|
1357
|
+
} else if (node.left.name) {
|
|
1358
|
+
left = `${kind} ${node.left.name}`
|
|
1359
|
+
} else {
|
|
1360
|
+
left = `${kind} item`
|
|
1361
|
+
}
|
|
1362
|
+
} else {
|
|
1363
|
+
left = this.generateNode(node.left)
|
|
1364
|
+
}
|
|
1365
|
+
} else if (node.variable) {
|
|
1366
|
+
left = `const ${node.variable}`
|
|
1228
1367
|
} else {
|
|
1229
|
-
left =
|
|
1368
|
+
left = 'const item'
|
|
1230
1369
|
}
|
|
1231
|
-
const right = this.generateNode(node.right)
|
|
1370
|
+
const right = this.generateNode(node.right || node.iterable)
|
|
1232
1371
|
|
|
1233
1372
|
this.writeLine(`for (${left} of ${right}) {`)
|
|
1234
1373
|
this.indent++
|
|
@@ -1241,14 +1380,26 @@ class JSGenerator {
|
|
|
1241
1380
|
generateForInStatement(node) {
|
|
1242
1381
|
this.pushContext('loop')
|
|
1243
1382
|
let left
|
|
1244
|
-
if (node.left
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1383
|
+
if (node.left) {
|
|
1384
|
+
if (node.left.type === 'VariableDeclaration') {
|
|
1385
|
+
const kind = this.translate(node.left.kind || 'const')
|
|
1386
|
+
if (node.left.declarations && node.left.declarations.length > 0) {
|
|
1387
|
+
const name = this.generateNode(node.left.declarations[0].id || node.left.declarations[0].name)
|
|
1388
|
+
left = `${kind} ${name}`
|
|
1389
|
+
} else if (node.left.name) {
|
|
1390
|
+
left = `${kind} ${node.left.name}`
|
|
1391
|
+
} else {
|
|
1392
|
+
left = `${kind} key`
|
|
1393
|
+
}
|
|
1394
|
+
} else {
|
|
1395
|
+
left = this.generateNode(node.left)
|
|
1396
|
+
}
|
|
1397
|
+
} else if (node.variable) {
|
|
1398
|
+
left = `const ${node.variable}`
|
|
1248
1399
|
} else {
|
|
1249
|
-
left =
|
|
1400
|
+
left = 'const key'
|
|
1250
1401
|
}
|
|
1251
|
-
const right = this.generateNode(node.right)
|
|
1402
|
+
const right = this.generateNode(node.right || node.iterable)
|
|
1252
1403
|
|
|
1253
1404
|
this.writeLine(`for (${left} in ${right}) {`)
|
|
1254
1405
|
this.indent++
|
|
@@ -1550,7 +1701,7 @@ class JSGenerator {
|
|
|
1550
1701
|
return `${object}[${property}]`
|
|
1551
1702
|
}
|
|
1552
1703
|
|
|
1553
|
-
const translatedProperty = this.
|
|
1704
|
+
const translatedProperty = this.translateMethod(property)
|
|
1554
1705
|
|
|
1555
1706
|
if (translatedProperty.includes('.')) {
|
|
1556
1707
|
const parts = translatedProperty.split('.')
|