ether-code 0.1.0
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/LICENSE +21 -0
- package/README.md +130 -0
- package/cli/compiler.js +298 -0
- package/cli/ether.js +532 -0
- package/cli/watcher.js +106 -0
- package/generators/css-generator.js +583 -0
- package/generators/graphql-generator.js +868 -0
- package/generators/html-generator.js +745 -0
- package/generators/js-generator.js +909 -0
- package/generators/node-generator.js +467 -0
- package/generators/php-generator.js +706 -0
- package/generators/python-generator.js +913 -0
- package/generators/react-generator.js +599 -0
- package/generators/ruby-generator.js +904 -0
- package/generators/sql-generator.js +988 -0
- package/generators/ts-generator.js +569 -0
- package/i18n/i18n-css.json +743 -0
- package/i18n/i18n-graphql.json +1531 -0
- package/i18n/i18n-html.json +572 -0
- package/i18n/i18n-js.json +2790 -0
- package/i18n/i18n-node.json +2442 -0
- package/i18n/i18n-php.json +4306 -0
- package/i18n/i18n-python.json +3080 -0
- package/i18n/i18n-react.json +1784 -0
- package/i18n/i18n-ruby.json +1858 -0
- package/i18n/i18n-sql.json +3466 -0
- package/i18n/i18n-ts.json +442 -0
- package/lexer/ether-lexer.js +728 -0
- package/lexer/tokens.js +292 -0
- package/package.json +45 -0
- package/parsers/ast-css.js +545 -0
- package/parsers/ast-graphql.js +424 -0
- package/parsers/ast-html.js +886 -0
- package/parsers/ast-js.js +750 -0
- package/parsers/ast-node.js +2440 -0
- package/parsers/ast-php.js +957 -0
- package/parsers/ast-react.js +580 -0
- package/parsers/ast-ruby.js +895 -0
- package/parsers/ast-ts.js +1352 -0
- package/parsers/css-parser.js +1981 -0
- package/parsers/graphql-parser.js +2011 -0
- package/parsers/html-parser.js +1181 -0
- package/parsers/js-parser.js +2564 -0
- package/parsers/node-parser.js +2644 -0
- package/parsers/php-parser.js +3037 -0
- package/parsers/react-parser.js +1035 -0
- package/parsers/ruby-parser.js +2680 -0
- package/parsers/ts-parser.js +3881 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const { JSGenerator } = require('./js-generator')
|
|
3
|
+
|
|
4
|
+
class TSGenerator extends JSGenerator {
|
|
5
|
+
constructor(i18nPath = null) {
|
|
6
|
+
super(i18nPath)
|
|
7
|
+
this.extendMaps()
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
extendMaps() {
|
|
11
|
+
const tsTranslations = {
|
|
12
|
+
'type': 'type',
|
|
13
|
+
'interface': 'interface',
|
|
14
|
+
'enum': 'enum',
|
|
15
|
+
'énumération': 'enum',
|
|
16
|
+
'declare': 'declare',
|
|
17
|
+
'déclarer': 'declare',
|
|
18
|
+
'namespace': 'namespace',
|
|
19
|
+
'espace de noms': 'namespace',
|
|
20
|
+
'module': 'module',
|
|
21
|
+
'abstract': 'abstract',
|
|
22
|
+
'abstrait': 'abstract',
|
|
23
|
+
'implements': 'implements',
|
|
24
|
+
'implémente': 'implements',
|
|
25
|
+
'extends': 'extends',
|
|
26
|
+
'étend': 'extends',
|
|
27
|
+
'readonly': 'readonly',
|
|
28
|
+
'lecture seule': 'readonly',
|
|
29
|
+
'public': 'public',
|
|
30
|
+
'private': 'private',
|
|
31
|
+
'privé': 'private',
|
|
32
|
+
'protected': 'protected',
|
|
33
|
+
'protégé': 'protected',
|
|
34
|
+
'override': 'override',
|
|
35
|
+
'remplacer': 'override',
|
|
36
|
+
'keyof': 'keyof',
|
|
37
|
+
'clé de': 'keyof',
|
|
38
|
+
'typeof': 'typeof',
|
|
39
|
+
'type de': 'typeof',
|
|
40
|
+
'infer': 'infer',
|
|
41
|
+
'inférer': 'infer',
|
|
42
|
+
'satisfies': 'satisfies',
|
|
43
|
+
'satisfait': 'satisfies',
|
|
44
|
+
'as': 'as',
|
|
45
|
+
'comme': 'as',
|
|
46
|
+
'is': 'is',
|
|
47
|
+
'est': 'is',
|
|
48
|
+
'asserts': 'asserts',
|
|
49
|
+
'affirme': 'asserts',
|
|
50
|
+
'chaîne': 'string',
|
|
51
|
+
'nombre': 'number',
|
|
52
|
+
'booléen': 'boolean',
|
|
53
|
+
'symbole': 'symbol',
|
|
54
|
+
'vide': 'void',
|
|
55
|
+
'nul type': 'null',
|
|
56
|
+
'indefini type': 'undefined',
|
|
57
|
+
'jamais': 'never',
|
|
58
|
+
'inconnu': 'unknown',
|
|
59
|
+
'quelconque': 'any',
|
|
60
|
+
'objet': 'object',
|
|
61
|
+
'tableau type': 'Array',
|
|
62
|
+
'promesse': 'Promise',
|
|
63
|
+
'partial': 'Partial',
|
|
64
|
+
'partiel': 'Partial',
|
|
65
|
+
'required': 'Required',
|
|
66
|
+
'requis type': 'Required',
|
|
67
|
+
'readonly type': 'Readonly',
|
|
68
|
+
'record': 'Record',
|
|
69
|
+
'enregistrement': 'Record',
|
|
70
|
+
'pick': 'Pick',
|
|
71
|
+
'choisir': 'Pick',
|
|
72
|
+
'omit': 'Omit',
|
|
73
|
+
'omettre': 'Omit',
|
|
74
|
+
'exclude': 'Exclude',
|
|
75
|
+
'exclure': 'Exclude',
|
|
76
|
+
'extract': 'Extract',
|
|
77
|
+
'extraire type': 'Extract',
|
|
78
|
+
'nonnullable': 'NonNullable',
|
|
79
|
+
'non nullable': 'NonNullable',
|
|
80
|
+
'returntype': 'ReturnType',
|
|
81
|
+
'type retour': 'ReturnType',
|
|
82
|
+
'parameters': 'Parameters',
|
|
83
|
+
'paramètres type': 'Parameters',
|
|
84
|
+
'awaited': 'Awaited',
|
|
85
|
+
'attendu type': 'Awaited'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const [fr, ts] of Object.entries(tsTranslations)) {
|
|
89
|
+
this.keywordMap[fr] = ts
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
generateNode(node) {
|
|
94
|
+
if (!node) return ''
|
|
95
|
+
|
|
96
|
+
switch (node.type) {
|
|
97
|
+
case 'TypeAlias':
|
|
98
|
+
case 'TypeAliasDeclaration':
|
|
99
|
+
return this.generateTypeAlias(node)
|
|
100
|
+
case 'InterfaceDeclaration':
|
|
101
|
+
return this.generateInterface(node)
|
|
102
|
+
case 'EnumDeclaration':
|
|
103
|
+
return this.generateEnum(node)
|
|
104
|
+
case 'TypeAnnotation':
|
|
105
|
+
return this.generateTypeAnnotation(node)
|
|
106
|
+
case 'GenericType':
|
|
107
|
+
return this.generateGenericType(node)
|
|
108
|
+
case 'UnionType':
|
|
109
|
+
return this.generateUnionType(node)
|
|
110
|
+
case 'IntersectionType':
|
|
111
|
+
return this.generateIntersectionType(node)
|
|
112
|
+
case 'TupleType':
|
|
113
|
+
return this.generateTupleType(node)
|
|
114
|
+
case 'FunctionType':
|
|
115
|
+
return this.generateFunctionType(node)
|
|
116
|
+
case 'ConditionalType':
|
|
117
|
+
return this.generateConditionalType(node)
|
|
118
|
+
case 'MappedType':
|
|
119
|
+
return this.generateMappedType(node)
|
|
120
|
+
case 'IndexedAccessType':
|
|
121
|
+
return this.generateIndexedAccessType(node)
|
|
122
|
+
case 'TypeAssertion':
|
|
123
|
+
return this.generateTypeAssertion(node)
|
|
124
|
+
case 'NamespaceDeclaration':
|
|
125
|
+
return this.generateNamespace(node)
|
|
126
|
+
default:
|
|
127
|
+
return super.generateNode(node)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
generateTypeAlias(node) {
|
|
132
|
+
const name = node.name
|
|
133
|
+
const typeParams = node.typeParameters ? this.generateTypeParams(node.typeParameters) : ''
|
|
134
|
+
const typeNode = node.aliasType || node.typeValue ||
|
|
135
|
+
(typeof node.type === 'object' ? node.type : null)
|
|
136
|
+
const type = this.generateType(typeNode)
|
|
137
|
+
|
|
138
|
+
this.writeLine(`type ${name}${typeParams} = ${type};`)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
generateInterface(node) {
|
|
142
|
+
const name = node.name
|
|
143
|
+
const typeParams = node.typeParameters ? this.generateTypeParams(node.typeParameters) : ''
|
|
144
|
+
const extend = node.extends && node.extends.length > 0
|
|
145
|
+
? ' extends ' + node.extends.map(e => this.generateType(e)).join(', ')
|
|
146
|
+
: ''
|
|
147
|
+
|
|
148
|
+
this.writeLine(`interface ${name}${typeParams}${extend} {`)
|
|
149
|
+
this.indent++
|
|
150
|
+
|
|
151
|
+
for (const member of node.members || node.properties || []) {
|
|
152
|
+
this.generateInterfaceMember(member)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.indent--
|
|
156
|
+
this.writeLine('}')
|
|
157
|
+
this.writeLine('')
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
generateInterfaceMember(member) {
|
|
161
|
+
const readonly = member.readonly ? 'readonly ' : ''
|
|
162
|
+
const optional = member.optional ? '?' : ''
|
|
163
|
+
const name = member.name || member.key
|
|
164
|
+
|
|
165
|
+
if (member.kind === 'method' || member.method) {
|
|
166
|
+
const typeParams = member.typeParameters ? this.generateTypeParams(member.typeParameters) : ''
|
|
167
|
+
const params = this.generateTypedParams(member.params || member.parameters || [])
|
|
168
|
+
const returnType = this.generateType(member.returnType || member.type || 'void')
|
|
169
|
+
this.writeLine(`${readonly}${name}${optional}${typeParams}(${params}): ${returnType};`)
|
|
170
|
+
} else if (member.kind === 'index' || member.index) {
|
|
171
|
+
const keyName = member.keyName || 'key'
|
|
172
|
+
const keyType = this.generateType(member.keyType || 'string')
|
|
173
|
+
const valueType = this.generateType(member.type || member.valueType || 'any')
|
|
174
|
+
this.writeLine(`[${keyName}: ${keyType}]: ${valueType};`)
|
|
175
|
+
} else {
|
|
176
|
+
const type = this.generateType(member.type || member.value)
|
|
177
|
+
this.writeLine(`${readonly}${name}${optional}: ${type};`)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
generateEnum(node) {
|
|
182
|
+
const name = node.name
|
|
183
|
+
const isConst = node.const ? 'const ' : ''
|
|
184
|
+
|
|
185
|
+
this.writeLine(`${isConst}enum ${name} {`)
|
|
186
|
+
this.indent++
|
|
187
|
+
|
|
188
|
+
const members = node.members || []
|
|
189
|
+
for (let i = 0; i < members.length; i++) {
|
|
190
|
+
const member = members[i]
|
|
191
|
+
const memberName = member.name || member
|
|
192
|
+
const value = member.value !== undefined ? ` = ${this.generateNode(member.value)}` : ''
|
|
193
|
+
this.writeLine(`${memberName}${value},`)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this.indent--
|
|
197
|
+
this.writeLine('}')
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
generateType(type) {
|
|
201
|
+
if (!type) return 'any'
|
|
202
|
+
if (typeof type === 'string') return this.translate(type)
|
|
203
|
+
|
|
204
|
+
const typeKind = type.kind || (typeof type.type === 'string' ? type.type : null)
|
|
205
|
+
|
|
206
|
+
switch (typeKind) {
|
|
207
|
+
case 'string':
|
|
208
|
+
case 'chaîne':
|
|
209
|
+
return 'string'
|
|
210
|
+
case 'number':
|
|
211
|
+
case 'nombre':
|
|
212
|
+
return 'number'
|
|
213
|
+
case 'boolean':
|
|
214
|
+
case 'booléen':
|
|
215
|
+
return 'boolean'
|
|
216
|
+
case 'void':
|
|
217
|
+
return 'void'
|
|
218
|
+
case 'null':
|
|
219
|
+
return 'null'
|
|
220
|
+
case 'undefined':
|
|
221
|
+
return 'undefined'
|
|
222
|
+
case 'any':
|
|
223
|
+
return 'any'
|
|
224
|
+
case 'never':
|
|
225
|
+
return 'never'
|
|
226
|
+
case 'unknown':
|
|
227
|
+
return 'unknown'
|
|
228
|
+
case 'référence':
|
|
229
|
+
const refName = this.translate(type.name)
|
|
230
|
+
if (type.typeArguments) {
|
|
231
|
+
return `${refName}<${type.typeArguments.map(a => this.generateType(a)).join(', ')}>`
|
|
232
|
+
}
|
|
233
|
+
return refName
|
|
234
|
+
case 'literal':
|
|
235
|
+
if (typeof type.value === 'string') return `"${type.value}"`
|
|
236
|
+
if (typeof type.value === 'boolean') return type.value ? 'true' : 'false'
|
|
237
|
+
return String(type.value)
|
|
238
|
+
case 'union':
|
|
239
|
+
return (type.types || []).map(t => this.generateType(t)).join(' | ')
|
|
240
|
+
case 'intersection':
|
|
241
|
+
return (type.types || []).map(t => this.generateType(t)).join(' & ')
|
|
242
|
+
case 'array':
|
|
243
|
+
return `${this.generateType(type.elementType)}[]`
|
|
244
|
+
case 'tuple':
|
|
245
|
+
return `[${(type.elements || type.elementTypes || []).map(e => this.generateType(e)).join(', ')}]`
|
|
246
|
+
case 'generic':
|
|
247
|
+
const base = this.generateType(type.base)
|
|
248
|
+
const args = type.arguments.map(a => this.generateType(a)).join(', ')
|
|
249
|
+
return `${base}<${args}>`
|
|
250
|
+
case 'function':
|
|
251
|
+
const params = this.generateTypedParams(type.parameters || [])
|
|
252
|
+
const ret = this.generateType(type.returnType)
|
|
253
|
+
return `(${params}) => ${ret}`
|
|
254
|
+
case 'object':
|
|
255
|
+
return this.generateObjectType(type)
|
|
256
|
+
case 'conditional':
|
|
257
|
+
const check = this.generateType(type.checkType)
|
|
258
|
+
const ext = this.generateType(type.extendsType)
|
|
259
|
+
const trueT = this.generateType(type.trueType)
|
|
260
|
+
const falseT = this.generateType(type.falseType)
|
|
261
|
+
return `${check} extends ${ext} ? ${trueT} : ${falseT}`
|
|
262
|
+
case 'keyof':
|
|
263
|
+
return `keyof ${this.generateType(type.type || type.operand)}`
|
|
264
|
+
case 'typeof':
|
|
265
|
+
return `typeof ${type.expression || this.generateNode(type.operand)}`
|
|
266
|
+
case 'indexed':
|
|
267
|
+
return `${this.generateType(type.objectType || type.object)}[${this.generateType(type.indexType || type.index)}]`
|
|
268
|
+
case 'mapped':
|
|
269
|
+
return this.generateMappedType(type)
|
|
270
|
+
case 'infer':
|
|
271
|
+
return `infer ${type.name}`
|
|
272
|
+
case 'template':
|
|
273
|
+
return this.generateTemplateLiteralType(type)
|
|
274
|
+
default:
|
|
275
|
+
if (type.name) {
|
|
276
|
+
const name = this.translate(type.name)
|
|
277
|
+
if (type.typeArguments) {
|
|
278
|
+
return `${name}<${type.typeArguments.map(a => this.generateType(a)).join(', ')}>`
|
|
279
|
+
}
|
|
280
|
+
return name
|
|
281
|
+
}
|
|
282
|
+
return 'any'
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
generateTemplateLiteralType(type) {
|
|
287
|
+
const parts = (type.parts || []).map(p => {
|
|
288
|
+
if (typeof p === 'string') return p
|
|
289
|
+
if (p.name) return '${' + this.generateType(p) + '}'
|
|
290
|
+
return this.generateType(p)
|
|
291
|
+
})
|
|
292
|
+
return '`' + parts.join('') + '`'
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
generateObjectType(type) {
|
|
296
|
+
const members = (type.members || type.properties || []).map(m => {
|
|
297
|
+
const readonly = m.readonly ? 'readonly ' : ''
|
|
298
|
+
const optional = m.optional ? '?' : ''
|
|
299
|
+
const name = m.name || m.key
|
|
300
|
+
const memberType = this.generateType(m.type || m.value)
|
|
301
|
+
return `${readonly}${name}${optional}: ${memberType}`
|
|
302
|
+
})
|
|
303
|
+
return `{ ${members.join('; ')} }`
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
generateLiteralType(type) {
|
|
307
|
+
if (typeof type.value === 'string') return `"${type.value}"`
|
|
308
|
+
if (typeof type.value === 'boolean') return type.value ? 'true' : 'false'
|
|
309
|
+
return String(type.value)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
generateMappedType(type) {
|
|
313
|
+
const readonly = type.readonly ? (type.readonly === '-' ? '-readonly ' : 'readonly ') : ''
|
|
314
|
+
const optional = type.optional ? (type.optional === '-' ? '-?' : '?') : ''
|
|
315
|
+
|
|
316
|
+
let key, constraint
|
|
317
|
+
if (type.typeParameter) {
|
|
318
|
+
key = type.typeParameter.name || 'K'
|
|
319
|
+
constraint = this.generateType(type.typeParameter.constraint)
|
|
320
|
+
} else {
|
|
321
|
+
key = type.key || 'K'
|
|
322
|
+
constraint = this.generateType(type.constraint)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const as = type.as ? ` as ${this.generateType(type.as)}` : ''
|
|
326
|
+
const valueType = this.generateType(type.valueType || type.value || type.type)
|
|
327
|
+
|
|
328
|
+
return `{ ${readonly}[${key} in ${constraint}${as}]${optional}: ${valueType} }`
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
generateTypeParams(params) {
|
|
332
|
+
const items = params.map(p => {
|
|
333
|
+
let param = p.name || p
|
|
334
|
+
if (p.constraint) {
|
|
335
|
+
param += ` extends ${this.generateType(p.constraint)}`
|
|
336
|
+
}
|
|
337
|
+
if (p.default) {
|
|
338
|
+
param += ` = ${this.generateType(p.default)}`
|
|
339
|
+
}
|
|
340
|
+
return param
|
|
341
|
+
})
|
|
342
|
+
return `<${items.join(', ')}>`
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
generateTypedParams(params) {
|
|
346
|
+
return params.map(p => {
|
|
347
|
+
let param = ''
|
|
348
|
+
if (p.rest) param += '...'
|
|
349
|
+
param += p.name || p.arg || p
|
|
350
|
+
if (p.optional) param += '?'
|
|
351
|
+
if (p.type) param += ': ' + this.generateType(p.type)
|
|
352
|
+
if (p.default !== undefined) {
|
|
353
|
+
param += ' = ' + this.generateNode(p.default)
|
|
354
|
+
}
|
|
355
|
+
return param
|
|
356
|
+
}).join(', ')
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
generateTypeAnnotation(node) {
|
|
360
|
+
return this.generateType(node.typeAnnotation || node.type)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
generateGenericType(node) {
|
|
364
|
+
const base = this.generateType(node.base || node.name)
|
|
365
|
+
const args = (node.typeArguments || node.arguments || []).map(a => this.generateType(a))
|
|
366
|
+
return `${base}<${args.join(', ')}>`
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
generateUnionType(node) {
|
|
370
|
+
return (node.types || []).map(t => this.generateType(t)).join(' | ')
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
generateIntersectionType(node) {
|
|
374
|
+
return (node.types || []).map(t => this.generateType(t)).join(' & ')
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
generateTupleType(node) {
|
|
378
|
+
const elements = (node.elements || node.types || []).map(e => {
|
|
379
|
+
if (e.optional) return this.generateType(e.type) + '?'
|
|
380
|
+
if (e.rest) return '...' + this.generateType(e.type)
|
|
381
|
+
return this.generateType(e)
|
|
382
|
+
})
|
|
383
|
+
return `[${elements.join(', ')}]`
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
generateFunctionType(node) {
|
|
387
|
+
const params = this.generateTypedParams(node.parameters || [])
|
|
388
|
+
const returnType = this.generateType(node.returnType)
|
|
389
|
+
return `(${params}) => ${returnType}`
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
generateConditionalType(node) {
|
|
393
|
+
const check = this.generateType(node.checkType)
|
|
394
|
+
const ext = this.generateType(node.extendsType)
|
|
395
|
+
const trueType = this.generateType(node.trueType)
|
|
396
|
+
const falseType = this.generateType(node.falseType)
|
|
397
|
+
return `${check} extends ${ext} ? ${trueType} : ${falseType}`
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
generateIndexedAccessType(node) {
|
|
401
|
+
const object = this.generateType(node.objectType)
|
|
402
|
+
const index = this.generateType(node.indexType)
|
|
403
|
+
return `${object}[${index}]`
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
generateTypeAssertion(node) {
|
|
407
|
+
const expression = this.generateNode(node.expression)
|
|
408
|
+
const typeNode = node.typeAnnotation || node.assertedType ||
|
|
409
|
+
(node.type !== 'TypeAssertion' ? node.type : null)
|
|
410
|
+
const type = this.generateType(typeNode)
|
|
411
|
+
|
|
412
|
+
if (node.asStyle !== false) {
|
|
413
|
+
return `${expression} as ${type}`
|
|
414
|
+
}
|
|
415
|
+
return `<${type}>${expression}`
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
generateNamespace(node) {
|
|
419
|
+
const name = node.name
|
|
420
|
+
this.writeLine(`namespace ${name} {`)
|
|
421
|
+
this.indent++
|
|
422
|
+
|
|
423
|
+
for (const member of node.body || node.members || []) {
|
|
424
|
+
const exported = member.exported ? 'export ' : ''
|
|
425
|
+
if (exported) {
|
|
426
|
+
this.output += this.getIndent() + 'export '
|
|
427
|
+
}
|
|
428
|
+
this.generateNode(member)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
this.indent--
|
|
432
|
+
this.writeLine('}')
|
|
433
|
+
this.writeLine('')
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
generateVariableDeclaration(node) {
|
|
437
|
+
const kind = this.translate(node.kind || 'let')
|
|
438
|
+
|
|
439
|
+
for (const decl of node.declarations || []) {
|
|
440
|
+
let name
|
|
441
|
+
if (typeof decl.id === 'string') {
|
|
442
|
+
name = decl.id
|
|
443
|
+
} else if (decl.id?.name) {
|
|
444
|
+
name = decl.id.name
|
|
445
|
+
} else if (typeof decl.name === 'string') {
|
|
446
|
+
name = decl.name
|
|
447
|
+
} else if (decl.name?.name) {
|
|
448
|
+
name = decl.name.name
|
|
449
|
+
} else {
|
|
450
|
+
name = this.generateNode(decl.id || decl.name)
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const typeNode = decl.typeAnnotation || decl.type
|
|
454
|
+
const type = typeNode ? ': ' + this.generateType(typeNode) : ''
|
|
455
|
+
|
|
456
|
+
if (decl.init) {
|
|
457
|
+
const init = this.generateNode(decl.init)
|
|
458
|
+
this.writeLine(`${kind} ${name}${type} = ${init};`)
|
|
459
|
+
} else {
|
|
460
|
+
this.writeLine(`${kind} ${name}${type};`)
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
generateFunctionDeclaration(node) {
|
|
466
|
+
const async = node.async ? 'async ' : ''
|
|
467
|
+
const generator = node.generator ? '*' : ''
|
|
468
|
+
const name = this.translate(node.id?.name || node.name || '')
|
|
469
|
+
const typeParams = node.typeParameters ? this.generateTypeParams(node.typeParameters) : ''
|
|
470
|
+
const params = this.generateTypedParams(node.params || [])
|
|
471
|
+
const returnType = node.returnType ? ': ' + this.generateType(node.returnType) : ''
|
|
472
|
+
|
|
473
|
+
this.writeLine(`${async}function${generator} ${name}${typeParams}(${params})${returnType} {`)
|
|
474
|
+
this.indent++
|
|
475
|
+
this.generateNode(node.body)
|
|
476
|
+
this.indent--
|
|
477
|
+
this.writeLine('}')
|
|
478
|
+
this.writeLine('')
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
generateClassDeclaration(node) {
|
|
482
|
+
const abstract = node.abstract ? 'abstract ' : ''
|
|
483
|
+
const name = this.translate(node.id?.name || node.name || '')
|
|
484
|
+
const typeParams = node.typeParameters ? this.generateTypeParams(node.typeParameters) : ''
|
|
485
|
+
const extend = node.superClass ? ` extends ${this.generateNode(node.superClass)}` : ''
|
|
486
|
+
const implement = node.implements && node.implements.length > 0
|
|
487
|
+
? ` implements ${node.implements.map(i => this.generateType(i)).join(', ')}`
|
|
488
|
+
: ''
|
|
489
|
+
|
|
490
|
+
this.writeLine(`${abstract}class ${name}${typeParams}${extend}${implement} {`)
|
|
491
|
+
this.indent++
|
|
492
|
+
|
|
493
|
+
const body = node.body?.body || node.body || []
|
|
494
|
+
for (const member of body) {
|
|
495
|
+
this.generateClassMemberTS(member)
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
this.indent--
|
|
499
|
+
this.writeLine('}')
|
|
500
|
+
this.writeLine('')
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
generateClassMemberTS(node) {
|
|
504
|
+
const visibility = node.accessibility || node.visibility || ''
|
|
505
|
+
const isStatic = node.static ? 'static ' : ''
|
|
506
|
+
const readonly = node.readonly ? 'readonly ' : ''
|
|
507
|
+
const abstract = node.abstract ? 'abstract ' : ''
|
|
508
|
+
const override = node.override ? 'override ' : ''
|
|
509
|
+
|
|
510
|
+
const modifiers = [visibility, isStatic, readonly, abstract, override].filter(m => m).join(' ')
|
|
511
|
+
|
|
512
|
+
if (node.kind === 'property' || node.type === 'PropertyDefinition' || node.property) {
|
|
513
|
+
const name = this.translate(node.key?.name || node.name || '')
|
|
514
|
+
const optional = node.optional ? '?' : ''
|
|
515
|
+
const typeNode = node.typeAnnotation || node.type
|
|
516
|
+
const type = typeNode && typeof typeNode === 'object' ? ': ' + this.generateType(typeNode) : ''
|
|
517
|
+
const value = node.value ? ' = ' + this.generateNode(node.value) : ''
|
|
518
|
+
this.writeLine(`${modifiers}${name}${optional}${type}${value};`)
|
|
519
|
+
return
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const name = this.translate(node.key?.name || node.name || '')
|
|
523
|
+
const typeParams = node.typeParameters ? this.generateTypeParams(node.typeParameters) : ''
|
|
524
|
+
const params = this.generateTypedParams(node.value?.params || node.params || [])
|
|
525
|
+
const returnType = node.returnType ? ': ' + this.generateType(node.returnType) : ''
|
|
526
|
+
|
|
527
|
+
if (name === 'constructor' || name === 'constructeur') {
|
|
528
|
+
this.writeLine(`constructor(${params}) {`)
|
|
529
|
+
} else if (node.kind === 'get') {
|
|
530
|
+
this.writeLine(`${modifiers}get ${name}()${returnType} {`)
|
|
531
|
+
} else if (node.kind === 'set') {
|
|
532
|
+
this.writeLine(`${modifiers}set ${name}(${params}) {`)
|
|
533
|
+
} else {
|
|
534
|
+
const async = node.value?.async || node.async ? 'async ' : ''
|
|
535
|
+
this.writeLine(`${modifiers}${async}${name}${typeParams}(${params})${returnType} {`)
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
this.indent++
|
|
539
|
+
this.generateNode(node.value?.body || node.body)
|
|
540
|
+
this.indent--
|
|
541
|
+
this.writeLine('}')
|
|
542
|
+
this.writeLine('')
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
generateArrowFunction(node) {
|
|
546
|
+
const async = node.async ? 'async ' : ''
|
|
547
|
+
const params = this.generateTypedParams(node.params || [])
|
|
548
|
+
const returnType = node.returnType ? ': ' + this.generateType(node.returnType) : ''
|
|
549
|
+
|
|
550
|
+
if (node.body?.type === 'BlockStatement') {
|
|
551
|
+
let body = ''
|
|
552
|
+
const savedOutput = this.output
|
|
553
|
+
this.output = ''
|
|
554
|
+
this.indent++
|
|
555
|
+
this.generateNode(node.body)
|
|
556
|
+
this.indent--
|
|
557
|
+
body = this.output.trim()
|
|
558
|
+
this.output = savedOutput
|
|
559
|
+
return `${async}(${params})${returnType} => {\n${body}\n${this.getIndent()}}`
|
|
560
|
+
} else {
|
|
561
|
+
const body = this.generateNode(node.body)
|
|
562
|
+
return `${async}(${params})${returnType} => ${body}`
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
module.exports = {
|
|
568
|
+
TSGenerator
|
|
569
|
+
}
|