@typemf/generator 0.5.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 +201 -0
- package/README.md +79 -0
- package/dist/cli.js +1612 -0
- package/dist/index.d.ts +741 -0
- package/dist/index.js +1678 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
- package/templates/typescript/eclass.njk +559 -0
- package/templates/typescript/eenum.njk +8 -0
- package/templates/typescript/efactory.njk +52 -0
- package/templates/typescript/epackage.njk +438 -0
- package/templates/typescript/epackageref.njk +46 -0
- package/templates/typescript/eswitch.njk +32 -0
- package/templates/typescript/etypeguards.njk +30 -0
- package/templates/typescript/main.njk +19 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1678 @@
|
|
|
1
|
+
// src/cli-config.ts
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
async function loadConfig(configPath) {
|
|
4
|
+
let raw;
|
|
5
|
+
try {
|
|
6
|
+
raw = await readFile(configPath, "utf-8");
|
|
7
|
+
} catch (err) {
|
|
8
|
+
throw new Error(`Could not read config file '${configPath}': ${err.message}`, { cause: err });
|
|
9
|
+
}
|
|
10
|
+
let parsed;
|
|
11
|
+
try {
|
|
12
|
+
parsed = JSON.parse(raw);
|
|
13
|
+
} catch (err) {
|
|
14
|
+
throw new Error(`Failed to parse '${configPath}' as JSON: ${err.message}`, { cause: err });
|
|
15
|
+
}
|
|
16
|
+
return validateConfig(parsed, configPath);
|
|
17
|
+
}
|
|
18
|
+
function validateConfig(value, configPath) {
|
|
19
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
20
|
+
throw new Error(`'${configPath}' must contain a JSON object.`);
|
|
21
|
+
}
|
|
22
|
+
const obj = value;
|
|
23
|
+
for (const key of ["ecoreFile", "outputDir", "templateSet"]) {
|
|
24
|
+
if (typeof obj[key] !== "string" || obj[key] === "") {
|
|
25
|
+
throw new Error(`'${configPath}': "${key}" is required and must be a non-empty string.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (obj.options !== void 0 && (typeof obj.options !== "object" || obj.options === null || Array.isArray(obj.options))) {
|
|
29
|
+
throw new Error(`'${configPath}': "options", if present, must be a JSON object.`);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
ecoreFile: obj.ecoreFile,
|
|
33
|
+
outputDir: obj.outputDir,
|
|
34
|
+
templateSet: obj.templateSet,
|
|
35
|
+
options: obj.options ?? {}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/ecore-loader.ts
|
|
40
|
+
import { EcorePackageImpl as EcorePackageImpl2, ResourceSetImpl, URI } from "@typemf/core";
|
|
41
|
+
import { NodeFileUriConverter } from "@typemf/node";
|
|
42
|
+
import { registerXmiFormat } from "@typemf/xmi";
|
|
43
|
+
|
|
44
|
+
// src/ecore-dynamic-to-typed.ts
|
|
45
|
+
import {
|
|
46
|
+
EAnnotationImpl,
|
|
47
|
+
EAttributeImpl,
|
|
48
|
+
setDetailValue,
|
|
49
|
+
EClassImpl,
|
|
50
|
+
EcorePackageImpl,
|
|
51
|
+
EDataTypeImpl,
|
|
52
|
+
EEnumImpl,
|
|
53
|
+
EEnumLiteralImpl,
|
|
54
|
+
EGenericTypeImpl,
|
|
55
|
+
EOperationImpl,
|
|
56
|
+
EPackageImpl,
|
|
57
|
+
ETypeParameterImpl,
|
|
58
|
+
EParameterImpl,
|
|
59
|
+
EReferenceImpl,
|
|
60
|
+
isEClassifier,
|
|
61
|
+
resolveAgainstPackage
|
|
62
|
+
} from "@typemf/core";
|
|
63
|
+
function convertDynamicEcoreToTyped(dynamicPkg) {
|
|
64
|
+
const realPkg = new EPackageImpl();
|
|
65
|
+
realPkg.setName(byName(dynamicPkg, "name") ?? "");
|
|
66
|
+
realPkg.setNsURI(byName(dynamicPkg, "nsURI") ?? "");
|
|
67
|
+
realPkg.setNsPrefix(byName(dynamicPkg, "nsPrefix") ?? "");
|
|
68
|
+
copyAnnotations(dynamicPkg, realPkg);
|
|
69
|
+
const dynamicClassifiers = listByName(dynamicPkg, "eClassifiers");
|
|
70
|
+
const classifierMap = /* @__PURE__ */ new Map();
|
|
71
|
+
const featureMap = /* @__PURE__ */ new Map();
|
|
72
|
+
const typeParameterMap = /* @__PURE__ */ new Map();
|
|
73
|
+
for (const dyn of dynamicClassifiers) {
|
|
74
|
+
const kind = dyn.eClass().getName();
|
|
75
|
+
const name = byName(dyn, "name") ?? "";
|
|
76
|
+
if (name === "EObject") {
|
|
77
|
+
classifierMap.set(dyn, void 0);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (kind === "EClass") {
|
|
81
|
+
const c = new EClassImpl();
|
|
82
|
+
c.setName(name);
|
|
83
|
+
copyAnnotations(dyn, c);
|
|
84
|
+
classifierMap.set(dyn, c);
|
|
85
|
+
} else if (kind === "EEnum") {
|
|
86
|
+
const e = new EEnumImpl();
|
|
87
|
+
e.setName(name);
|
|
88
|
+
copyAnnotations(dyn, e);
|
|
89
|
+
classifierMap.set(dyn, e);
|
|
90
|
+
} else {
|
|
91
|
+
const d = new EDataTypeImpl();
|
|
92
|
+
d.setName(name);
|
|
93
|
+
copyAnnotations(dyn, d);
|
|
94
|
+
classifierMap.set(dyn, d);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function classifierOf(dynClassifier) {
|
|
98
|
+
if (classifierMap.has(dynClassifier)) return classifierMap.get(dynClassifier);
|
|
99
|
+
const uri = dynClassifier.eIsProxy() ? dynClassifier.getProxyURI() : void 0;
|
|
100
|
+
const ecore = EcorePackageImpl.eINSTANCE;
|
|
101
|
+
if (uri && uri.trimFragment().toString() === ecore.getNsURI()) {
|
|
102
|
+
const fragment = uri.getFragment() ?? "";
|
|
103
|
+
if (fragment === "//EObject") return void 0;
|
|
104
|
+
const resolved = resolveAgainstPackage(ecore, fragment);
|
|
105
|
+
if (isEClassifier(resolved)) return resolved;
|
|
106
|
+
}
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Cannot resolve the classifier reference '${uri?.toString() ?? dynClassifier.fullId()}': only classifiers of this package and of Ecore are supported.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
function resolveType(dynFeature) {
|
|
112
|
+
const dynType = byNameRaw(dynFeature, "eType");
|
|
113
|
+
if (dynType) return classifierOf(dynType);
|
|
114
|
+
const dynGeneric = byNameRaw(dynFeature, "eGenericType");
|
|
115
|
+
if (dynGeneric) {
|
|
116
|
+
const dynClassifier = byNameRaw(dynGeneric, "eClassifier");
|
|
117
|
+
if (dynClassifier) return classifierOf(dynClassifier);
|
|
118
|
+
}
|
|
119
|
+
return void 0;
|
|
120
|
+
}
|
|
121
|
+
function convertGenericType(dynGeneric) {
|
|
122
|
+
const gt = new EGenericTypeImpl();
|
|
123
|
+
const dynClassifier = byNameRaw(dynGeneric, "eClassifier");
|
|
124
|
+
if (dynClassifier) gt.setEClassifier(classifierOf(dynClassifier));
|
|
125
|
+
const dynParameter = byNameRaw(dynGeneric, "eTypeParameter");
|
|
126
|
+
if (dynParameter) gt.setETypeParameter(typeParameterMap.get(dynParameter));
|
|
127
|
+
for (const dynArgument of listByName(dynGeneric, "eTypeArguments")) {
|
|
128
|
+
gt.getETypeArguments().add(convertGenericType(dynArgument));
|
|
129
|
+
}
|
|
130
|
+
return gt;
|
|
131
|
+
}
|
|
132
|
+
function applyType(dynTyped, real) {
|
|
133
|
+
const dynGeneric = byNameRaw(dynTyped, "eGenericType");
|
|
134
|
+
if (dynGeneric) {
|
|
135
|
+
real.setEGenericType(convertGenericType(dynGeneric));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const type = resolveType(dynTyped);
|
|
139
|
+
if (type) real.setEType(type);
|
|
140
|
+
}
|
|
141
|
+
for (const dyn of dynamicClassifiers) {
|
|
142
|
+
const real = classifierMap.get(dyn);
|
|
143
|
+
if (!real) continue;
|
|
144
|
+
const kind = dyn.eClass().getName();
|
|
145
|
+
for (const dynParameter of listByName(dyn, "eTypeParameters")) {
|
|
146
|
+
const parameter = new ETypeParameterImpl();
|
|
147
|
+
parameter.setName(byName(dynParameter, "name") ?? "");
|
|
148
|
+
real.getETypeParameters().add(parameter);
|
|
149
|
+
typeParameterMap.set(dynParameter, parameter);
|
|
150
|
+
}
|
|
151
|
+
const instanceClassName = byName(dyn, "instanceClassName");
|
|
152
|
+
if (instanceClassName !== void 0 && instanceClassName !== "") real.setInstanceClassName(instanceClassName);
|
|
153
|
+
if (kind === "EClass") {
|
|
154
|
+
const c = real;
|
|
155
|
+
if (byName(dyn, "abstract")) c.setAbstract(true);
|
|
156
|
+
if (byName(dyn, "interface")) c.setInterface(true);
|
|
157
|
+
for (const dynSuper of listByName(dyn, "eSuperTypes")) {
|
|
158
|
+
const realSuper = classifierOf(dynSuper);
|
|
159
|
+
if (realSuper) c.getESuperTypes().add(realSuper);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
for (const dyn of dynamicClassifiers) {
|
|
164
|
+
const real = classifierMap.get(dyn);
|
|
165
|
+
if (!real || dyn.eClass().getName() !== "EClass") continue;
|
|
166
|
+
const realClass = real;
|
|
167
|
+
for (const dynFeature of listByName(dyn, "eStructuralFeatures")) {
|
|
168
|
+
const featureKind = dynFeature.eClass().getName();
|
|
169
|
+
const name = byName(dynFeature, "name") ?? "";
|
|
170
|
+
const lowerBound = byName(dynFeature, "lowerBound");
|
|
171
|
+
const upperBound = byName(dynFeature, "upperBound");
|
|
172
|
+
if (featureKind === "EReference") {
|
|
173
|
+
const r = new EReferenceImpl();
|
|
174
|
+
r.setName(name);
|
|
175
|
+
applyType(dynFeature, r);
|
|
176
|
+
if (typeof lowerBound === "number") r.setLowerBound(lowerBound);
|
|
177
|
+
if (typeof upperBound === "number") r.setUpperBound(upperBound);
|
|
178
|
+
if (byName(dynFeature, "containment")) r.setContainment(true);
|
|
179
|
+
if (byName(dynFeature, "resolveProxies") === false) r.setResolveProxies(false);
|
|
180
|
+
r.setEContainingClass(realClass);
|
|
181
|
+
copyFeatureFlags(dynFeature, r);
|
|
182
|
+
copyAnnotations(dynFeature, r);
|
|
183
|
+
realClass.getEStructuralFeatures().add(r);
|
|
184
|
+
featureMap.set(dynFeature, r);
|
|
185
|
+
} else {
|
|
186
|
+
const a = new EAttributeImpl();
|
|
187
|
+
a.setName(name);
|
|
188
|
+
applyType(dynFeature, a);
|
|
189
|
+
if (typeof lowerBound === "number") a.setLowerBound(lowerBound);
|
|
190
|
+
if (typeof upperBound === "number") a.setUpperBound(upperBound);
|
|
191
|
+
if (byName(dynFeature, "iD")) a.setID(true);
|
|
192
|
+
copyFeatureFlags(dynFeature, a);
|
|
193
|
+
a.setEContainingClass(realClass);
|
|
194
|
+
copyAnnotations(dynFeature, a);
|
|
195
|
+
realClass.getEStructuralFeatures().add(a);
|
|
196
|
+
featureMap.set(dynFeature, a);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
for (const dynOp of listByName(dyn, "eOperations")) {
|
|
200
|
+
const op = new EOperationImpl();
|
|
201
|
+
op.setName(byName(dynOp, "name") ?? "");
|
|
202
|
+
applyType(dynOp, op);
|
|
203
|
+
copyAnnotations(dynOp, op);
|
|
204
|
+
const opLowerBound = byName(dynOp, "lowerBound");
|
|
205
|
+
const opUpperBound = byName(dynOp, "upperBound");
|
|
206
|
+
if (typeof opLowerBound === "number") op.setLowerBound(opLowerBound);
|
|
207
|
+
if (typeof opUpperBound === "number") op.setUpperBound(opUpperBound);
|
|
208
|
+
for (const dynParam of listByName(dynOp, "eParameters")) {
|
|
209
|
+
const param = new EParameterImpl();
|
|
210
|
+
param.setName(byName(dynParam, "name") ?? "");
|
|
211
|
+
applyType(dynParam, param);
|
|
212
|
+
const paramLowerBound = byName(dynParam, "lowerBound");
|
|
213
|
+
const paramUpperBound = byName(dynParam, "upperBound");
|
|
214
|
+
if (typeof paramLowerBound === "number") param.setLowerBound(paramLowerBound);
|
|
215
|
+
if (typeof paramUpperBound === "number") param.setUpperBound(paramUpperBound);
|
|
216
|
+
op.getEParameters().add(param);
|
|
217
|
+
}
|
|
218
|
+
realClass.getEOperations().add(op);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
for (const dyn of dynamicClassifiers) {
|
|
222
|
+
const real = classifierMap.get(dyn);
|
|
223
|
+
if (!real || dyn.eClass().getName() !== "EEnum") continue;
|
|
224
|
+
for (const dynLiteral of listByName(dyn, "eLiterals")) {
|
|
225
|
+
const lit = new EEnumLiteralImpl();
|
|
226
|
+
lit.setName(byName(dynLiteral, "name") ?? "");
|
|
227
|
+
lit.setValue(byName(dynLiteral, "value") ?? 0);
|
|
228
|
+
lit.setLiteral(byName(dynLiteral, "literal") ?? byName(dynLiteral, "name") ?? "");
|
|
229
|
+
copyAnnotations(dynLiteral, lit);
|
|
230
|
+
real.getELiterals().add(lit);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
for (const [dynFeature, realFeature] of featureMap) {
|
|
234
|
+
const dynOpposite = byNameRaw(dynFeature, "eOpposite");
|
|
235
|
+
if (!dynOpposite) continue;
|
|
236
|
+
const realOpposite = featureMap.get(dynOpposite);
|
|
237
|
+
if (realOpposite && "setEOpposite" in realFeature) {
|
|
238
|
+
realFeature.setEOpposite(realOpposite);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
for (const real of classifierMap.values()) {
|
|
242
|
+
if (real) realPkg.getEClassifiers().add(real);
|
|
243
|
+
}
|
|
244
|
+
return realPkg;
|
|
245
|
+
}
|
|
246
|
+
function copyAnnotations(dyn, real) {
|
|
247
|
+
for (const dynAnnotation of listByName(dyn, "eAnnotations")) {
|
|
248
|
+
const annotation = new EAnnotationImpl();
|
|
249
|
+
const source = byName(dynAnnotation, "source");
|
|
250
|
+
if (source !== void 0) annotation.setSource(source);
|
|
251
|
+
for (const dynDetail of listByName(dynAnnotation, "details")) {
|
|
252
|
+
const key = byName(dynDetail, "key");
|
|
253
|
+
const value = byName(dynDetail, "value");
|
|
254
|
+
if (key !== void 0 && value !== void 0) {
|
|
255
|
+
setDetailValue(annotation.getDetails(), key, value);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
real.getEAnnotations().add(annotation);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function copyFeatureFlags(dyn, real) {
|
|
262
|
+
const changeable = byName(dyn, "changeable");
|
|
263
|
+
if (changeable === false) real.setChangeable(false);
|
|
264
|
+
if (byName(dyn, "volatile")) real.setVolatile(true);
|
|
265
|
+
if (byName(dyn, "transient")) real.setTransient(true);
|
|
266
|
+
if (byName(dyn, "derived")) real.setDerived(true);
|
|
267
|
+
if (byName(dyn, "unsettable")) real.setUnsettable(true);
|
|
268
|
+
const defaultValueLiteral = byName(dyn, "defaultValueLiteral");
|
|
269
|
+
if (defaultValueLiteral !== void 0) real.setDefaultValueLiteral(defaultValueLiteral);
|
|
270
|
+
}
|
|
271
|
+
function byNameRaw(obj, featureName) {
|
|
272
|
+
const feature = obj.eClass().getEStructuralFeature(featureName);
|
|
273
|
+
if (!feature) return void 0;
|
|
274
|
+
return obj.eGet(feature);
|
|
275
|
+
}
|
|
276
|
+
function byName(obj, featureName) {
|
|
277
|
+
return byNameRaw(obj, featureName);
|
|
278
|
+
}
|
|
279
|
+
function listByName(obj, featureName) {
|
|
280
|
+
const value = byNameRaw(obj, featureName);
|
|
281
|
+
if (!value) return [];
|
|
282
|
+
return [...value];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/ecore-meta-schema.ts
|
|
286
|
+
import {
|
|
287
|
+
DynamicEFactoryImpl,
|
|
288
|
+
EAttributeImpl as EAttributeImpl2,
|
|
289
|
+
EClassImpl as EClassImpl2,
|
|
290
|
+
EDataTypeImpl as EDataTypeImpl2,
|
|
291
|
+
EPackageImpl as EPackageImpl2,
|
|
292
|
+
EReferenceImpl as EReferenceImpl2
|
|
293
|
+
} from "@typemf/core";
|
|
294
|
+
|
|
295
|
+
// src/id-assignment.ts
|
|
296
|
+
function assignFreshIds(pkg) {
|
|
297
|
+
let classifierId = 0;
|
|
298
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
299
|
+
classifier.setClassifierID(classifierId++);
|
|
300
|
+
}
|
|
301
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
302
|
+
if (!isEClass(classifier)) continue;
|
|
303
|
+
classifier.getEAllStructuralFeatures().forEach((feature, index) => feature.setFeatureID(index));
|
|
304
|
+
classifier.getEAllOperations().forEach((op, index) => op.setOperationID(index));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function isEClass(classifier) {
|
|
308
|
+
return "getEStructuralFeatures" in classifier;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/ecore-meta-schema.ts
|
|
312
|
+
function buildEcoreMetaSchema() {
|
|
313
|
+
const primitiveNames = [
|
|
314
|
+
"EBigDecimal",
|
|
315
|
+
"EBigInteger",
|
|
316
|
+
"EBoolean",
|
|
317
|
+
"EBooleanObject",
|
|
318
|
+
"EByte",
|
|
319
|
+
"EByteArray",
|
|
320
|
+
"EByteObject",
|
|
321
|
+
"EChar",
|
|
322
|
+
"ECharacterObject",
|
|
323
|
+
"EDate",
|
|
324
|
+
"EDiagnosticChain",
|
|
325
|
+
"EDouble",
|
|
326
|
+
"EDoubleObject",
|
|
327
|
+
"EEList",
|
|
328
|
+
"EEnumerator",
|
|
329
|
+
"EFeatureMap",
|
|
330
|
+
"EFeatureMapEntry",
|
|
331
|
+
"EFloat",
|
|
332
|
+
"EFloatObject",
|
|
333
|
+
"EInt",
|
|
334
|
+
"EIntegerObject",
|
|
335
|
+
"EJavaClass",
|
|
336
|
+
"EJavaObject",
|
|
337
|
+
"ELong",
|
|
338
|
+
"ELongObject",
|
|
339
|
+
"EMap",
|
|
340
|
+
"EResource",
|
|
341
|
+
"EResourceSet",
|
|
342
|
+
"EShort",
|
|
343
|
+
"EShortObject",
|
|
344
|
+
"EString",
|
|
345
|
+
"ETreeIterator",
|
|
346
|
+
"EInvocationTargetException"
|
|
347
|
+
];
|
|
348
|
+
const primitives = new Map(
|
|
349
|
+
primitiveNames.map((n) => [
|
|
350
|
+
n,
|
|
351
|
+
(() => {
|
|
352
|
+
const d = new EDataTypeImpl2();
|
|
353
|
+
d.setName(n);
|
|
354
|
+
return d;
|
|
355
|
+
})()
|
|
356
|
+
])
|
|
357
|
+
);
|
|
358
|
+
const p = (name) => primitives.get(name);
|
|
359
|
+
const eObject = new EClassImpl2();
|
|
360
|
+
eObject.setName("EObject");
|
|
361
|
+
const eModelElement = new EClassImpl2();
|
|
362
|
+
eModelElement.setName("EModelElement");
|
|
363
|
+
eModelElement.setAbstract(true);
|
|
364
|
+
const eAnnotation = new EClassImpl2();
|
|
365
|
+
eAnnotation.setName("EAnnotation");
|
|
366
|
+
const eNamedElement = new EClassImpl2();
|
|
367
|
+
eNamedElement.setName("ENamedElement");
|
|
368
|
+
eNamedElement.setAbstract(true);
|
|
369
|
+
const eTypedElement = new EClassImpl2();
|
|
370
|
+
eTypedElement.setName("ETypedElement");
|
|
371
|
+
eTypedElement.setAbstract(true);
|
|
372
|
+
const eClassifier = new EClassImpl2();
|
|
373
|
+
eClassifier.setName("EClassifier");
|
|
374
|
+
eClassifier.setAbstract(true);
|
|
375
|
+
const eStructuralFeature = new EClassImpl2();
|
|
376
|
+
eStructuralFeature.setName("EStructuralFeature");
|
|
377
|
+
eStructuralFeature.setAbstract(true);
|
|
378
|
+
const eAttribute = new EClassImpl2();
|
|
379
|
+
eAttribute.setName("EAttribute");
|
|
380
|
+
const eReference = new EClassImpl2();
|
|
381
|
+
eReference.setName("EReference");
|
|
382
|
+
const eClass = new EClassImpl2();
|
|
383
|
+
eClass.setName("EClass");
|
|
384
|
+
const ePackage = new EClassImpl2();
|
|
385
|
+
ePackage.setName("EPackage");
|
|
386
|
+
const eDataType = new EClassImpl2();
|
|
387
|
+
eDataType.setName("EDataType");
|
|
388
|
+
const eEnum = new EClassImpl2();
|
|
389
|
+
eEnum.setName("EEnum");
|
|
390
|
+
const eEnumLiteral = new EClassImpl2();
|
|
391
|
+
eEnumLiteral.setName("EEnumLiteral");
|
|
392
|
+
const eFactory = new EClassImpl2();
|
|
393
|
+
eFactory.setName("EFactory");
|
|
394
|
+
const eOperation = new EClassImpl2();
|
|
395
|
+
eOperation.setName("EOperation");
|
|
396
|
+
const eParameter = new EClassImpl2();
|
|
397
|
+
eParameter.setName("EParameter");
|
|
398
|
+
const eStringToStringMapEntry = new EClassImpl2();
|
|
399
|
+
eStringToStringMapEntry.setName("EStringToStringMapEntry");
|
|
400
|
+
const eGenericType = new EClassImpl2();
|
|
401
|
+
eGenericType.setName("EGenericType");
|
|
402
|
+
const eTypeParameter = new EClassImpl2();
|
|
403
|
+
eTypeParameter.setName("ETypeParameter");
|
|
404
|
+
eAnnotation.getESuperTypes().add(eModelElement);
|
|
405
|
+
eNamedElement.getESuperTypes().add(eModelElement);
|
|
406
|
+
eTypedElement.getESuperTypes().add(eNamedElement);
|
|
407
|
+
eClassifier.getESuperTypes().add(eNamedElement);
|
|
408
|
+
eStructuralFeature.getESuperTypes().add(eTypedElement);
|
|
409
|
+
eAttribute.getESuperTypes().add(eStructuralFeature);
|
|
410
|
+
eReference.getESuperTypes().add(eStructuralFeature);
|
|
411
|
+
eClass.getESuperTypes().add(eClassifier);
|
|
412
|
+
ePackage.getESuperTypes().add(eNamedElement);
|
|
413
|
+
eDataType.getESuperTypes().add(eClassifier);
|
|
414
|
+
eEnum.getESuperTypes().add(eDataType);
|
|
415
|
+
eEnumLiteral.getESuperTypes().add(eNamedElement);
|
|
416
|
+
eFactory.getESuperTypes().add(eModelElement);
|
|
417
|
+
eOperation.getESuperTypes().add(eTypedElement);
|
|
418
|
+
eParameter.getESuperTypes().add(eTypedElement);
|
|
419
|
+
eTypeParameter.getESuperTypes().add(eNamedElement);
|
|
420
|
+
const allClasses = [
|
|
421
|
+
eObject,
|
|
422
|
+
eModelElement,
|
|
423
|
+
eAnnotation,
|
|
424
|
+
eNamedElement,
|
|
425
|
+
eTypedElement,
|
|
426
|
+
eClassifier,
|
|
427
|
+
eStructuralFeature,
|
|
428
|
+
eAttribute,
|
|
429
|
+
eReference,
|
|
430
|
+
eClass,
|
|
431
|
+
ePackage,
|
|
432
|
+
eDataType,
|
|
433
|
+
eEnum,
|
|
434
|
+
eEnumLiteral,
|
|
435
|
+
eFactory,
|
|
436
|
+
eOperation,
|
|
437
|
+
eParameter,
|
|
438
|
+
eStringToStringMapEntry,
|
|
439
|
+
eGenericType,
|
|
440
|
+
eTypeParameter
|
|
441
|
+
];
|
|
442
|
+
function attr(owner, name, type, opts = {}) {
|
|
443
|
+
const a = new EAttributeImpl2();
|
|
444
|
+
a.setName(name);
|
|
445
|
+
a.setEType(type);
|
|
446
|
+
if (opts.many) a.setUpperBound(-1);
|
|
447
|
+
if (opts.changeable === false) a.setChangeable(false);
|
|
448
|
+
if (opts.volatile) a.setVolatile(true);
|
|
449
|
+
if (opts.transient) a.setTransient(true);
|
|
450
|
+
if (opts.derived) a.setDerived(true);
|
|
451
|
+
a.setEContainingClass(owner);
|
|
452
|
+
owner.getEStructuralFeatures().add(a);
|
|
453
|
+
return a;
|
|
454
|
+
}
|
|
455
|
+
function ref(owner, name, type, opts = {}) {
|
|
456
|
+
const r = new EReferenceImpl2();
|
|
457
|
+
r.setName(name);
|
|
458
|
+
r.setEType(type);
|
|
459
|
+
if (opts.many) r.setUpperBound(-1);
|
|
460
|
+
if (opts.containment) r.setContainment(true);
|
|
461
|
+
if (opts.changeable === false) r.setChangeable(false);
|
|
462
|
+
if (opts.volatile) r.setVolatile(true);
|
|
463
|
+
if (opts.transient) r.setTransient(true);
|
|
464
|
+
if (opts.derived) r.setDerived(true);
|
|
465
|
+
r.setEContainingClass(owner);
|
|
466
|
+
owner.getEStructuralFeatures().add(r);
|
|
467
|
+
return r;
|
|
468
|
+
}
|
|
469
|
+
const eAnnotations = ref(eModelElement, "eAnnotations", eAnnotation, { many: true, containment: true });
|
|
470
|
+
attr(eAnnotation, "source", p("EString"));
|
|
471
|
+
ref(eAnnotation, "details", eStringToStringMapEntry, { many: true, containment: true });
|
|
472
|
+
const annotation_eModelElement = ref(eAnnotation, "eModelElement", eModelElement, { transient: true });
|
|
473
|
+
ref(eAnnotation, "contents", eObject, { many: true, containment: true });
|
|
474
|
+
ref(eAnnotation, "references", eObject, { many: true });
|
|
475
|
+
attr(eNamedElement, "name", p("EString"));
|
|
476
|
+
attr(eTypedElement, "ordered", p("EBoolean"));
|
|
477
|
+
attr(eTypedElement, "unique", p("EBoolean"));
|
|
478
|
+
attr(eTypedElement, "lowerBound", p("EInt"));
|
|
479
|
+
attr(eTypedElement, "upperBound", p("EInt"));
|
|
480
|
+
attr(eTypedElement, "many", p("EBoolean"), { changeable: false, volatile: true, transient: true, derived: true });
|
|
481
|
+
attr(eTypedElement, "required", p("EBoolean"), { changeable: false, volatile: true, transient: true, derived: true });
|
|
482
|
+
const eType = ref(eTypedElement, "eType", eClassifier, { volatile: true });
|
|
483
|
+
ref(eTypedElement, "eGenericType", eGenericType, { containment: true, volatile: true });
|
|
484
|
+
const classifier_ePackage = ref(eClassifier, "ePackage", ePackage, { changeable: false, transient: true });
|
|
485
|
+
ref(eClassifier, "eTypeParameters", eTypeParameter, { many: true, containment: true });
|
|
486
|
+
attr(eClassifier, "instanceClassName", p("EString"), { volatile: true });
|
|
487
|
+
attr(eClassifier, "instanceClass", p("EJavaClass"), {
|
|
488
|
+
changeable: false,
|
|
489
|
+
volatile: true,
|
|
490
|
+
transient: true,
|
|
491
|
+
derived: true
|
|
492
|
+
});
|
|
493
|
+
attr(eClassifier, "defaultValue", p("EJavaObject"), {
|
|
494
|
+
changeable: false,
|
|
495
|
+
volatile: true,
|
|
496
|
+
transient: true,
|
|
497
|
+
derived: true
|
|
498
|
+
});
|
|
499
|
+
attr(eClassifier, "instanceTypeName", p("EString"), { volatile: true });
|
|
500
|
+
attr(eStructuralFeature, "changeable", p("EBoolean"));
|
|
501
|
+
attr(eStructuralFeature, "volatile", p("EBoolean"));
|
|
502
|
+
attr(eStructuralFeature, "transient", p("EBoolean"));
|
|
503
|
+
attr(eStructuralFeature, "defaultValueLiteral", p("EString"));
|
|
504
|
+
attr(eStructuralFeature, "defaultValue", p("EJavaObject"), {
|
|
505
|
+
changeable: false,
|
|
506
|
+
volatile: true,
|
|
507
|
+
transient: true,
|
|
508
|
+
derived: true
|
|
509
|
+
});
|
|
510
|
+
attr(eStructuralFeature, "unsettable", p("EBoolean"));
|
|
511
|
+
attr(eStructuralFeature, "derived", p("EBoolean"));
|
|
512
|
+
const feature_eContainingClass = ref(eStructuralFeature, "eContainingClass", eClass, {
|
|
513
|
+
changeable: false,
|
|
514
|
+
transient: true
|
|
515
|
+
});
|
|
516
|
+
attr(eAttribute, "iD", p("EBoolean"));
|
|
517
|
+
ref(eAttribute, "eAttributeType", eDataType, { changeable: false, volatile: true, transient: true, derived: true });
|
|
518
|
+
attr(eReference, "containment", p("EBoolean"));
|
|
519
|
+
attr(eReference, "container", p("EBoolean"), { changeable: false, volatile: true, transient: true, derived: true });
|
|
520
|
+
attr(eReference, "resolveProxies", p("EBoolean"));
|
|
521
|
+
const eOpposite = ref(eReference, "eOpposite", eReference, {});
|
|
522
|
+
ref(eReference, "eReferenceType", eClass, { changeable: false, volatile: true, transient: true, derived: true });
|
|
523
|
+
ref(eReference, "eKeys", eAttribute, { many: true });
|
|
524
|
+
attr(eClass, "abstract", p("EBoolean"));
|
|
525
|
+
attr(eClass, "interface", p("EBoolean"));
|
|
526
|
+
ref(eClass, "eSuperTypes", eClass, { many: true });
|
|
527
|
+
const eOperations = ref(eClass, "eOperations", eOperation, { many: true, containment: true });
|
|
528
|
+
ref(eClass, "eAllAttributes", eAttribute, {
|
|
529
|
+
many: true,
|
|
530
|
+
changeable: false,
|
|
531
|
+
volatile: true,
|
|
532
|
+
transient: true,
|
|
533
|
+
derived: true
|
|
534
|
+
});
|
|
535
|
+
ref(eClass, "eAllReferences", eReference, {
|
|
536
|
+
many: true,
|
|
537
|
+
changeable: false,
|
|
538
|
+
volatile: true,
|
|
539
|
+
transient: true,
|
|
540
|
+
derived: true
|
|
541
|
+
});
|
|
542
|
+
ref(eClass, "eReferences", eReference, {
|
|
543
|
+
many: true,
|
|
544
|
+
changeable: false,
|
|
545
|
+
volatile: true,
|
|
546
|
+
transient: true,
|
|
547
|
+
derived: true
|
|
548
|
+
});
|
|
549
|
+
ref(eClass, "eAttributes", eAttribute, {
|
|
550
|
+
many: true,
|
|
551
|
+
changeable: false,
|
|
552
|
+
volatile: true,
|
|
553
|
+
transient: true,
|
|
554
|
+
derived: true
|
|
555
|
+
});
|
|
556
|
+
ref(eClass, "eAllContainments", eReference, {
|
|
557
|
+
many: true,
|
|
558
|
+
changeable: false,
|
|
559
|
+
volatile: true,
|
|
560
|
+
transient: true,
|
|
561
|
+
derived: true
|
|
562
|
+
});
|
|
563
|
+
ref(eClass, "eAllOperations", eOperation, {
|
|
564
|
+
many: true,
|
|
565
|
+
changeable: false,
|
|
566
|
+
volatile: true,
|
|
567
|
+
transient: true,
|
|
568
|
+
derived: true
|
|
569
|
+
});
|
|
570
|
+
ref(eClass, "eAllStructuralFeatures", eStructuralFeature, {
|
|
571
|
+
many: true,
|
|
572
|
+
changeable: false,
|
|
573
|
+
volatile: true,
|
|
574
|
+
transient: true,
|
|
575
|
+
derived: true
|
|
576
|
+
});
|
|
577
|
+
ref(eClass, "eAllSuperTypes", eClass, {
|
|
578
|
+
many: true,
|
|
579
|
+
changeable: false,
|
|
580
|
+
volatile: true,
|
|
581
|
+
transient: true,
|
|
582
|
+
derived: true
|
|
583
|
+
});
|
|
584
|
+
ref(eClass, "eIDAttribute", eAttribute, { changeable: false, volatile: true, transient: true, derived: true });
|
|
585
|
+
const eStructuralFeatures = ref(eClass, "eStructuralFeatures", eStructuralFeature, { many: true, containment: true });
|
|
586
|
+
ref(eClass, "eGenericSuperTypes", eGenericType, { many: true, containment: true });
|
|
587
|
+
ref(eClass, "eAllGenericSuperTypes", eGenericType, {
|
|
588
|
+
many: true,
|
|
589
|
+
changeable: false,
|
|
590
|
+
volatile: true,
|
|
591
|
+
transient: true,
|
|
592
|
+
derived: true
|
|
593
|
+
});
|
|
594
|
+
attr(eDataType, "serializable", p("EBoolean"));
|
|
595
|
+
const eLiterals = ref(eEnum, "eLiterals", eEnumLiteral, { many: true, containment: true });
|
|
596
|
+
attr(eEnumLiteral, "value", p("EInt"));
|
|
597
|
+
attr(eEnumLiteral, "instance", p("EEnumerator"), { transient: true });
|
|
598
|
+
attr(eEnumLiteral, "literal", p("EString"));
|
|
599
|
+
const eEnumLiteral_eEnum = ref(eEnumLiteral, "eEnum", eEnum, { changeable: false, transient: true });
|
|
600
|
+
const factory_ePackage = ref(eFactory, "ePackage", ePackage, { transient: true });
|
|
601
|
+
const operation_eContainingClass = ref(eOperation, "eContainingClass", eClass, {
|
|
602
|
+
changeable: false,
|
|
603
|
+
transient: true
|
|
604
|
+
});
|
|
605
|
+
ref(eOperation, "eTypeParameters", eTypeParameter, { many: true, containment: true });
|
|
606
|
+
const eParameters = ref(eOperation, "eParameters", eParameter, { many: true, containment: true });
|
|
607
|
+
ref(eOperation, "eExceptions", eClassifier, { many: true });
|
|
608
|
+
ref(eOperation, "eGenericExceptions", eGenericType, { many: true, containment: true });
|
|
609
|
+
attr(ePackage, "nsURI", p("EString"));
|
|
610
|
+
attr(ePackage, "nsPrefix", p("EString"));
|
|
611
|
+
const eFactoryInstance = ref(ePackage, "eFactoryInstance", eFactory, { transient: true });
|
|
612
|
+
const eClassifiers = ref(ePackage, "eClassifiers", eClassifier, { many: true, containment: true });
|
|
613
|
+
const eSubpackages = ref(ePackage, "eSubpackages", ePackage, { many: true, containment: true });
|
|
614
|
+
const eSuperPackage = ref(ePackage, "eSuperPackage", ePackage, { changeable: false, transient: true });
|
|
615
|
+
const parameter_eOperation = ref(eParameter, "eOperation", eOperation, { changeable: false, transient: true });
|
|
616
|
+
attr(eStringToStringMapEntry, "key", p("EString"));
|
|
617
|
+
attr(eStringToStringMapEntry, "value", p("EString"));
|
|
618
|
+
ref(eGenericType, "eUpperBound", eGenericType, { containment: true });
|
|
619
|
+
ref(eGenericType, "eTypeArguments", eGenericType, { many: true, containment: true });
|
|
620
|
+
ref(eGenericType, "eRawType", eClassifier, { changeable: false, transient: true, derived: true });
|
|
621
|
+
ref(eGenericType, "eLowerBound", eGenericType, { containment: true });
|
|
622
|
+
ref(eGenericType, "eTypeParameter", eTypeParameter, {});
|
|
623
|
+
ref(eGenericType, "eClassifier", eClassifier, {});
|
|
624
|
+
ref(eTypeParameter, "eBounds", eGenericType, { many: true, containment: true });
|
|
625
|
+
eAnnotations.setEOpposite(annotation_eModelElement);
|
|
626
|
+
annotation_eModelElement.setEOpposite(eAnnotations);
|
|
627
|
+
classifier_ePackage.setEOpposite(eClassifiers);
|
|
628
|
+
eClassifiers.setEOpposite(classifier_ePackage);
|
|
629
|
+
feature_eContainingClass.setEOpposite(eStructuralFeatures);
|
|
630
|
+
eStructuralFeatures.setEOpposite(feature_eContainingClass);
|
|
631
|
+
operation_eContainingClass.setEOpposite(eOperations);
|
|
632
|
+
eOperations.setEOpposite(operation_eContainingClass);
|
|
633
|
+
parameter_eOperation.setEOpposite(eParameters);
|
|
634
|
+
eParameters.setEOpposite(parameter_eOperation);
|
|
635
|
+
factory_ePackage.setEOpposite(eFactoryInstance);
|
|
636
|
+
eFactoryInstance.setEOpposite(factory_ePackage);
|
|
637
|
+
eSubpackages.setEOpposite(eSuperPackage);
|
|
638
|
+
eSuperPackage.setEOpposite(eSubpackages);
|
|
639
|
+
eEnumLiteral_eEnum.setEOpposite(eLiterals);
|
|
640
|
+
eLiterals.setEOpposite(eEnumLiteral_eEnum);
|
|
641
|
+
void eOpposite;
|
|
642
|
+
void eType;
|
|
643
|
+
const pkg = new EPackageImpl2();
|
|
644
|
+
pkg.setName("ecore");
|
|
645
|
+
pkg.setNsURI("http://www.eclipse.org/emf/2002/Ecore");
|
|
646
|
+
pkg.setNsPrefix("ecore");
|
|
647
|
+
for (const d of primitives.values()) pkg.getEClassifiers().add(d);
|
|
648
|
+
for (const c of allClasses) pkg.getEClassifiers().add(c);
|
|
649
|
+
pkg.setEFactoryInstance(new DynamicEFactoryImpl());
|
|
650
|
+
assignFreshIds(pkg);
|
|
651
|
+
return {
|
|
652
|
+
pkg,
|
|
653
|
+
eObject,
|
|
654
|
+
eModelElement,
|
|
655
|
+
eAnnotation,
|
|
656
|
+
eNamedElement,
|
|
657
|
+
eTypedElement,
|
|
658
|
+
eClassifier,
|
|
659
|
+
eStructuralFeature,
|
|
660
|
+
eAttribute,
|
|
661
|
+
eReference,
|
|
662
|
+
eClass,
|
|
663
|
+
ePackage,
|
|
664
|
+
eDataType,
|
|
665
|
+
eEnum,
|
|
666
|
+
eEnumLiteral,
|
|
667
|
+
eFactory,
|
|
668
|
+
eOperation,
|
|
669
|
+
eParameter,
|
|
670
|
+
eStringToStringMapEntry,
|
|
671
|
+
eGenericType,
|
|
672
|
+
eTypeParameter
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// src/ecore-loader.ts
|
|
677
|
+
async function loadEcorePackage(ecoreFilePath) {
|
|
678
|
+
void EcorePackageImpl2.eINSTANCE;
|
|
679
|
+
const resourceSet = new ResourceSetImpl();
|
|
680
|
+
resourceSet.getUriConverterRegistry().register(new NodeFileUriConverter());
|
|
681
|
+
registerXmiFormat(resourceSet.getResourceFactoryRegistry());
|
|
682
|
+
const metaSchema = buildEcoreMetaSchema();
|
|
683
|
+
resourceSet.getPackageRegistry().register(metaSchema.pkg);
|
|
684
|
+
const uri = URI.createFileURI(ecoreFilePath);
|
|
685
|
+
const resource = await resourceSet.getResource(uri, true);
|
|
686
|
+
if (!resource) {
|
|
687
|
+
throw new Error(`Could not load '${ecoreFilePath}'.`);
|
|
688
|
+
}
|
|
689
|
+
const roots = resource.getContents().toArray();
|
|
690
|
+
const dynamicPkg = roots[0];
|
|
691
|
+
if (!dynamicPkg) {
|
|
692
|
+
throw new Error(`'${ecoreFilePath}' has no root element - expected a single EPackage.`);
|
|
693
|
+
}
|
|
694
|
+
return convertDynamicEcoreToTyped(dynamicPkg);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/generate.ts
|
|
698
|
+
import nunjucks from "nunjucks";
|
|
699
|
+
|
|
700
|
+
// src/file-extension.ts
|
|
701
|
+
var FileExtension = class {
|
|
702
|
+
constructor(postProcess) {
|
|
703
|
+
this.postProcess = postProcess;
|
|
704
|
+
}
|
|
705
|
+
postProcess;
|
|
706
|
+
tags = ["file"];
|
|
707
|
+
collected = [];
|
|
708
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
709
|
+
parse(parser, nodes) {
|
|
710
|
+
const tok = parser.nextToken();
|
|
711
|
+
const pathExpr = parser.parseExpression();
|
|
712
|
+
parser.advanceAfterBlockEnd(tok.value);
|
|
713
|
+
const body = parser.parseUntilBlocks("endfile");
|
|
714
|
+
parser.advanceAfterBlockEnd();
|
|
715
|
+
return new nodes.CallExtensionAsync(this, "run", new nodes.NodeList(tok.lineno, tok.colno, [pathExpr]), [body]);
|
|
716
|
+
}
|
|
717
|
+
run(_context, path, body, callback) {
|
|
718
|
+
body((err, content) => {
|
|
719
|
+
if (err) {
|
|
720
|
+
callback(err, "");
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
this.collected.push({ path, content: this.postProcess ? this.postProcess(path, content) : content });
|
|
724
|
+
callback(null, "");
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
/** Everything collected so far in this Environment's lifetime. */
|
|
728
|
+
getCollected() {
|
|
729
|
+
return this.collected;
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
// src/generate.ts
|
|
734
|
+
function generate(pkg, templateSet, options = {}) {
|
|
735
|
+
assignFreshIds(pkg);
|
|
736
|
+
const problems = templateSet.validate?.(pkg) ?? [];
|
|
737
|
+
if (problems.length > 0) {
|
|
738
|
+
throw new Error(
|
|
739
|
+
`Cannot generate from this package - ${templateSet.name} found ${problems.length} unresolved problem(s):
|
|
740
|
+
` + problems.map((p) => ` - ${p}`).join("\n")
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
const loader = new nunjucks.FileSystemLoader(templateSet.baseFolder, { noCache: true });
|
|
744
|
+
const env = new nunjucks.Environment(loader, { autoescape: false, trimBlocks: true, lstripBlocks: true });
|
|
745
|
+
const fileExtension = new FileExtension(
|
|
746
|
+
templateSet.postProcessFile ? (path, content) => templateSet.postProcessFile(path, content, options) : void 0
|
|
747
|
+
);
|
|
748
|
+
env.addExtension("file", fileExtension);
|
|
749
|
+
env.addGlobal("package", pkg);
|
|
750
|
+
env.addGlobal("options", options);
|
|
751
|
+
templateSet.configureEnvironment?.(env, { pkg, options });
|
|
752
|
+
env.render("main.njk");
|
|
753
|
+
return fileExtension.getCollected();
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// src/run-generation.ts
|
|
757
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
758
|
+
import { dirname as dirname2, join as join2, resolve } from "path";
|
|
759
|
+
|
|
760
|
+
// src/typescript-template-set.ts
|
|
761
|
+
import { fileURLToPath } from "url";
|
|
762
|
+
import { dirname, join } from "path";
|
|
763
|
+
|
|
764
|
+
// src/type-import-mapping.ts
|
|
765
|
+
import { detailValue } from "@typemf/core";
|
|
766
|
+
var IMPORT_ANNOTATION_SOURCE = "https://typemf.dev/generator/import";
|
|
767
|
+
var nonEmpty = (value) => value !== void 0 && value !== "" ? value : void 0;
|
|
768
|
+
function info(type, from, internalFrom) {
|
|
769
|
+
const result = { type };
|
|
770
|
+
if (from !== void 0) result.from = from;
|
|
771
|
+
if (internalFrom !== void 0) result.internalFrom = internalFrom;
|
|
772
|
+
return result;
|
|
773
|
+
}
|
|
774
|
+
function importInfoOf(details) {
|
|
775
|
+
const type = nonEmpty(details && detailValue(details, "type"));
|
|
776
|
+
if (type === void 0) return void 0;
|
|
777
|
+
return info(
|
|
778
|
+
type,
|
|
779
|
+
nonEmpty(details && detailValue(details, "from")),
|
|
780
|
+
nonEmpty(details && detailValue(details, "internal-from"))
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
function readImportAnnotation(element) {
|
|
784
|
+
return importInfoOf(element.getEAnnotation(IMPORT_ANNOTATION_SOURCE)?.getDetails());
|
|
785
|
+
}
|
|
786
|
+
function readImportAnnotations(element) {
|
|
787
|
+
const result = [];
|
|
788
|
+
for (const annotation of element.getEAnnotations()) {
|
|
789
|
+
if (annotation.getSource() !== IMPORT_ANNOTATION_SOURCE) continue;
|
|
790
|
+
const entry = importInfoOf(annotation.getDetails());
|
|
791
|
+
if (entry !== void 0) result.push(entry);
|
|
792
|
+
}
|
|
793
|
+
return result;
|
|
794
|
+
}
|
|
795
|
+
var TypeImportMapping = class _TypeImportMapping {
|
|
796
|
+
explicit = /* @__PURE__ */ new Map();
|
|
797
|
+
constructor(entries = {}) {
|
|
798
|
+
for (const [key, entry] of Object.entries(entries)) {
|
|
799
|
+
const type = nonEmpty(entry.type);
|
|
800
|
+
if (type !== void 0) this.set(key, info(type, nonEmpty(entry.from), nonEmpty(entry["internal-from"])));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
static keyOf(classifier) {
|
|
804
|
+
return `${classifier.getEPackage()?.getNsURI() ?? ""}#${classifier.getName()}`;
|
|
805
|
+
}
|
|
806
|
+
set(key, value) {
|
|
807
|
+
this.explicit.set(key, value);
|
|
808
|
+
}
|
|
809
|
+
lookup(classifier) {
|
|
810
|
+
return this.explicit.get(_TypeImportMapping.keyOf(classifier)) ?? readImportAnnotation(classifier);
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
// src/generation-context.ts
|
|
815
|
+
var generationContext = { pkg: void 0, typeImports: new TypeImportMapping() };
|
|
816
|
+
var TYPE_IMPORTS_OPTION = "type-imports";
|
|
817
|
+
function beginGeneration(pkg, options) {
|
|
818
|
+
generationContext.pkg = pkg;
|
|
819
|
+
const entries = options[TYPE_IMPORTS_OPTION];
|
|
820
|
+
const valid = typeof entries === "object" && entries !== null && !Array.isArray(entries);
|
|
821
|
+
generationContext.typeImports = new TypeImportMapping(valid ? entries : {});
|
|
822
|
+
}
|
|
823
|
+
function isExternal(classifier) {
|
|
824
|
+
const owner = classifier.getEPackage();
|
|
825
|
+
return generationContext.pkg !== void 0 && owner !== void 0 && owner !== generationContext.pkg;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// src/import-collector.ts
|
|
829
|
+
import { posix } from "path";
|
|
830
|
+
function relativeImportPath(from, to, file) {
|
|
831
|
+
if (from === to) return `./${file}.js`;
|
|
832
|
+
if (from === "root") return `./${to}/${file}.js`;
|
|
833
|
+
if (to === "root") return `../${file}.js`;
|
|
834
|
+
return `../${to}/${file}.js`;
|
|
835
|
+
}
|
|
836
|
+
var ImportCollector = class {
|
|
837
|
+
/**
|
|
838
|
+
* Every distinct way each name has been requested. Usually one; more
|
|
839
|
+
* than one is only a problem if, once the mode and importing folder are
|
|
840
|
+
* known (render time), they resolve to genuinely different modules.
|
|
841
|
+
*/
|
|
842
|
+
entries = /* @__PURE__ */ new Map();
|
|
843
|
+
add(entry) {
|
|
844
|
+
const variants = this.entries.get(entry.name) ?? [];
|
|
845
|
+
const sameSource = variants.findIndex(
|
|
846
|
+
(v) => v.location === entry.location && (v.file ?? v.name) === (entry.file ?? entry.name) && v.from === entry.from
|
|
847
|
+
);
|
|
848
|
+
if (sameSource >= 0) {
|
|
849
|
+
if (entry.foundational && !variants[sameSource].foundational) variants[sameSource] = entry;
|
|
850
|
+
} else {
|
|
851
|
+
variants.push(entry);
|
|
852
|
+
}
|
|
853
|
+
this.entries.set(entry.name, variants);
|
|
854
|
+
}
|
|
855
|
+
clear() {
|
|
856
|
+
this.entries.clear();
|
|
857
|
+
}
|
|
858
|
+
isEmpty() {
|
|
859
|
+
return this.entries.size === 0;
|
|
860
|
+
}
|
|
861
|
+
render(currentLocation, options) {
|
|
862
|
+
const generateEcore = Boolean(options["generate-ecore"]);
|
|
863
|
+
const corePackageNames = [];
|
|
864
|
+
const groups = /* @__PURE__ */ new Map();
|
|
865
|
+
const addToGroup = (key, specifier, name) => {
|
|
866
|
+
if (!groups.has(key)) groups.set(key, { specifier, names: [] });
|
|
867
|
+
groups.get(key).names.push(name);
|
|
868
|
+
};
|
|
869
|
+
for (const name of [...this.entries.keys()].sort((a, b) => a.localeCompare(b))) {
|
|
870
|
+
const resolved = this.entries.get(name).map((entry) => ({ entry, ...resolveEntry(entry, currentLocation, generateEcore) }));
|
|
871
|
+
const distinct = new Set(resolved.map((r) => r.specifier.replace(/\.(js|ts)$/, "")));
|
|
872
|
+
if (distinct.size > 1) {
|
|
873
|
+
throw new Error(
|
|
874
|
+
`Import collision while generating: "${name}" was requested from ${resolved.map((r) => `"${r.specifier}"`).join(" and ")}. A single name must resolve to exactly one real source.`
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
const chosen = resolved.find((r) => r.entry.from !== void 0) ?? resolved[0];
|
|
878
|
+
if (chosen.core) corePackageNames.push(name);
|
|
879
|
+
else addToGroup(chosen.key, chosen.specifier, name);
|
|
880
|
+
}
|
|
881
|
+
const lines = [];
|
|
882
|
+
if (corePackageNames.length > 0) {
|
|
883
|
+
lines.push(`import { ${corePackageNames.join(", ")} } from '@typemf/core';`);
|
|
884
|
+
}
|
|
885
|
+
for (const key of [...groups.keys()].sort()) {
|
|
886
|
+
const { specifier, names } = groups.get(key);
|
|
887
|
+
lines.push(`import { ${names.join(", ")} } from '${specifier}';`);
|
|
888
|
+
}
|
|
889
|
+
return lines.join("\n");
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
function resolveEntry(entry, currentLocation, generateEcore) {
|
|
893
|
+
if (entry.from !== void 0) {
|
|
894
|
+
const specifier = explicitImportSpecifier(entry.from, currentLocation);
|
|
895
|
+
return { specifier, key: `~${specifier}`, core: specifier === "@typemf/core" };
|
|
896
|
+
}
|
|
897
|
+
if (entry.foundational && !generateEcore) return { specifier: "@typemf/core", key: "@typemf/core", core: true };
|
|
898
|
+
const file = entry.file ?? entry.name;
|
|
899
|
+
return {
|
|
900
|
+
specifier: relativeImportPath(currentLocation, entry.location, file),
|
|
901
|
+
key: `${entry.location}/${file}`,
|
|
902
|
+
core: false
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
function explicitImportSpecifier(from, currentLocation) {
|
|
906
|
+
if (!from.startsWith("./") && !from.startsWith("../")) return from;
|
|
907
|
+
const fromDir = posix.join("/pkg", currentLocation === "root" ? "" : currentLocation);
|
|
908
|
+
const relative = posix.relative(fromDir, posix.join("/pkg", from));
|
|
909
|
+
return relative.startsWith(".") ? relative : `./${relative}`;
|
|
910
|
+
}
|
|
911
|
+
var importCollector = new ImportCollector();
|
|
912
|
+
function locationOfPath(path) {
|
|
913
|
+
if (path.startsWith("types/")) return "types";
|
|
914
|
+
if (path.startsWith("impl/")) return "impl";
|
|
915
|
+
if (path.startsWith("util/")) return "util";
|
|
916
|
+
return "root";
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// src/typescript-filters.ts
|
|
920
|
+
import {
|
|
921
|
+
detailValue as detailValue2
|
|
922
|
+
} from "@typemf/core";
|
|
923
|
+
var TYPEMF_GENERATOR_ANNOTATION_SOURCE = "https://typemf.dev/generator";
|
|
924
|
+
var ECLIPSE_GENMODEL_ANNOTATION_SOURCE = "http://www.eclipse.org/emf/2002/GenModel";
|
|
925
|
+
var ECLIPSE_ECORE_ANNOTATION_SOURCE = "http://www.eclipse.org/emf/2002/Ecore";
|
|
926
|
+
function layeredAnnotationDetail(element, key, fallbackSource) {
|
|
927
|
+
for (const source of [TYPEMF_GENERATOR_ANNOTATION_SOURCE, fallbackSource]) {
|
|
928
|
+
const details = element.getEAnnotation(source)?.getDetails();
|
|
929
|
+
const value = details && detailValue2(details, key);
|
|
930
|
+
if (value !== void 0 && value !== "") return value;
|
|
931
|
+
}
|
|
932
|
+
return void 0;
|
|
933
|
+
}
|
|
934
|
+
function documentationOf(element) {
|
|
935
|
+
return layeredAnnotationDetail(element, "documentation", ECLIPSE_ECORE_ANNOTATION_SOURCE);
|
|
936
|
+
}
|
|
937
|
+
function docComment(element, indent = "") {
|
|
938
|
+
const doc = documentationOf(element);
|
|
939
|
+
if (!doc) return "";
|
|
940
|
+
const lines = doc.trim().split("\n");
|
|
941
|
+
if (lines.length === 1) {
|
|
942
|
+
return `${indent}/** ${lines[0]} */`;
|
|
943
|
+
}
|
|
944
|
+
const body = lines.map((line) => `${indent} * ${line}`).join("\n");
|
|
945
|
+
return `${indent}/**
|
|
946
|
+
${body}
|
|
947
|
+
${indent} */`;
|
|
948
|
+
}
|
|
949
|
+
function operationBody(operation) {
|
|
950
|
+
return layeredAnnotationDetail(operation, "body", ECLIPSE_GENMODEL_ANNOTATION_SOURCE);
|
|
951
|
+
}
|
|
952
|
+
var FEATURE_ANNOTATION_SOURCE = "https://typemf.dev/generator/feature";
|
|
953
|
+
function featureDetail(feature, key) {
|
|
954
|
+
const details = feature.getEAnnotation(FEATURE_ANNOTATION_SOURCE)?.getDetails();
|
|
955
|
+
const value = details && detailValue2(details, key);
|
|
956
|
+
return value !== void 0 && value !== "" ? value : void 0;
|
|
957
|
+
}
|
|
958
|
+
function featureGetter(feature) {
|
|
959
|
+
return featureDetail(feature, "get");
|
|
960
|
+
}
|
|
961
|
+
function featureSetter(feature) {
|
|
962
|
+
return featureDetail(feature, "set");
|
|
963
|
+
}
|
|
964
|
+
function customBodyNeedsOwnField(feature) {
|
|
965
|
+
const getter = featureGetter(feature);
|
|
966
|
+
const setter = featureSetter(feature);
|
|
967
|
+
if (!getter && !setter) return false;
|
|
968
|
+
const ownFieldRef = new RegExp(`\\bthis\\._${feature.getName()}\\b`);
|
|
969
|
+
return getter !== void 0 && ownFieldRef.test(getter) || setter !== void 0 && ownFieldRef.test(setter);
|
|
970
|
+
}
|
|
971
|
+
function isReadOnlyFeature(feature) {
|
|
972
|
+
return trivialDerivedFormula(feature) !== void 0 || featureGetter(feature) !== void 0 && featureSetter(feature) === void 0;
|
|
973
|
+
}
|
|
974
|
+
function needsImplOnlySetter(feature) {
|
|
975
|
+
return !isReadOnlyFeature(feature) && !feature.isChangeable();
|
|
976
|
+
}
|
|
977
|
+
function findFeatureAnnotationProblems(pkg) {
|
|
978
|
+
const problems = [];
|
|
979
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
980
|
+
if (!isEClass2(classifier)) continue;
|
|
981
|
+
for (const feature of classifier.getEStructuralFeatures()) {
|
|
982
|
+
if (feature.isMany() && featureSetter(feature) !== void 0) {
|
|
983
|
+
problems.push(
|
|
984
|
+
`${classifier.getName()}.${feature.getName()}: has a \`set\` annotation, but is many-valued - many-valued features never have a setter, so it is ignored`
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
return problems;
|
|
990
|
+
}
|
|
991
|
+
var TRIVIAL_DERIVED_FORMULAS = {
|
|
992
|
+
many: "this.getUpperBound() === -1 || this.getUpperBound() > 1",
|
|
993
|
+
// Verified directly against real EMF's own ETypedElementImpl.isRequired()
|
|
994
|
+
// source (org.eclipse.emf.ecore.impl) while implementing the equivalent
|
|
995
|
+
// reflective dispatch in @typemf/core: it is exactly `lowerBound >= 1`,
|
|
996
|
+
// with NO `!many` check. An earlier version of this formula incorrectly
|
|
997
|
+
// added one; caught only because the hand-written @typemf/core port
|
|
998
|
+
// (built independently, then checked against the same source) disagreed
|
|
999
|
+
// with this file.
|
|
1000
|
+
required: "this.getLowerBound() >= 1",
|
|
1001
|
+
container: "(this.getEOpposite()?.isContainment() ?? false)",
|
|
1002
|
+
eReferenceType: "(this.getEType() as EClass | undefined)",
|
|
1003
|
+
eAttributeType: "(this.getEType() as EDataType | undefined)"
|
|
1004
|
+
};
|
|
1005
|
+
function trivialDerivedFormula(feature) {
|
|
1006
|
+
if (!feature.isDerived()) return void 0;
|
|
1007
|
+
return TRIVIAL_DERIVED_FORMULAS[feature.getName()];
|
|
1008
|
+
}
|
|
1009
|
+
function tsScalarType(type) {
|
|
1010
|
+
if (type !== void 0 && isTypedElement(type)) return tsTypeReference(type.getEType(), type.getEGenericType());
|
|
1011
|
+
return tsTypeReference(type, void 0);
|
|
1012
|
+
}
|
|
1013
|
+
function isTypedElement(x) {
|
|
1014
|
+
return "getEType" in x;
|
|
1015
|
+
}
|
|
1016
|
+
function tsTypeReference(classifier, genericType) {
|
|
1017
|
+
const base = tsBaseType(classifier);
|
|
1018
|
+
const parameterCount = classifier?.getETypeParameters().size() ?? 0;
|
|
1019
|
+
if (parameterCount === 0) return base;
|
|
1020
|
+
const given = genericType?.getETypeArguments();
|
|
1021
|
+
const args = [];
|
|
1022
|
+
for (let i = 0; i < parameterCount; i++) {
|
|
1023
|
+
const argument = given !== void 0 && i < given.size() ? given.get(i) : void 0;
|
|
1024
|
+
args.push(argument === void 0 ? "unknown" : tsGenericArgument(argument));
|
|
1025
|
+
}
|
|
1026
|
+
return `${base}<${args.join(", ")}>`;
|
|
1027
|
+
}
|
|
1028
|
+
function tsGenericArgument(argument) {
|
|
1029
|
+
const classifier = argument.getEClassifier();
|
|
1030
|
+
if (classifier) return tsTypeReference(classifier, argument);
|
|
1031
|
+
const parameter = argument.getETypeParameter();
|
|
1032
|
+
if (parameter) return parameter.getName();
|
|
1033
|
+
return "unknown";
|
|
1034
|
+
}
|
|
1035
|
+
function genericArgumentClassifiers(genericType) {
|
|
1036
|
+
const result = [];
|
|
1037
|
+
const visit = (gt) => {
|
|
1038
|
+
for (const argument of gt.getETypeArguments()) {
|
|
1039
|
+
const classifier = argument.getEClassifier();
|
|
1040
|
+
if (classifier) result.push(classifier);
|
|
1041
|
+
visit(argument);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
if (genericType) visit(genericType);
|
|
1045
|
+
return result;
|
|
1046
|
+
}
|
|
1047
|
+
function tsBaseType(classifier) {
|
|
1048
|
+
if (!classifier) {
|
|
1049
|
+
importCollector.add({ name: "EObject", location: "types", foundational: true });
|
|
1050
|
+
return "EObject";
|
|
1051
|
+
}
|
|
1052
|
+
if (isEDataType(classifier)) return tsPrimitiveType(classifier);
|
|
1053
|
+
return classifier.getName();
|
|
1054
|
+
}
|
|
1055
|
+
function resolveDataTypeTs(dataType) {
|
|
1056
|
+
const resolved = resolveDataTypeText(dataType);
|
|
1057
|
+
const importInfo = generationContext.typeImports.lookup(dataType);
|
|
1058
|
+
if (importInfo !== void 0) {
|
|
1059
|
+
const source = isExternal(dataType) ? importInfo.from : importInfo.internalFrom ?? importInfo.from;
|
|
1060
|
+
if (source !== void 0) return { ...resolved, importName: importInfo.type, importFrom: source };
|
|
1061
|
+
}
|
|
1062
|
+
return resolved;
|
|
1063
|
+
}
|
|
1064
|
+
function resolveDataTypeText(dataType) {
|
|
1065
|
+
const ownDetails = dataType.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();
|
|
1066
|
+
const annotated = ownDetails && detailValue2(ownDetails, "type");
|
|
1067
|
+
if (annotated !== void 0 && annotated !== "") return { text: annotated };
|
|
1068
|
+
const instanceClassName = dataType.getInstanceClassName();
|
|
1069
|
+
if (instanceClassName !== void 0 && instanceClassName !== "") return { text: instanceClassName };
|
|
1070
|
+
return { text: dataType.getName() };
|
|
1071
|
+
}
|
|
1072
|
+
function registerBodyImports(element) {
|
|
1073
|
+
for (const entry of readImportAnnotations(element)) {
|
|
1074
|
+
const source = entry.internalFrom ?? entry.from;
|
|
1075
|
+
if (source !== void 0)
|
|
1076
|
+
importCollector.add({ name: entry.type, location: "root", foundational: false, from: source });
|
|
1077
|
+
}
|
|
1078
|
+
return "";
|
|
1079
|
+
}
|
|
1080
|
+
function tsPrimitiveType(dataType) {
|
|
1081
|
+
const resolved = resolveDataTypeTs(dataType);
|
|
1082
|
+
if (resolved.importName !== void 0 && resolved.importFrom !== void 0) {
|
|
1083
|
+
importCollector.add({
|
|
1084
|
+
name: resolved.importName,
|
|
1085
|
+
location: "root",
|
|
1086
|
+
foundational: false,
|
|
1087
|
+
from: resolved.importFrom
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
return resolved.text;
|
|
1091
|
+
}
|
|
1092
|
+
var PRIMITIVE_VALUE_DATATYPE_NAMES = /* @__PURE__ */ new Set(["EBoolean", "EInt", "ELong", "EFloat", "EDouble", "EShort", "EByte"]);
|
|
1093
|
+
function isPrimitiveValueType(classifier) {
|
|
1094
|
+
return classifier !== void 0 && isEDataType(classifier) && PRIMITIVE_VALUE_DATATYPE_NAMES.has(classifier.getName());
|
|
1095
|
+
}
|
|
1096
|
+
function primitiveDefaultValue(feature) {
|
|
1097
|
+
const literal = "getDefaultValueLiteral" in feature ? feature.getDefaultValueLiteral() : void 0;
|
|
1098
|
+
if (literal !== void 0 && literal !== "") return literal;
|
|
1099
|
+
const classifier = feature.getEType();
|
|
1100
|
+
return classifier?.getName() === "EBoolean" ? "false" : "0";
|
|
1101
|
+
}
|
|
1102
|
+
function tsOptionalScalarType(type) {
|
|
1103
|
+
const scalar = tsScalarType(type);
|
|
1104
|
+
const classifier = type !== void 0 && isTypedElement(type) ? type.getEType() : type;
|
|
1105
|
+
if (classifier && isPrimitiveValueType(classifier)) return scalar;
|
|
1106
|
+
if (scalar === "unknown") return scalar;
|
|
1107
|
+
return `${scalar} | undefined`;
|
|
1108
|
+
}
|
|
1109
|
+
function beanGetterName(feature) {
|
|
1110
|
+
const type = feature.getEType();
|
|
1111
|
+
if (!feature.isMany() && type && type.getName() === "EBoolean") {
|
|
1112
|
+
return `is${ucfirst(feature.getName())}`;
|
|
1113
|
+
}
|
|
1114
|
+
return `get${ucfirst(feature.getName())}`;
|
|
1115
|
+
}
|
|
1116
|
+
function tsFeatureType(feature) {
|
|
1117
|
+
const scalar = tsScalarType(feature);
|
|
1118
|
+
if ("isMany" in feature && feature.isMany()) {
|
|
1119
|
+
return `EList<${scalar}>`;
|
|
1120
|
+
}
|
|
1121
|
+
return scalar;
|
|
1122
|
+
}
|
|
1123
|
+
function isOptional(feature) {
|
|
1124
|
+
return !feature.isRequired();
|
|
1125
|
+
}
|
|
1126
|
+
function isEClass2(classifier) {
|
|
1127
|
+
return "getEStructuralFeatures" in classifier;
|
|
1128
|
+
}
|
|
1129
|
+
function isEEnum(classifier) {
|
|
1130
|
+
return "getELiterals" in classifier;
|
|
1131
|
+
}
|
|
1132
|
+
function isEDataType(classifier) {
|
|
1133
|
+
return !isEClass2(classifier) && !isEEnum(classifier);
|
|
1134
|
+
}
|
|
1135
|
+
function isEReference(feature) {
|
|
1136
|
+
return "isContainment" in feature;
|
|
1137
|
+
}
|
|
1138
|
+
function paramList(operation) {
|
|
1139
|
+
return operation.getEParameters().toArray().map((p) => `${p.getName()}: ${tsFeatureType(p)}`).join(", ");
|
|
1140
|
+
}
|
|
1141
|
+
function optionalParamList(operation) {
|
|
1142
|
+
return operation.getEParameters().toArray().map((p) => `${p.getName()}?: ${tsFeatureType(p)}`).join(", ");
|
|
1143
|
+
}
|
|
1144
|
+
function argList(operation) {
|
|
1145
|
+
return operation.getEParameters().toArray().map((p) => p.getName()).join(", ");
|
|
1146
|
+
}
|
|
1147
|
+
function groupOperationsByName(operations) {
|
|
1148
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1149
|
+
for (const op of operations) {
|
|
1150
|
+
const list = groups.get(op.getName());
|
|
1151
|
+
if (list) list.push(op);
|
|
1152
|
+
else groups.set(op.getName(), [op]);
|
|
1153
|
+
}
|
|
1154
|
+
return [...groups.values()];
|
|
1155
|
+
}
|
|
1156
|
+
function mergeNames(names) {
|
|
1157
|
+
const unique = [...new Set(names)];
|
|
1158
|
+
return unique[0] + unique.slice(1).map((n) => `Or${ucfirst(n)}`).join("");
|
|
1159
|
+
}
|
|
1160
|
+
function mergedParams(group) {
|
|
1161
|
+
const arity = Math.max(...group.map((op) => op.getEParameters().size()));
|
|
1162
|
+
const params = [];
|
|
1163
|
+
for (let i = 0; i < arity; i++) {
|
|
1164
|
+
const having = group.filter((op) => op.getEParameters().size() > i);
|
|
1165
|
+
params.push({
|
|
1166
|
+
name: mergeNames(having.map((op) => op.getEParameters().get(i).getName())),
|
|
1167
|
+
type: [...new Set(having.map((op) => tsFeatureType(op.getEParameters().get(i))))].join(" | "),
|
|
1168
|
+
optional: having.length < group.length
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
return params;
|
|
1172
|
+
}
|
|
1173
|
+
function mergedParamList(group) {
|
|
1174
|
+
const first = group[0];
|
|
1175
|
+
if (group.length === 1) return paramList(first);
|
|
1176
|
+
return mergedParams(group).map((p) => `${p.name}${p.optional ? "?" : ""}: ${p.type}`).join(", ");
|
|
1177
|
+
}
|
|
1178
|
+
function primitiveTest(name, tsText) {
|
|
1179
|
+
return ["string", "number", "boolean", "bigint"].includes(tsText) ? `typeof ${name} === '${tsText}'` : void 0;
|
|
1180
|
+
}
|
|
1181
|
+
function codeOnly(source) {
|
|
1182
|
+
let out = "";
|
|
1183
|
+
let i = 0;
|
|
1184
|
+
const n = source.length;
|
|
1185
|
+
while (i < n) {
|
|
1186
|
+
const c = source[i];
|
|
1187
|
+
const next = source[i + 1];
|
|
1188
|
+
if (c === "/" && next === "/") {
|
|
1189
|
+
while (i < n && source[i] !== "\n") i++;
|
|
1190
|
+
} else if (c === "/" && next === "*") {
|
|
1191
|
+
const end = source.indexOf("*/", i + 2);
|
|
1192
|
+
i = end === -1 ? n : end + 2;
|
|
1193
|
+
} else if (c === "'" || c === '"') {
|
|
1194
|
+
i++;
|
|
1195
|
+
while (i < n && source[i] !== c) i += source[i] === "\\" ? 2 : 1;
|
|
1196
|
+
i++;
|
|
1197
|
+
out += " ";
|
|
1198
|
+
} else if (c === "`") {
|
|
1199
|
+
i++;
|
|
1200
|
+
while (i < n && source[i] !== "`") {
|
|
1201
|
+
if (source[i] === "\\") i += 2;
|
|
1202
|
+
else if (source[i] === "$" && source[i + 1] === "{") {
|
|
1203
|
+
let depth = 1;
|
|
1204
|
+
i += 2;
|
|
1205
|
+
while (i < n && depth > 0) {
|
|
1206
|
+
if (source[i] === "{") depth++;
|
|
1207
|
+
else if (source[i] === "}") depth--;
|
|
1208
|
+
if (depth > 0) out += source[i];
|
|
1209
|
+
i++;
|
|
1210
|
+
}
|
|
1211
|
+
out += " ";
|
|
1212
|
+
} else i++;
|
|
1213
|
+
}
|
|
1214
|
+
i++;
|
|
1215
|
+
out += " ";
|
|
1216
|
+
} else {
|
|
1217
|
+
out += c;
|
|
1218
|
+
i++;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return out;
|
|
1222
|
+
}
|
|
1223
|
+
var escapeForSingleQuotes = (text) => text.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1224
|
+
function overloadDispatch(group, className) {
|
|
1225
|
+
const name = group[0].getName();
|
|
1226
|
+
const stub = (why) => ({
|
|
1227
|
+
branches: [],
|
|
1228
|
+
stubMessage: escapeForSingleQuotes(`${className}.${name}() is overloaded and ${why} - nothing to generate.`)
|
|
1229
|
+
});
|
|
1230
|
+
if (!group.some((op) => operationBody(op) !== void 0))
|
|
1231
|
+
return stub("none of its overloads has a `body` annotation");
|
|
1232
|
+
const merged = mergedParams(group);
|
|
1233
|
+
const branches = [];
|
|
1234
|
+
for (const op of group) {
|
|
1235
|
+
const params = [...op.getEParameters()];
|
|
1236
|
+
const label = `${className}.${name}(${params.map((p) => p.getName()).join(", ")})`;
|
|
1237
|
+
const dispatchDetails = op.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();
|
|
1238
|
+
let condition = dispatchDetails && detailValue2(dispatchDetails, "dispatch");
|
|
1239
|
+
if (condition === void 0 || condition === "") {
|
|
1240
|
+
const parts = [];
|
|
1241
|
+
for (let i = 0; i < merged.length; i++) {
|
|
1242
|
+
const m = merged[i];
|
|
1243
|
+
const own = params[i];
|
|
1244
|
+
if (own === void 0) {
|
|
1245
|
+
parts.push(`${m.name} === undefined`);
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
const havingTypes = new Set(
|
|
1249
|
+
group.filter((o) => o.getEParameters().size() > i).map((o) => tsFeatureType(o.getEParameters().get(i)))
|
|
1250
|
+
);
|
|
1251
|
+
if (havingTypes.size > 1) {
|
|
1252
|
+
const test = "isMany" in own && own.isMany() ? void 0 : primitiveTest(m.name, tsScalarType(own));
|
|
1253
|
+
if (test === void 0) {
|
|
1254
|
+
return stub(
|
|
1255
|
+
`cannot be dispatched: the parameter \`${own.getName()}\` of ${label} has type ${tsFeatureType(own)}, which has no runtime test - add a \`dispatch\` detail to the overload`
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
parts.push(test);
|
|
1259
|
+
} else if (m.optional) {
|
|
1260
|
+
parts.push(`${m.name} !== undefined`);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
condition = parts.join(" && ");
|
|
1264
|
+
}
|
|
1265
|
+
const body = operationBody(op);
|
|
1266
|
+
const code = body === void 0 ? "" : codeOnly(body);
|
|
1267
|
+
const aliases = body === void 0 ? [] : params.flatMap((p, i) => {
|
|
1268
|
+
const merged_i = merged[i];
|
|
1269
|
+
const own = p.getName();
|
|
1270
|
+
return own !== merged_i.name && new RegExp(`(?<![\\w$])${own.replace(/[$]/g, "\\$")}(?![\\w$])`).test(code) ? [`const ${own} = ${merged_i.name} as ${tsFeatureType(p)};`] : [];
|
|
1271
|
+
});
|
|
1272
|
+
branches.push({ operation: op, condition, body, aliases, label });
|
|
1273
|
+
}
|
|
1274
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1275
|
+
for (const b of branches) {
|
|
1276
|
+
const earlier = seen.get(b.condition);
|
|
1277
|
+
if (earlier !== void 0 || b.condition === "") {
|
|
1278
|
+
return stub(
|
|
1279
|
+
`cannot be dispatched: ${earlier ?? b.label} and ${b.label} have the same dispatch condition (${b.condition === "" ? "none" : b.condition}), so they cannot be told apart at runtime - add a \`dispatch\` detail`
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1282
|
+
seen.set(b.condition, b.label);
|
|
1283
|
+
}
|
|
1284
|
+
return { branches };
|
|
1285
|
+
}
|
|
1286
|
+
function tsOperationReturnType(op) {
|
|
1287
|
+
const scalar = tsScalarType(op);
|
|
1288
|
+
if (isPrimitiveValueType(op.getEType())) return scalar;
|
|
1289
|
+
if (op.isRequired()) return scalar;
|
|
1290
|
+
if (scalar === "unknown") return scalar;
|
|
1291
|
+
return `${scalar} | undefined`;
|
|
1292
|
+
}
|
|
1293
|
+
function mergedReturnType(group) {
|
|
1294
|
+
return [...new Set(group.map((op) => tsOperationReturnType(op)))].join(" | ");
|
|
1295
|
+
}
|
|
1296
|
+
function ucfirst(s) {
|
|
1297
|
+
return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
|
|
1298
|
+
}
|
|
1299
|
+
function packageClassName(pkg) {
|
|
1300
|
+
return `${ucfirst(pkg.getName())}Package`;
|
|
1301
|
+
}
|
|
1302
|
+
function factoryClassName(pkg) {
|
|
1303
|
+
return `${ucfirst(pkg.getName())}Factory`;
|
|
1304
|
+
}
|
|
1305
|
+
function switchClassName(pkg) {
|
|
1306
|
+
return `${ucfirst(pkg.getName())}Switch`;
|
|
1307
|
+
}
|
|
1308
|
+
function typeGuardsClassName(pkg) {
|
|
1309
|
+
return `${ucfirst(pkg.getName())}TypeGuards`;
|
|
1310
|
+
}
|
|
1311
|
+
function superType(eClass) {
|
|
1312
|
+
const supers = eClass.getESuperTypes();
|
|
1313
|
+
return supers.size() > 0 ? supers.get(0) : void 0;
|
|
1314
|
+
}
|
|
1315
|
+
function superTypeChain(eClass) {
|
|
1316
|
+
const chain = [eClass];
|
|
1317
|
+
let current = superType(eClass);
|
|
1318
|
+
while (current) {
|
|
1319
|
+
chain.push(current);
|
|
1320
|
+
current = superType(current);
|
|
1321
|
+
}
|
|
1322
|
+
return chain;
|
|
1323
|
+
}
|
|
1324
|
+
function isClassifierDerived(eClass) {
|
|
1325
|
+
return superTypeChain(eClass).some((c) => c.getName() === "EClassifier");
|
|
1326
|
+
}
|
|
1327
|
+
function isStructuralFeatureDerived(eClass) {
|
|
1328
|
+
return superTypeChain(eClass).some((c) => c.getName() === "EStructuralFeature");
|
|
1329
|
+
}
|
|
1330
|
+
function isOperationDerived(eClass) {
|
|
1331
|
+
return superTypeChain(eClass).some((c) => c.getName() === "EOperation");
|
|
1332
|
+
}
|
|
1333
|
+
function isBookkeepingOperation(op, eClass) {
|
|
1334
|
+
if (op.getName() === "getClassifierID" && op.getEParameters().isEmpty() && isClassifierDerived(eClass)) return true;
|
|
1335
|
+
if (op.getName() === "getFeatureID" && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))
|
|
1336
|
+
return true;
|
|
1337
|
+
if (op.getName() === "getOperationID" && op.getEParameters().isEmpty() && isOperationDerived(eClass)) return true;
|
|
1338
|
+
if (op.getName() === "getContainerClass" && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))
|
|
1339
|
+
return true;
|
|
1340
|
+
return false;
|
|
1341
|
+
}
|
|
1342
|
+
function metaclassAccessorCollision(classifierName, pkg) {
|
|
1343
|
+
const ePackageClassifier = [...pkg.getEClassifiers()].find((c) => c.getName() === "EPackage" && isEClass2(c));
|
|
1344
|
+
if (!ePackageClassifier) return void 0;
|
|
1345
|
+
const accessorName = "get" + classifierName;
|
|
1346
|
+
for (const ancestor of superTypeChain(ePackageClassifier)) {
|
|
1347
|
+
for (const op of ancestor.getEOperations()) {
|
|
1348
|
+
if (op.getName() === accessorName) return op;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
return void 0;
|
|
1352
|
+
}
|
|
1353
|
+
function metaclassAccessorCollisionTypeNames(pkg) {
|
|
1354
|
+
const names = /* @__PURE__ */ new Set();
|
|
1355
|
+
const maybeAdd = (type) => {
|
|
1356
|
+
if (type && (isEClass2(type) || isEEnum(type))) names.add(type.getName());
|
|
1357
|
+
};
|
|
1358
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
1359
|
+
const collision = metaclassAccessorCollision(classifier.getName(), pkg);
|
|
1360
|
+
if (!collision) continue;
|
|
1361
|
+
maybeAdd(collision.getEType());
|
|
1362
|
+
for (const param of collision.getEParameters()) maybeAdd(param.getEType());
|
|
1363
|
+
}
|
|
1364
|
+
return [...names];
|
|
1365
|
+
}
|
|
1366
|
+
function findUnnamedElements(pkg) {
|
|
1367
|
+
const problems = [];
|
|
1368
|
+
const check = (element, kind, where) => {
|
|
1369
|
+
if (element.getName() === void 0) problems.push(`${where}: a ${kind} with no name`);
|
|
1370
|
+
};
|
|
1371
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
1372
|
+
check(classifier, "classifier", pkg.getName() ?? "(this package)");
|
|
1373
|
+
if (isEClass2(classifier)) {
|
|
1374
|
+
for (const feature of classifier.getEStructuralFeatures())
|
|
1375
|
+
check(feature, "feature", classifier.getName() ?? "(unnamed classifier)");
|
|
1376
|
+
for (const op of classifier.getEOperations()) {
|
|
1377
|
+
check(op, "operation", classifier.getName() ?? "(unnamed classifier)");
|
|
1378
|
+
for (const param of op.getEParameters())
|
|
1379
|
+
check(
|
|
1380
|
+
param,
|
|
1381
|
+
"parameter",
|
|
1382
|
+
`${classifier.getName() ?? "(unnamed classifier)"}.${op.getName() ?? "(unnamed operation)"}`
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1385
|
+
} else if (isEEnum(classifier)) {
|
|
1386
|
+
for (const literal of classifier.getELiterals())
|
|
1387
|
+
check(literal, "enum literal", classifier.getName() ?? "(unnamed classifier)");
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return problems;
|
|
1391
|
+
}
|
|
1392
|
+
function findUnresolvedCollisions(pkg) {
|
|
1393
|
+
const packageClassifierName = "EPackage";
|
|
1394
|
+
const isSelfHosting = [...pkg.getEClassifiers()].some((c) => c.getName() === packageClassifierName && isEClass2(c));
|
|
1395
|
+
const classifiers = [...pkg.getEClassifiers()].filter(isEClass2);
|
|
1396
|
+
const results = [];
|
|
1397
|
+
function scan(chainRoot, label, extra) {
|
|
1398
|
+
const chain = superTypeChain(chainRoot);
|
|
1399
|
+
const byName2 = /* @__PURE__ */ new Map();
|
|
1400
|
+
const add = (name, source) => {
|
|
1401
|
+
if (!byName2.has(name)) byName2.set(name, []);
|
|
1402
|
+
byName2.get(name).push(source);
|
|
1403
|
+
};
|
|
1404
|
+
for (const [name, source] of extra) add(name, source);
|
|
1405
|
+
for (const anc of chain) {
|
|
1406
|
+
const ancName = anc.getName();
|
|
1407
|
+
for (const f of anc.getEStructuralFeatures()) {
|
|
1408
|
+
add(beanGetterName(f), `${ancName}.${f.getName()} getter`);
|
|
1409
|
+
if (!f.isMany()) {
|
|
1410
|
+
add("set" + f.getName()[0].toUpperCase() + f.getName().slice(1), `${ancName}.${f.getName()} setter`);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
for (const group of groupOperationsByName(anc.getEOperations())) {
|
|
1414
|
+
const op = group[0];
|
|
1415
|
+
if (isBookkeepingOperation(op, anc)) continue;
|
|
1416
|
+
add(op.getName(), `${ancName}.${op.getName()} operation`);
|
|
1417
|
+
}
|
|
1418
|
+
if (isClassifierDerived(anc) && ancName === "EClassifier") {
|
|
1419
|
+
add("getClassifierID", `${ancName} bookkeeping`);
|
|
1420
|
+
add("setClassifierID", `${ancName} bookkeeping`);
|
|
1421
|
+
}
|
|
1422
|
+
if (isStructuralFeatureDerived(anc) && ancName === "EStructuralFeature") {
|
|
1423
|
+
add("getFeatureID", `${ancName} bookkeeping`);
|
|
1424
|
+
add("setFeatureID", `${ancName} bookkeeping`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
for (const [name, sources] of byName2) {
|
|
1428
|
+
if (sources.length > 1) {
|
|
1429
|
+
results.push({ classifierName: label, memberName: name, sources });
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
for (const c of classifiers) {
|
|
1434
|
+
scan(c, c.getName(), []);
|
|
1435
|
+
}
|
|
1436
|
+
if (isSelfHosting) {
|
|
1437
|
+
const ePackageClassifier = classifiers.find((c) => c.getName() === packageClassifierName);
|
|
1438
|
+
const ownAccessors = [];
|
|
1439
|
+
for (const classifier of pkg.getEClassifiers()) {
|
|
1440
|
+
if (metaclassAccessorCollision(classifier.getName(), pkg)) continue;
|
|
1441
|
+
ownAccessors.push(["get" + classifier.getName(), `EcorePackage.get${classifier.getName()} metaclass accessor`]);
|
|
1442
|
+
}
|
|
1443
|
+
scan(ePackageClassifier, "EcorePackage", ownAccessors);
|
|
1444
|
+
}
|
|
1445
|
+
return results;
|
|
1446
|
+
}
|
|
1447
|
+
function referencedApiTypes(features, ...excludeTypeNames) {
|
|
1448
|
+
const exclude = new Set(excludeTypeNames);
|
|
1449
|
+
const names = /* @__PURE__ */ new Set();
|
|
1450
|
+
for (const feature of features) {
|
|
1451
|
+
const type = feature.getEType();
|
|
1452
|
+
if (type && (isEReference(feature) || isEEnum(type)) && !exclude.has(type.getName())) names.add(type.getName());
|
|
1453
|
+
for (const argument of genericArgumentClassifiers(feature.getEGenericType())) {
|
|
1454
|
+
if ((isEClass2(argument) || isEEnum(argument)) && !exclude.has(argument.getName()))
|
|
1455
|
+
names.add(argument.getName());
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
return [...names];
|
|
1459
|
+
}
|
|
1460
|
+
function referencedOperationTypes(operations, ...excludeTypeNames) {
|
|
1461
|
+
const exclude = new Set(excludeTypeNames);
|
|
1462
|
+
const names = /* @__PURE__ */ new Set();
|
|
1463
|
+
const maybeAdd = (type) => {
|
|
1464
|
+
if (type && (isEClass2(type) || isEEnum(type)) && !exclude.has(type.getName())) {
|
|
1465
|
+
names.add(type.getName());
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
for (const op of operations) {
|
|
1469
|
+
maybeAdd(op.getEType());
|
|
1470
|
+
for (const argument of genericArgumentClassifiers(op.getEGenericType())) maybeAdd(argument);
|
|
1471
|
+
for (const param of op.getEParameters()) {
|
|
1472
|
+
maybeAdd(param.getEType());
|
|
1473
|
+
for (const argument of genericArgumentClassifiers(param.getEGenericType())) maybeAdd(argument);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
return [...names];
|
|
1477
|
+
}
|
|
1478
|
+
function jsString(value) {
|
|
1479
|
+
if (value === void 0) {
|
|
1480
|
+
throw new Error(
|
|
1481
|
+
"jsString() received undefined - this means required metamodel data (a name, nsURI, nsPrefix, or annotation value) is missing on the source EPackage. JSON.stringify(undefined) is not a string, so this would otherwise silently emit an empty/malformed argument into generated code rather than failing clearly at generation time."
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
return JSON.stringify(value);
|
|
1485
|
+
}
|
|
1486
|
+
function detailsEntries(annotation) {
|
|
1487
|
+
return [...annotation.getDetails()].map((entry) => ({ key: entry.getKey() ?? "", value: entry.getValue() ?? "" }));
|
|
1488
|
+
}
|
|
1489
|
+
function eClassesOf(pkg) {
|
|
1490
|
+
return pkg.getEClassifiers().toArray().filter((c) => isEClass2(c) && c.getName() !== "EObject");
|
|
1491
|
+
}
|
|
1492
|
+
function concreteEClassesOf(pkg) {
|
|
1493
|
+
return eClassesOf(pkg).filter((c) => !c.isAbstract());
|
|
1494
|
+
}
|
|
1495
|
+
function findEClassByName(pkg, name) {
|
|
1496
|
+
return eClassesOf(pkg).find((c) => c.getName() === name);
|
|
1497
|
+
}
|
|
1498
|
+
function singleValuedFeatures(features) {
|
|
1499
|
+
return [...features].filter((f) => !f.isMany());
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
// src/typescript-template-set.ts
|
|
1503
|
+
var packageRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
1504
|
+
function useImport(name, location, opts) {
|
|
1505
|
+
importCollector.add({ name, location, file: opts.file, foundational: opts.foundational });
|
|
1506
|
+
return name;
|
|
1507
|
+
}
|
|
1508
|
+
var typescriptTemplateSet = {
|
|
1509
|
+
name: "typescript",
|
|
1510
|
+
baseFolder: join(packageRoot, "templates", "typescript"),
|
|
1511
|
+
validate(pkg) {
|
|
1512
|
+
return [
|
|
1513
|
+
...findUnnamedElements(pkg),
|
|
1514
|
+
...findUnresolvedCollisions(pkg).map(
|
|
1515
|
+
(c) => `${c.classifierName}.${c.memberName}: name collision between ${c.sources.join(" and ")}`
|
|
1516
|
+
)
|
|
1517
|
+
];
|
|
1518
|
+
},
|
|
1519
|
+
configureEnvironment(env, { pkg, options }) {
|
|
1520
|
+
importCollector.clear();
|
|
1521
|
+
beginGeneration(pkg, options);
|
|
1522
|
+
env.addGlobal("docComment", docComment);
|
|
1523
|
+
env.addGlobal("operationBody", operationBody);
|
|
1524
|
+
env.addGlobal("featureGetter", featureGetter);
|
|
1525
|
+
env.addGlobal("featureSetter", featureSetter);
|
|
1526
|
+
env.addGlobal("isReadOnlyFeature", isReadOnlyFeature);
|
|
1527
|
+
env.addGlobal("needsImplOnlySetter", needsImplOnlySetter);
|
|
1528
|
+
env.addGlobal("customBodyNeedsOwnField", customBodyNeedsOwnField);
|
|
1529
|
+
env.addGlobal("registerBodyImports", registerBodyImports);
|
|
1530
|
+
env.addGlobal("overloadDispatch", overloadDispatch);
|
|
1531
|
+
env.addGlobal("tsScalarType", tsScalarType);
|
|
1532
|
+
env.addGlobal("tsFeatureType", tsFeatureType);
|
|
1533
|
+
env.addGlobal("tsOperationReturnType", tsOperationReturnType);
|
|
1534
|
+
env.addGlobal("isOptional", isOptional);
|
|
1535
|
+
env.addGlobal("isEClass", isEClass2);
|
|
1536
|
+
env.addGlobal("isEEnum", isEEnum);
|
|
1537
|
+
env.addGlobal("isEDataType", isEDataType);
|
|
1538
|
+
env.addGlobal("isEReference", isEReference);
|
|
1539
|
+
env.addGlobal("paramList", paramList);
|
|
1540
|
+
env.addGlobal("argList", argList);
|
|
1541
|
+
env.addGlobal("ucfirst", ucfirst);
|
|
1542
|
+
env.addGlobal("packageClassName", packageClassName);
|
|
1543
|
+
env.addGlobal("factoryClassName", factoryClassName);
|
|
1544
|
+
env.addGlobal("switchClassName", switchClassName);
|
|
1545
|
+
env.addGlobal("superType", superType);
|
|
1546
|
+
env.addGlobal("superTypeChain", superTypeChain);
|
|
1547
|
+
env.addGlobal("referencedApiTypes", referencedApiTypes);
|
|
1548
|
+
env.addGlobal("referencedOperationTypes", referencedOperationTypes);
|
|
1549
|
+
env.addGlobal("eClassesOf", eClassesOf);
|
|
1550
|
+
env.addGlobal("concreteEClassesOf", concreteEClassesOf);
|
|
1551
|
+
env.addGlobal("singleValuedFeatures", singleValuedFeatures);
|
|
1552
|
+
env.addGlobal("trivialDerivedFormula", trivialDerivedFormula);
|
|
1553
|
+
env.addGlobal("findEClassByName", findEClassByName);
|
|
1554
|
+
env.addGlobal("jsString", jsString);
|
|
1555
|
+
env.addGlobal("detailsEntries", detailsEntries);
|
|
1556
|
+
env.addGlobal("beanGetterName", beanGetterName);
|
|
1557
|
+
env.addGlobal("isPrimitiveValueType", isPrimitiveValueType);
|
|
1558
|
+
env.addGlobal("primitiveDefaultValue", primitiveDefaultValue);
|
|
1559
|
+
env.addGlobal("tsOptionalScalarType", tsOptionalScalarType);
|
|
1560
|
+
env.addGlobal("groupOperationsByName", groupOperationsByName);
|
|
1561
|
+
env.addGlobal("mergedParamList", mergedParamList);
|
|
1562
|
+
env.addGlobal("mergedReturnType", mergedReturnType);
|
|
1563
|
+
env.addGlobal("isClassifierDerived", isClassifierDerived);
|
|
1564
|
+
env.addGlobal("isBookkeepingOperation", isBookkeepingOperation);
|
|
1565
|
+
env.addGlobal("metaclassAccessorCollision", metaclassAccessorCollision);
|
|
1566
|
+
env.addGlobal("metaclassAccessorCollisionTypeNames", metaclassAccessorCollisionTypeNames);
|
|
1567
|
+
env.addGlobal("optionalParamList", optionalParamList);
|
|
1568
|
+
env.addGlobal("typeGuardsClassName", typeGuardsClassName);
|
|
1569
|
+
env.addGlobal("useImport", useImport);
|
|
1570
|
+
},
|
|
1571
|
+
postProcessFile(path, content, options) {
|
|
1572
|
+
const header = importCollector.render(locationOfPath(path), options);
|
|
1573
|
+
importCollector.clear();
|
|
1574
|
+
return header ? `${header}
|
|
1575
|
+
|
|
1576
|
+
${content}` : content;
|
|
1577
|
+
}
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
// src/template-set-registry.ts
|
|
1581
|
+
var builtinTemplateSets = {
|
|
1582
|
+
typescript: typescriptTemplateSet
|
|
1583
|
+
};
|
|
1584
|
+
function resolveTemplateSet(name) {
|
|
1585
|
+
const set = builtinTemplateSets[name];
|
|
1586
|
+
if (!set) {
|
|
1587
|
+
const known = Object.keys(builtinTemplateSets).join(", ");
|
|
1588
|
+
throw new Error(`Unknown template set '${name}'. Known built-in sets: ${known}.`);
|
|
1589
|
+
}
|
|
1590
|
+
return set;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
// src/run-generation.ts
|
|
1594
|
+
async function runGeneration(config, configDir, pkg) {
|
|
1595
|
+
const templateSet = resolveTemplateSet(config.templateSet);
|
|
1596
|
+
const files = generate(pkg, templateSet, config.options);
|
|
1597
|
+
const outputRoot = resolve(configDir, config.outputDir);
|
|
1598
|
+
const writtenPaths = [];
|
|
1599
|
+
for (const file of files) {
|
|
1600
|
+
const fullPath = join2(outputRoot, file.path);
|
|
1601
|
+
await mkdir(dirname2(fullPath), { recursive: true });
|
|
1602
|
+
await writeFile(fullPath, file.content, "utf-8");
|
|
1603
|
+
writtenPaths.push(fullPath);
|
|
1604
|
+
}
|
|
1605
|
+
return { writtenPaths, outputRoot };
|
|
1606
|
+
}
|
|
1607
|
+
export {
|
|
1608
|
+
ECLIPSE_ECORE_ANNOTATION_SOURCE,
|
|
1609
|
+
ECLIPSE_GENMODEL_ANNOTATION_SOURCE,
|
|
1610
|
+
FEATURE_ANNOTATION_SOURCE,
|
|
1611
|
+
TYPEMF_GENERATOR_ANNOTATION_SOURCE,
|
|
1612
|
+
argList,
|
|
1613
|
+
assignFreshIds,
|
|
1614
|
+
beanGetterName,
|
|
1615
|
+
buildEcoreMetaSchema,
|
|
1616
|
+
concreteEClassesOf,
|
|
1617
|
+
convertDynamicEcoreToTyped,
|
|
1618
|
+
customBodyNeedsOwnField,
|
|
1619
|
+
detailsEntries,
|
|
1620
|
+
docComment,
|
|
1621
|
+
documentationOf,
|
|
1622
|
+
eClassesOf,
|
|
1623
|
+
factoryClassName,
|
|
1624
|
+
featureGetter,
|
|
1625
|
+
featureSetter,
|
|
1626
|
+
findEClassByName,
|
|
1627
|
+
findFeatureAnnotationProblems,
|
|
1628
|
+
findUnnamedElements,
|
|
1629
|
+
findUnresolvedCollisions,
|
|
1630
|
+
generate,
|
|
1631
|
+
genericArgumentClassifiers,
|
|
1632
|
+
groupOperationsByName,
|
|
1633
|
+
isBookkeepingOperation,
|
|
1634
|
+
isClassifierDerived,
|
|
1635
|
+
isEClass2 as isEClass,
|
|
1636
|
+
isEDataType,
|
|
1637
|
+
isEEnum,
|
|
1638
|
+
isEReference,
|
|
1639
|
+
isOperationDerived,
|
|
1640
|
+
isOptional,
|
|
1641
|
+
isPrimitiveValueType,
|
|
1642
|
+
isReadOnlyFeature,
|
|
1643
|
+
isStructuralFeatureDerived,
|
|
1644
|
+
jsString,
|
|
1645
|
+
layeredAnnotationDetail,
|
|
1646
|
+
loadConfig,
|
|
1647
|
+
loadEcorePackage,
|
|
1648
|
+
mergedParamList,
|
|
1649
|
+
mergedReturnType,
|
|
1650
|
+
metaclassAccessorCollision,
|
|
1651
|
+
metaclassAccessorCollisionTypeNames,
|
|
1652
|
+
needsImplOnlySetter,
|
|
1653
|
+
operationBody,
|
|
1654
|
+
optionalParamList,
|
|
1655
|
+
overloadDispatch,
|
|
1656
|
+
packageClassName,
|
|
1657
|
+
paramList,
|
|
1658
|
+
primitiveDefaultValue,
|
|
1659
|
+
referencedApiTypes,
|
|
1660
|
+
referencedOperationTypes,
|
|
1661
|
+
registerBodyImports,
|
|
1662
|
+
resolveDataTypeTs,
|
|
1663
|
+
resolveTemplateSet,
|
|
1664
|
+
runGeneration,
|
|
1665
|
+
singleValuedFeatures,
|
|
1666
|
+
superType,
|
|
1667
|
+
superTypeChain,
|
|
1668
|
+
switchClassName,
|
|
1669
|
+
trivialDerivedFormula,
|
|
1670
|
+
tsFeatureType,
|
|
1671
|
+
tsOperationReturnType,
|
|
1672
|
+
tsOptionalScalarType,
|
|
1673
|
+
tsScalarType,
|
|
1674
|
+
typeGuardsClassName,
|
|
1675
|
+
typescriptTemplateSet,
|
|
1676
|
+
ucfirst
|
|
1677
|
+
};
|
|
1678
|
+
//# sourceMappingURL=index.js.map
|