@typemf/generator 0.5.1 → 0.6.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/dist/cli.js CHANGED
@@ -62,6 +62,7 @@ import {
62
62
  ETypeParameterImpl,
63
63
  EParameterImpl,
64
64
  EReferenceImpl,
65
+ getProxyURI,
65
66
  isEClassifier,
66
67
  resolveAgainstPackage
67
68
  } from "@typemf/core";
@@ -101,7 +102,7 @@ function convertDynamicEcoreToTyped(dynamicPkg) {
101
102
  }
102
103
  function classifierOf(dynClassifier) {
103
104
  if (classifierMap.has(dynClassifier)) return classifierMap.get(dynClassifier);
104
- const uri = dynClassifier.eIsProxy() ? dynClassifier.getProxyURI() : void 0;
105
+ const uri = dynClassifier.eIsProxy() ? getProxyURI(dynClassifier) : void 0;
105
106
  const ecore = EcorePackageImpl.eINSTANCE;
106
107
  if (uri && uri.trimFragment().toString() === ecore.getNsURI()) {
107
108
  const fragment = uri.getFragment() ?? "";
package/dist/index.js CHANGED
@@ -57,6 +57,7 @@ import {
57
57
  ETypeParameterImpl,
58
58
  EParameterImpl,
59
59
  EReferenceImpl,
60
+ getProxyURI,
60
61
  isEClassifier,
61
62
  resolveAgainstPackage
62
63
  } from "@typemf/core";
@@ -96,7 +97,7 @@ function convertDynamicEcoreToTyped(dynamicPkg) {
96
97
  }
97
98
  function classifierOf(dynClassifier) {
98
99
  if (classifierMap.has(dynClassifier)) return classifierMap.get(dynClassifier);
99
- const uri = dynClassifier.eIsProxy() ? dynClassifier.getProxyURI() : void 0;
100
+ const uri = dynClassifier.eIsProxy() ? getProxyURI(dynClassifier) : void 0;
100
101
  const ecore = EcorePackageImpl.eINSTANCE;
101
102
  if (uri && uri.trimFragment().toString() === ecore.getNsURI()) {
102
103
  const fragment = uri.getFragment() ?? "";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli-config.ts","../src/ecore-loader.ts","../src/ecore-dynamic-to-typed.ts","../src/ecore-meta-schema.ts","../src/id-assignment.ts","../src/generate.ts","../src/file-extension.ts","../src/run-generation.ts","../src/typescript-template-set.ts","../src/type-import-mapping.ts","../src/generation-context.ts","../src/import-collector.ts","../src/typescript-filters.ts","../src/template-set-registry.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\n/**\n * One config, one template set, one .ecore file, one outputDir - per the\n * design discussion. Multi-language generation is achieved by running the\n * CLI multiple times with different config files (e.g.\n * typescript.typemf-generator.json, java.typemf-generator.json), not by\n * one config handling multiple sets.\n */\nexport interface GeneratorConfig {\n ecoreFile: string;\n outputDir: string;\n templateSet: string;\n options: Record<string, unknown>;\n}\n\nexport async function loadConfig(configPath: string): Promise<GeneratorConfig> {\n let raw: string;\n try {\n raw = await readFile(configPath, 'utf-8');\n } catch (err) {\n throw new Error(`Could not read config file '${configPath}': ${(err as Error).message}`, { cause: err });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(`Failed to parse '${configPath}' as JSON: ${(err as Error).message}`, { cause: err });\n }\n\n return validateConfig(parsed, configPath);\n}\n\nfunction validateConfig(value: unknown, configPath: string): GeneratorConfig {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`'${configPath}' must contain a JSON object.`);\n }\n const obj = value as Record<string, unknown>;\n\n for (const key of ['ecoreFile', 'outputDir', 'templateSet']) {\n if (typeof obj[key] !== 'string' || obj[key] === '') {\n throw new Error(`'${configPath}': \"${key}\" is required and must be a non-empty string.`);\n }\n }\n\n if (\n obj.options !== undefined &&\n (typeof obj.options !== 'object' || obj.options === null || Array.isArray(obj.options))\n ) {\n throw new Error(`'${configPath}': \"options\", if present, must be a JSON object.`);\n }\n\n return {\n ecoreFile: obj.ecoreFile as string,\n outputDir: obj.outputDir as string,\n templateSet: obj.templateSet as string,\n options: (obj.options as Record<string, unknown> | undefined) ?? {},\n };\n}\n","import { EcorePackageImpl, EPackage, ResourceSetImpl, URI } from '@typemf/core';\nimport { NodeFileUriConverter } from '@typemf/node';\nimport { registerXmiFormat } from '@typemf/xmi';\nimport { convertDynamicEcoreToTyped } from './ecore-dynamic-to-typed.js';\nimport { buildEcoreMetaSchema } from './ecore-meta-schema.js';\n\n/**\n * Loads a real .ecore file into a typed EPackage. A .ecore file is an\n * ordinary XMI instance document whose root happens to be an EPackage -\n * read here by @typemf/xmi's own generic XmiSerializer, with no separate\n * parsing logic of its own. Interpreting it correctly needs a registered\n * meta-schema describing what \"EClass\"/\"EAttribute\"/etc mean (see\n * ecore-meta-schema.ts) - this produces a DYNAMIC EObject graph, which\n * gets converted (see ecore-dynamic-to-typed.ts) into the real, typed\n * EPackage generate() actually needs as input. See NOTES.md for the full\n * bootstrapping story and why this two-step shape is necessary - NOT\n * because hand-written classes lack eSet() support (they support it fully\n * for every real, modeled feature now, confirmed directly), but because\n * bookkeeping fields (classifierID, featureID, containerClass,\n * operationID) are deliberately excluded from eSet() by design, matching\n * real EMF, and generate()'s own internals need those set too (via plain\n * methods and id-assignment.ts, not eSet) - so a pure eSet-driven read\n * could never be sufficient on its own regardless.\n */\nexport async function loadEcorePackage(ecoreFilePath: string): Promise<EPackage> {\n // Post-swap, every @typemf/core setter (setName() included) routes through getEcorePackageRef(),\n // which needs Ecore's own metaclass system bootstrapped first - this triggers that safely, once,\n // right here (the single earliest entry point), before buildEcoreMetaSchema() OR\n // convertDynamicEcoreToTyped() construct a single typed metaclass instance. See NOTES.md's point\n // 6/7 write-ups.\n void EcorePackageImpl.eINSTANCE;\n const resourceSet = new ResourceSetImpl();\n resourceSet.getUriConverterRegistry().register(new NodeFileUriConverter());\n registerXmiFormat(resourceSet.getResourceFactoryRegistry());\n\n const metaSchema = buildEcoreMetaSchema();\n resourceSet.getPackageRegistry().register(metaSchema.pkg);\n\n const uri = URI.createFileURI(ecoreFilePath);\n const resource = await resourceSet.getResource(uri, true);\n if (!resource) {\n throw new Error(`Could not load '${ecoreFilePath}'.`);\n }\n\n const roots = resource.getContents().toArray();\n const dynamicPkg = roots[0];\n if (!dynamicPkg) {\n throw new Error(`'${ecoreFilePath}' has no root element - expected a single EPackage.`);\n }\n\n return convertDynamicEcoreToTyped(dynamicPkg);\n}\n","import {\n EAnnotationImpl,\n EAttributeImpl,\n EClass,\n setDetailValue,\n EClassifier,\n EClassImpl,\n EcorePackageImpl,\n EDataTypeImpl,\n EEnumImpl,\n EEnumLiteralImpl,\n EGenericTypeImpl,\n EModelElement,\n EObject,\n EOperationImpl,\n EPackage,\n EPackageImpl,\n ETypeParameterImpl,\n EParameterImpl,\n EReferenceImpl,\n EStructuralFeature,\n isEClassifier,\n ProxyEObjectImpl,\n resolveAgainstPackage,\n type EGenericType,\n type ETypedElement,\n type ETypeParameter,\n} from '@typemf/core';\n\n/**\n * Converts a dynamic EObject graph - produced by parsing a real .ecore\n * file against the meta-schema (see ecore-meta-schema.ts) - into a real,\n * typed EPackage built from @typemf/core's own hand-written classes. This\n * is the piece generate() actually needs as input; a dynamic graph, even\n * though it fully supports eGet/eSet reflectively, doesn't have the plain\n * convenience methods (setClassifierID(), recomputeAllLists(), ...)\n * generate()'s own internals call directly - only the real typed classes\n * do. This conversion writes via the real classes' own plain methods\n * throughout, not because eSet() itself is unsupported there (it is, for\n * every real, modeled feature - confirmed directly, this comment used to\n * claim otherwise), but because bookkeeping (classifierID, featureID,\n * containerClass, operationID) is deliberately unreachable via eSet by\n * design, matching real EMF, and this conversion needs to set exactly\n * that bookkeeping too - so writing everything through the SAME plain\n * methods uniformly is simpler than splitting eSet-for-real-features from\n * plain-calls-for-bookkeeping. It reads reflectively throughout (eGet, by\n * name, off whatever meta-schema classifier each dynamic object happens\n * to be an instance of).\n *\n * A classifier named \"EObject\" in the source graph (present only so\n * \"#//EObject\" fragments resolve during parsing - see\n * ecore-meta-schema.ts) is deliberately NOT converted into a real\n * classifier here: any reference to it becomes `undefined` on the real\n * side, matching the generator's own existing convention for a classifier\n * with no explicit type (which already means \"real @typemf/core EObject\").\n */\nexport function convertDynamicEcoreToTyped(dynamicPkg: EObject): EPackage {\n const realPkg = new EPackageImpl();\n realPkg.setName(byName<string>(dynamicPkg, 'name') ?? '');\n realPkg.setNsURI(byName<string>(dynamicPkg, 'nsURI') ?? '');\n realPkg.setNsPrefix(byName<string>(dynamicPkg, 'nsPrefix') ?? '');\n copyAnnotations(dynamicPkg, realPkg);\n\n const dynamicClassifiers = listByName(dynamicPkg, 'eClassifiers');\n\n // dynamic classifier instance -> real classifier (EObject-named ones map\n // to undefined - see doc comment).\n const classifierMap = new Map<EObject, EClassifier | undefined>();\n // dynamic feature instance -> real feature (for eOpposite wiring, a\n // second pass after every feature on every class already exists).\n const featureMap = new Map<EObject, EStructuralFeature>();\n // dynamic type-parameter instance -> real ETypeParameter (so an\n // EGenericType that refers to one can be wired up).\n const typeParameterMap = new Map<EObject, ETypeParameter>();\n\n // Pass 1: every classifier as a real, empty shell - keyed by what KIND\n // of thing the dynamic instance itself reflectively is (an instance of\n // the meta-schema's own \"EClass\"/\"EDataType\"/\"EEnum\" classifier).\n for (const dyn of dynamicClassifiers) {\n const kind = dyn.eClass().getName();\n const name = byName<string>(dyn, 'name') ?? '';\n if (name === 'EObject') {\n classifierMap.set(dyn, undefined);\n continue;\n }\n if (kind === 'EClass') {\n const c = new EClassImpl();\n c.setName(name);\n copyAnnotations(dyn, c);\n classifierMap.set(dyn, c);\n } else if (kind === 'EEnum') {\n const e = new EEnumImpl();\n e.setName(name);\n copyAnnotations(dyn, e);\n classifierMap.set(dyn, e);\n } else {\n // EDataType (or an unrecognized classifier kind - treated\n // defensively as a plain named datatype).\n const d = new EDataTypeImpl();\n d.setName(name);\n copyAnnotations(dyn, d);\n classifierMap.set(dyn, d);\n }\n }\n\n /**\n * The real classifier a dynamic classifier reference denotes: one of this package's own, or, for a\n * proxy into Ecore (e.g. `http://www.eclipse.org/emf/2002/Ecore#//EString`), Ecore's own. Ecore's\n * EObject maps to undefined, like a local one.\n */\n function classifierOf(dynClassifier: EObject): EClassifier | undefined {\n if (classifierMap.has(dynClassifier)) return classifierMap.get(dynClassifier);\n const uri = dynClassifier.eIsProxy() ? (dynClassifier as ProxyEObjectImpl).getProxyURI() : undefined;\n const ecore = EcorePackageImpl.eINSTANCE;\n if (uri && uri.trimFragment().toString() === ecore.getNsURI()) {\n const fragment = uri.getFragment() ?? '';\n if (fragment === '//EObject') return undefined;\n const resolved = resolveAgainstPackage(ecore, fragment);\n if (isEClassifier(resolved)) return resolved;\n }\n throw new Error(\n `Cannot resolve the classifier reference '${uri?.toString() ?? dynClassifier.fullId()}': only classifiers of this package and of Ecore are supported.`\n );\n }\n\n /** Resolves a dynamic classifier reference, or reads eGenericType.eClassifier as a fallback when eType itself is unset. */\n function resolveType(dynFeature: EObject): EClassifier | undefined {\n const dynType = byNameRaw(dynFeature, 'eType') as EObject | undefined;\n if (dynType) return classifierOf(dynType);\n const dynGeneric = byNameRaw(dynFeature, 'eGenericType') as EObject | undefined;\n if (dynGeneric) {\n const dynClassifier = byNameRaw(dynGeneric, 'eClassifier') as EObject | undefined;\n if (dynClassifier) return classifierOf(dynClassifier);\n }\n return undefined;\n }\n\n /**\n * A real EGenericType mirroring a dynamic one, recursively: its\n * classifier and type parameter (each only if set AND resolvable - an\n * EObject-bound reference resolves to undefined here, the same\n * documented loss as anywhere else EObject is dropped, so it reads as\n * \"unbound\"), and every type argument in order (an argument with\n * neither is Ecore's `<eTypeArguments/>`: unbound).\n */\n function convertGenericType(dynGeneric: EObject): EGenericType {\n const gt = new EGenericTypeImpl();\n const dynClassifier = byNameRaw(dynGeneric, 'eClassifier') as EObject | undefined;\n if (dynClassifier) gt.setEClassifier(classifierOf(dynClassifier));\n const dynParameter = byNameRaw(dynGeneric, 'eTypeParameter') as EObject | undefined;\n if (dynParameter) gt.setETypeParameter(typeParameterMap.get(dynParameter));\n for (const dynArgument of listByName(dynGeneric, 'eTypeArguments')) {\n gt.getETypeArguments().add(convertGenericType(dynArgument));\n }\n return gt;\n }\n\n /** Sets a real typed element's type from its dynamic counterpart: the full generic type when it has one (which also sets eType), else the plain eType. */\n function applyType(dynTyped: EObject, real: ETypedElement): void {\n const dynGeneric = byNameRaw(dynTyped, 'eGenericType') as EObject | undefined;\n if (dynGeneric) {\n real.setEGenericType(convertGenericType(dynGeneric));\n return;\n }\n const type = resolveType(dynTyped);\n if (type) real.setEType(type);\n }\n\n // Pass 2: classifier-level scalar properties + EClass.eSuperTypes (every\n // classifier now exists, so cross-references resolve).\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real) continue;\n const kind = dyn.eClass().getName();\n\n for (const dynParameter of listByName(dyn, 'eTypeParameters')) {\n const parameter = new ETypeParameterImpl();\n parameter.setName(byName<string>(dynParameter, 'name') ?? '');\n real.getETypeParameters().add(parameter);\n typeParameterMap.set(dynParameter, parameter);\n }\n\n // instanceClassName (on every EClassifier in real Ecore.ecore, not just\n // EDataType) - consumed by the typescript template set's layered\n // EDataType-to-TypeScript-type resolution (see typescript-filters.ts).\n const instanceClassName = byName<string>(dyn, 'instanceClassName');\n if (instanceClassName !== undefined && instanceClassName !== '') real.setInstanceClassName(instanceClassName);\n\n if (kind === 'EClass') {\n const c = real as EClass;\n if (byName<boolean>(dyn, 'abstract')) c.setAbstract(true);\n if (byName<boolean>(dyn, 'interface')) c.setInterface(true);\n for (const dynSuper of listByName(dyn, 'eSuperTypes')) {\n const realSuper = classifierOf(dynSuper);\n if (realSuper) c.getESuperTypes().add(realSuper as EClass);\n }\n }\n }\n\n // Pass 3: structural features + operations, for every EClass.\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real || dyn.eClass().getName() !== 'EClass') continue;\n const realClass = real as EClass;\n\n for (const dynFeature of listByName(dyn, 'eStructuralFeatures')) {\n const featureKind = dynFeature.eClass().getName();\n const name = byName<string>(dynFeature, 'name') ?? '';\n const lowerBound = byName<number>(dynFeature, 'lowerBound');\n const upperBound = byName<number>(dynFeature, 'upperBound');\n\n if (featureKind === 'EReference') {\n const r = new EReferenceImpl();\n r.setName(name);\n applyType(dynFeature, r);\n if (typeof lowerBound === 'number') r.setLowerBound(lowerBound);\n if (typeof upperBound === 'number') r.setUpperBound(upperBound);\n if (byName<boolean>(dynFeature, 'containment')) r.setContainment(true);\n if (byName<boolean>(dynFeature, 'resolveProxies') === false) r.setResolveProxies(false);\n r.setEContainingClass(realClass);\n copyFeatureFlags(dynFeature, r);\n copyAnnotations(dynFeature, r);\n realClass.getEStructuralFeatures().add(r);\n featureMap.set(dynFeature, r);\n } else {\n // EAttribute\n const a = new EAttributeImpl();\n a.setName(name);\n applyType(dynFeature, a);\n if (typeof lowerBound === 'number') a.setLowerBound(lowerBound);\n if (typeof upperBound === 'number') a.setUpperBound(upperBound);\n if (byName<boolean>(dynFeature, 'iD')) a.setID(true);\n copyFeatureFlags(dynFeature, a); // now copies defaultValueLiteral too - see copyFeatureFlags\n a.setEContainingClass(realClass);\n copyAnnotations(dynFeature, a);\n realClass.getEStructuralFeatures().add(a);\n featureMap.set(dynFeature, a);\n }\n }\n\n for (const dynOp of listByName(dyn, 'eOperations')) {\n const op = new EOperationImpl();\n op.setName(byName<string>(dynOp, 'name') ?? '');\n applyType(dynOp, op);\n copyAnnotations(dynOp, op);\n const opLowerBound = byName<number>(dynOp, 'lowerBound');\n const opUpperBound = byName<number>(dynOp, 'upperBound');\n if (typeof opLowerBound === 'number') op.setLowerBound(opLowerBound);\n if (typeof opUpperBound === 'number') op.setUpperBound(opUpperBound);\n for (const dynParam of listByName(dynOp, 'eParameters')) {\n const param = new EParameterImpl();\n param.setName(byName<string>(dynParam, 'name') ?? '');\n applyType(dynParam, param);\n const paramLowerBound = byName<number>(dynParam, 'lowerBound');\n const paramUpperBound = byName<number>(dynParam, 'upperBound');\n if (typeof paramLowerBound === 'number') param.setLowerBound(paramLowerBound);\n if (typeof paramUpperBound === 'number') param.setUpperBound(paramUpperBound);\n op.getEParameters().add(param);\n }\n realClass.getEOperations().add(op);\n }\n }\n\n // Pass 4: EEnum.eLiterals (deferred until here purely for readability;\n // no cross-classifier dependency involved).\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real || dyn.eClass().getName() !== 'EEnum') continue;\n for (const dynLiteral of listByName(dyn, 'eLiterals')) {\n const lit = new EEnumLiteralImpl();\n lit.setName(byName<string>(dynLiteral, 'name') ?? '');\n lit.setValue(byName<number>(dynLiteral, 'value') ?? 0);\n lit.setLiteral(byName<string>(dynLiteral, 'literal') ?? byName<string>(dynLiteral, 'name') ?? '');\n copyAnnotations(dynLiteral, lit);\n // addLiteral() no longer exists - @typemf/core's own EEnumLiteralImpl is itself now generated\n // code, properly extending EObjectImpl, so the ordinary getELiterals().add() path correctly\n // wires the eEnum opposite automatically (see NOTES.md's point 6/7 write-ups, and the matching\n // fix in epackage.njk).\n (real as EEnumImpl).getELiterals().add(lit);\n }\n }\n\n // Pass 5: eOpposite (every feature on every class now exists).\n for (const [dynFeature, realFeature] of featureMap) {\n const dynOpposite = byNameRaw(dynFeature, 'eOpposite') as EObject | undefined;\n if (!dynOpposite) continue;\n const realOpposite = featureMap.get(dynOpposite);\n if (realOpposite && 'setEOpposite' in realFeature) {\n (realFeature as EReferenceImpl).setEOpposite(realOpposite as EReferenceImpl);\n }\n }\n\n // Pass 6 (recompute EAll* caches for every real EClass) removed - recomputeAllLists() no longer\n // exists at all post-swap; generated get-bodied features cache automatically (see\n // EObjectImpl.getModelGeneration()), needing no manual recompute step.\n\n // Assemble.\n for (const real of classifierMap.values()) {\n if (real) realPkg.getEClassifiers().add(real);\n }\n\n return realPkg;\n}\n\n/**\n * Copies every EAnnotation (source + details) from a dynamic element onto\n * the corresponding real, typed one - package, classifier, feature,\n * operation and enum literal (not parameters). Operations matter because\n * that is where the generator reads an operation's `body` from (see\n * operationBody); they were left out here originally on the reasoning\n * that a converted operation has no runtime representation to attach to,\n * which is true of the GENERATED package's bootstrap (it builds no\n * operations, so emits no operation annotations) but not of this input\n * model, where a body written in a real .ecore file could otherwise\n * never reach the generator.\n */\nfunction copyAnnotations(dyn: EObject, real: EModelElement): void {\n for (const dynAnnotation of listByName(dyn, 'eAnnotations')) {\n const annotation = new EAnnotationImpl();\n const source = byName<string>(dynAnnotation, 'source');\n if (source !== undefined) annotation.setSource(source);\n for (const dynDetail of listByName(dynAnnotation, 'details')) {\n const key = byName<string>(dynDetail, 'key');\n const value = byName<string>(dynDetail, 'value');\n if (key !== undefined && value !== undefined) {\n setDetailValue(annotation.getDetails(), key, value);\n }\n }\n real.getEAnnotations().add(annotation);\n }\n}\n\n/**\n * Copies changeable/volatile/transient/derived/unsettable from a dynamic\n * feature onto the real one. A real, previously-missed gap: without this,\n * EVERY feature converted from a real .ecore file loses these flags\n * entirely (defaulting to changeable=true, everything else false) -\n * regardless of what the source file actually declares. Concretely, this\n * silently broke the generator's derived-feature formula treatment\n * (TRIVIAL_DERIVED_FORMULAS checks feature.isDerived() first) for every\n * real file this pipeline has ever converted, including real Ecore.ecore\n * itself - \"required\"/\"many\"/etc were generating as ordinary stored\n * fields, not the intended formulas, until this was added.\n */\nfunction copyFeatureFlags(dyn: EObject, real: EStructuralFeature): void {\n const changeable = byName<boolean>(dyn, 'changeable');\n if (changeable === false) real.setChangeable(false);\n if (byName<boolean>(dyn, 'volatile')) real.setVolatile(true);\n if (byName<boolean>(dyn, 'transient')) real.setTransient(true);\n if (byName<boolean>(dyn, 'derived')) real.setDerived(true);\n if (byName<boolean>(dyn, 'unsettable')) real.setUnsettable(true);\n const defaultValueLiteral = byName<string>(dyn, 'defaultValueLiteral');\n if (defaultValueLiteral !== undefined) real.setDefaultValueLiteral(defaultValueLiteral);\n}\n\n/** Reads a named feature's value reflectively, off whatever classifier `obj` happens to be an instance of. */\nfunction byNameRaw(obj: EObject, featureName: string): unknown {\n const feature = obj.eClass().getEStructuralFeature(featureName);\n if (!feature) return undefined;\n return obj.eGet(feature);\n}\n\nfunction byName<T>(obj: EObject, featureName: string): T | undefined {\n return byNameRaw(obj, featureName) as T | undefined;\n}\n\nfunction listByName(obj: EObject, featureName: string): EObject[] {\n const value = byNameRaw(obj, featureName);\n if (!value) return [];\n return [...(value as Iterable<EObject>)];\n}\n","import {\n DynamicEFactoryImpl,\n EAttributeImpl,\n EClassImpl,\n EDataTypeImpl,\n EPackageImpl,\n EReferenceImpl,\n type EClass,\n} from '@typemf/core';\nimport { assignFreshIds } from './id-assignment.js';\n\n/**\n * A hand-authored graph mirroring real Ecore.ecore's own full structure -\n * every EClass, every EDataType, every declared feature (including\n * derived/transient ones - these ARE present in the real file as ordinary\n * <eStructuralFeatures> descriptions of what features a class HAS; what's\n * never serialized is a VALUE for a derived feature on some downstream\n * instance, which never comes up while parsing Ecore.ecore itself, since\n * this file describes structure, not instances-of-that-structure).\n *\n * Two distinct roles, same shape:\n * 1. Registered as the meta-schema the generic XmiSerializer needs to\n * interpret the real Ecore.ecore file at all (a .ecore file is an\n * ordinary XMI instance document whose root is an EPackage - reading\n * it needs SOME registered EPackage describing what \"EClass\"/\n * \"EAttribute\"/etc mean, or there's nothing to dispatch xsi:type\n * against).\n * 2. The target shape the dynamic-graph -> typed-EPackage conversion step\n * produces after parsing - what actually gets fed to generate().\n *\n * EObject gets a real classifier shell here (needed so \"#//EObject\"\n * fragments - e.g. EAnnotation.contents: EObject[] - resolve during\n * parsing) but is deliberately excluded from what the GENERATOR treats as\n * a real classifier to produce files for: it's the one name the generator\n * special-cases exactly the way it already handles \"no declared supertype\"\n * (see eclass.njk) - any reference to a classifier named \"EObject\"\n * resolves to @typemf/core's own real EObject instead of generating a\n * redundant, shadowing one.\n *\n * Does NOT model EString/EInt/EBoolean/etc as anything other than bare\n * EDataType shells - no instanceClassName is set here beyond a name;\n * `serializable`/`defaultValueLiteral` on real Ecore.ecore's own\n * EDataType declarations are read during conversion where present, not\n * hardcoded into this meta-schema (the meta-schema only needs to recognize\n * these as valid attributes to parse, not carry their real values itself).\n */\nexport function buildEcoreMetaSchema() {\n // --- Primitive EDataTypes (bare shells; real Ecore.ecore's own\n // instanceClassName/serializable/etc values are read from the file\n // itself during conversion, not hardcoded here).\n const primitiveNames = [\n 'EBigDecimal',\n 'EBigInteger',\n 'EBoolean',\n 'EBooleanObject',\n 'EByte',\n 'EByteArray',\n 'EByteObject',\n 'EChar',\n 'ECharacterObject',\n 'EDate',\n 'EDiagnosticChain',\n 'EDouble',\n 'EDoubleObject',\n 'EEList',\n 'EEnumerator',\n 'EFeatureMap',\n 'EFeatureMapEntry',\n 'EFloat',\n 'EFloatObject',\n 'EInt',\n 'EIntegerObject',\n 'EJavaClass',\n 'EJavaObject',\n 'ELong',\n 'ELongObject',\n 'EMap',\n 'EResource',\n 'EResourceSet',\n 'EShort',\n 'EShortObject',\n 'EString',\n 'ETreeIterator',\n 'EInvocationTargetException',\n ];\n const primitives = new Map(\n primitiveNames.map((n) => [\n n,\n (() => {\n const d = new EDataTypeImpl();\n d.setName(n);\n return d;\n })(),\n ])\n );\n const p = (name: string) => primitives.get(name)!;\n\n // --- Pass 1: every EClass as an empty shell.\n const eObject = new EClassImpl();\n eObject.setName('EObject');\n const eModelElement = new EClassImpl();\n eModelElement.setName('EModelElement');\n eModelElement.setAbstract(true);\n const eAnnotation = new EClassImpl();\n eAnnotation.setName('EAnnotation');\n const eNamedElement = new EClassImpl();\n eNamedElement.setName('ENamedElement');\n eNamedElement.setAbstract(true);\n const eTypedElement = new EClassImpl();\n eTypedElement.setName('ETypedElement');\n eTypedElement.setAbstract(true);\n const eClassifier = new EClassImpl();\n eClassifier.setName('EClassifier');\n eClassifier.setAbstract(true);\n const eStructuralFeature = new EClassImpl();\n eStructuralFeature.setName('EStructuralFeature');\n eStructuralFeature.setAbstract(true);\n const eAttribute = new EClassImpl();\n eAttribute.setName('EAttribute');\n const eReference = new EClassImpl();\n eReference.setName('EReference');\n const eClass = new EClassImpl();\n eClass.setName('EClass');\n const ePackage = new EClassImpl();\n ePackage.setName('EPackage');\n const eDataType = new EClassImpl();\n eDataType.setName('EDataType');\n const eEnum = new EClassImpl();\n eEnum.setName('EEnum');\n const eEnumLiteral = new EClassImpl();\n eEnumLiteral.setName('EEnumLiteral');\n const eFactory = new EClassImpl();\n eFactory.setName('EFactory');\n const eOperation = new EClassImpl();\n eOperation.setName('EOperation');\n const eParameter = new EClassImpl();\n eParameter.setName('EParameter');\n const eStringToStringMapEntry = new EClassImpl();\n eStringToStringMapEntry.setName('EStringToStringMapEntry');\n const eGenericType = new EClassImpl();\n eGenericType.setName('EGenericType');\n const eTypeParameter = new EClassImpl();\n eTypeParameter.setName('ETypeParameter');\n\n // --- Pass 2: supertypes.\n eAnnotation.getESuperTypes().add(eModelElement);\n eNamedElement.getESuperTypes().add(eModelElement);\n eTypedElement.getESuperTypes().add(eNamedElement);\n eClassifier.getESuperTypes().add(eNamedElement);\n eStructuralFeature.getESuperTypes().add(eTypedElement);\n eAttribute.getESuperTypes().add(eStructuralFeature);\n eReference.getESuperTypes().add(eStructuralFeature);\n eClass.getESuperTypes().add(eClassifier);\n ePackage.getESuperTypes().add(eNamedElement);\n eDataType.getESuperTypes().add(eClassifier);\n eEnum.getESuperTypes().add(eDataType);\n eEnumLiteral.getESuperTypes().add(eNamedElement);\n eFactory.getESuperTypes().add(eModelElement);\n eOperation.getESuperTypes().add(eTypedElement);\n eParameter.getESuperTypes().add(eTypedElement);\n eTypeParameter.getESuperTypes().add(eNamedElement);\n\n const allClasses: EClass[] = [\n eObject,\n eModelElement,\n eAnnotation,\n eNamedElement,\n eTypedElement,\n eClassifier,\n eStructuralFeature,\n eAttribute,\n eReference,\n eClass,\n ePackage,\n eDataType,\n eEnum,\n eEnumLiteral,\n eFactory,\n eOperation,\n eParameter,\n eStringToStringMapEntry,\n eGenericType,\n eTypeParameter,\n ];\n\n // --- Small helpers to keep pass 3 readable - mirror real Ecore.ecore's\n // own feature declarations line-for-line, not a generalized DSL.\n function attr(\n owner: EClass,\n name: string,\n type: EClass | ReturnType<typeof p>,\n opts: { many?: boolean; changeable?: boolean; volatile?: boolean; transient?: boolean; derived?: boolean } = {}\n ) {\n const a = new EAttributeImpl();\n a.setName(name);\n a.setEType(type);\n if (opts.many) a.setUpperBound(-1);\n if (opts.changeable === false) a.setChangeable(false);\n if (opts.volatile) a.setVolatile(true);\n if (opts.transient) a.setTransient(true);\n if (opts.derived) a.setDerived(true);\n a.setEContainingClass(owner);\n owner.getEStructuralFeatures().add(a);\n return a;\n }\n function ref(\n owner: EClass,\n name: string,\n type: EClass,\n opts: {\n many?: boolean;\n containment?: boolean;\n changeable?: boolean;\n volatile?: boolean;\n transient?: boolean;\n derived?: boolean;\n } = {}\n ) {\n const r = new EReferenceImpl();\n r.setName(name);\n r.setEType(type);\n if (opts.many) r.setUpperBound(-1);\n if (opts.containment) r.setContainment(true);\n if (opts.changeable === false) r.setChangeable(false);\n if (opts.volatile) r.setVolatile(true);\n if (opts.transient) r.setTransient(true);\n if (opts.derived) r.setDerived(true);\n r.setEContainingClass(owner);\n owner.getEStructuralFeatures().add(r);\n return r;\n }\n\n // --- Pass 3: features, per class, matching real Ecore.ecore's own\n // declaration order.\n\n // EModelElement\n const eAnnotations = ref(eModelElement, 'eAnnotations', eAnnotation, { many: true, containment: true });\n\n // EAnnotation\n attr(eAnnotation, 'source', p('EString'));\n ref(eAnnotation, 'details', eStringToStringMapEntry, { many: true, containment: true });\n const annotation_eModelElement = ref(eAnnotation, 'eModelElement', eModelElement, { transient: true });\n ref(eAnnotation, 'contents', eObject, { many: true, containment: true });\n ref(eAnnotation, 'references', eObject, { many: true });\n\n // ENamedElement\n attr(eNamedElement, 'name', p('EString'));\n\n // ETypedElement\n attr(eTypedElement, 'ordered', p('EBoolean'));\n attr(eTypedElement, 'unique', p('EBoolean'));\n attr(eTypedElement, 'lowerBound', p('EInt'));\n attr(eTypedElement, 'upperBound', p('EInt'));\n attr(eTypedElement, 'many', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n attr(eTypedElement, 'required', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n const eType = ref(eTypedElement, 'eType', eClassifier, { volatile: true });\n ref(eTypedElement, 'eGenericType', eGenericType, { containment: true, volatile: true });\n\n // EClassifier\n const classifier_ePackage = ref(eClassifier, 'ePackage', ePackage, { changeable: false, transient: true });\n ref(eClassifier, 'eTypeParameters', eTypeParameter, { many: true, containment: true });\n attr(eClassifier, 'instanceClassName', p('EString'), { volatile: true });\n attr(eClassifier, 'instanceClass', p('EJavaClass'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eClassifier, 'defaultValue', p('EJavaObject'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eClassifier, 'instanceTypeName', p('EString'), { volatile: true });\n\n // EStructuralFeature\n attr(eStructuralFeature, 'changeable', p('EBoolean'));\n attr(eStructuralFeature, 'volatile', p('EBoolean'));\n attr(eStructuralFeature, 'transient', p('EBoolean'));\n attr(eStructuralFeature, 'defaultValueLiteral', p('EString'));\n attr(eStructuralFeature, 'defaultValue', p('EJavaObject'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eStructuralFeature, 'unsettable', p('EBoolean'));\n attr(eStructuralFeature, 'derived', p('EBoolean'));\n const feature_eContainingClass = ref(eStructuralFeature, 'eContainingClass', eClass, {\n changeable: false,\n transient: true,\n });\n\n // EAttribute\n attr(eAttribute, 'iD', p('EBoolean'));\n ref(eAttribute, 'eAttributeType', eDataType, { changeable: false, volatile: true, transient: true, derived: true });\n\n // EReference\n attr(eReference, 'containment', p('EBoolean'));\n attr(eReference, 'container', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n attr(eReference, 'resolveProxies', p('EBoolean'));\n const eOpposite = ref(eReference, 'eOpposite', eReference, {});\n ref(eReference, 'eReferenceType', eClass, { changeable: false, volatile: true, transient: true, derived: true });\n ref(eReference, 'eKeys', eAttribute, { many: true });\n\n // EClass\n attr(eClass, 'abstract', p('EBoolean'));\n attr(eClass, 'interface', p('EBoolean'));\n ref(eClass, 'eSuperTypes', eClass, { many: true });\n const eOperations = ref(eClass, 'eOperations', eOperation, { many: true, containment: true });\n ref(eClass, 'eAllAttributes', eAttribute, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllReferences', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eReferences', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAttributes', eAttribute, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllContainments', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllOperations', eOperation, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllStructuralFeatures', eStructuralFeature, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllSuperTypes', eClass, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eIDAttribute', eAttribute, { changeable: false, volatile: true, transient: true, derived: true });\n const eStructuralFeatures = ref(eClass, 'eStructuralFeatures', eStructuralFeature, { many: true, containment: true });\n ref(eClass, 'eGenericSuperTypes', eGenericType, { many: true, containment: true });\n ref(eClass, 'eAllGenericSuperTypes', eGenericType, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n\n // EDataType\n attr(eDataType, 'serializable', p('EBoolean'));\n\n // EEnum\n const eLiterals = ref(eEnum, 'eLiterals', eEnumLiteral, { many: true, containment: true });\n\n // EEnumLiteral\n attr(eEnumLiteral, 'value', p('EInt'));\n attr(eEnumLiteral, 'instance', p('EEnumerator'), { transient: true });\n attr(eEnumLiteral, 'literal', p('EString'));\n const eEnumLiteral_eEnum = ref(eEnumLiteral, 'eEnum', eEnum, { changeable: false, transient: true });\n\n // EFactory\n const factory_ePackage = ref(eFactory, 'ePackage', ePackage, { transient: true });\n\n // EObject - reflective operations only, no structural features of its\n // own (matches the real file), and no eOperations shell needed here\n // since nothing in Ecore.ecore itself declares operations ON an EObject\n // instance the way it does for EClass etc.\n\n // EOperation\n const operation_eContainingClass = ref(eOperation, 'eContainingClass', eClass, {\n changeable: false,\n transient: true,\n });\n ref(eOperation, 'eTypeParameters', eTypeParameter, { many: true, containment: true });\n const eParameters = ref(eOperation, 'eParameters', eParameter, { many: true, containment: true });\n ref(eOperation, 'eExceptions', eClassifier, { many: true });\n ref(eOperation, 'eGenericExceptions', eGenericType, { many: true, containment: true });\n\n // EPackage\n attr(ePackage, 'nsURI', p('EString'));\n attr(ePackage, 'nsPrefix', p('EString'));\n const eFactoryInstance = ref(ePackage, 'eFactoryInstance', eFactory, { transient: true });\n const eClassifiers = ref(ePackage, 'eClassifiers', eClassifier, { many: true, containment: true });\n const eSubpackages = ref(ePackage, 'eSubpackages', ePackage, { many: true, containment: true });\n const eSuperPackage = ref(ePackage, 'eSuperPackage', ePackage, { changeable: false, transient: true });\n\n // EParameter\n const parameter_eOperation = ref(eParameter, 'eOperation', eOperation, { changeable: false, transient: true });\n\n // EStringToStringMapEntry\n attr(eStringToStringMapEntry, 'key', p('EString'));\n attr(eStringToStringMapEntry, 'value', p('EString'));\n\n // EGenericType\n ref(eGenericType, 'eUpperBound', eGenericType, { containment: true });\n ref(eGenericType, 'eTypeArguments', eGenericType, { many: true, containment: true });\n ref(eGenericType, 'eRawType', eClassifier, { changeable: false, transient: true, derived: true });\n ref(eGenericType, 'eLowerBound', eGenericType, { containment: true });\n ref(eGenericType, 'eTypeParameter', eTypeParameter, {});\n ref(eGenericType, 'eClassifier', eClassifier, {});\n\n // ETypeParameter\n ref(eTypeParameter, 'eBounds', eGenericType, { many: true, containment: true });\n\n // --- Pass 4: opposites (symmetric pairs; matches real Ecore.ecore's own\n // eOpposite declarations exactly).\n eAnnotations.setEOpposite(annotation_eModelElement);\n annotation_eModelElement.setEOpposite(eAnnotations);\n classifier_ePackage.setEOpposite(eClassifiers);\n eClassifiers.setEOpposite(classifier_ePackage);\n feature_eContainingClass.setEOpposite(eStructuralFeatures);\n eStructuralFeatures.setEOpposite(feature_eContainingClass);\n operation_eContainingClass.setEOpposite(eOperations);\n eOperations.setEOpposite(operation_eContainingClass);\n parameter_eOperation.setEOpposite(eParameters);\n eParameters.setEOpposite(parameter_eOperation);\n factory_ePackage.setEOpposite(eFactoryInstance);\n eFactoryInstance.setEOpposite(factory_ePackage);\n eSubpackages.setEOpposite(eSuperPackage);\n eSuperPackage.setEOpposite(eSubpackages);\n eEnumLiteral_eEnum.setEOpposite(eLiterals);\n eLiterals.setEOpposite(eEnumLiteral_eEnum);\n // eOpposite itself is intentionally NOT paired with a reverse eOpposite -\n // matches real Ecore.ecore exactly (EMF handles the symmetry at runtime,\n // not via a modeled self-loop).\n void eOpposite;\n void eType;\n\n // Assemble the package. Real Ecore's own nsURI/nsPrefix/name.\n const pkg = new EPackageImpl();\n pkg.setName('ecore');\n pkg.setNsURI('http://www.eclipse.org/emf/2002/Ecore');\n pkg.setNsPrefix('ecore');\n for (const d of primitives.values()) pkg.getEClassifiers().add(d);\n for (const c of allClasses) pkg.getEClassifiers().add(c);\n pkg.setEFactoryInstance(new DynamicEFactoryImpl());\n\n // Pass 5: assign real, unique featureIDs to every feature (also\n // recomputes EAll* caches internally). Critical, not cosmetic here:\n // DynamicEObjectImpl indexes its own internal storage by featureID, so\n // every feature needs a distinct one before any dynamic instance is\n // constructed against this schema - without this, every feature\n // defaults to the same -1 and many-valued lists silently collide.\n assignFreshIds(pkg);\n\n return {\n pkg,\n eObject,\n eModelElement,\n eAnnotation,\n eNamedElement,\n eTypedElement,\n eClassifier,\n eStructuralFeature,\n eAttribute,\n eReference,\n eClass,\n ePackage,\n eDataType,\n eEnum,\n eEnumLiteral,\n eFactory,\n eOperation,\n eParameter,\n eStringToStringMapEntry,\n eGenericType,\n eTypeParameter,\n };\n}\n","import { EClass, EClassifier, EClassifierImpl, EOperationImpl, EPackage, EStructuralFeatureImpl } from '@typemf/core';\n\n/**\n * Assigns classifierID/featureID freshly, in declaration order, mutating\n * the EClass/EStructuralFeature objects directly - matches real EMF's own\n * behaviour (these are recomputed-every-build implementation details of\n * the generated code, not values meant to persist anywhere). See the\n * design discussion: our wire formats (json/xmi) address by name, never by\n * numeric ID, so this never threatens file compatibility - the only\n * observable effect is generated-code diff noise across unrelated\n * metamodel edits, a cosmetic cost judged acceptable given it matches\n * upstream EMF precedent.\n *\n * featureID is assigned over getEAllStructuralFeatures() (inherited-then-\n * own, matching real EMF), NOT a per-class restart at 0 - a subclass's\n * generated eGet/eSet needs one flat ID space covering both its inherited\n * and its own features (a generated subclass typically delegates any\n * featureID it doesn't recognize to `super.eGet()`/`super.eSet()`), so an\n * inherited feature and a subclass's own new feature must never collide.\n * Reassigning via any subclass's getEAllStructuralFeatures() is safe to\n * repeat for the same feature across multiple classes in the hierarchy -\n * the computed index is the same regardless of which class's perspective\n * computes it, since supertype features always come first in the same\n * relative order.\n *\n * operationID follows the exact same shape and rationale, over\n * getEAllOperations() instead - added for point 4 (EOperation.\n * getOperationID(), which just exposes this).\n */\nexport function assignFreshIds(pkg: EPackage): void {\n let classifierId = 0;\n for (const classifier of pkg.getEClassifiers()) {\n // classifierID/featureID/operationID are deliberately impl-only - not on the public interfaces at\n // all, matching real EMF's own design (see EStructuralFeature.getContainerClass()'s doc comment\n // for the fullest version of this reasoning). assignFreshIds() IS the legitimate \"set once during\n // bootstrap\" caller these setters exist for, so casting to the concrete impl here is correct, not\n // a workaround - the same pattern the generated getOperationID(operation)/getFeatureID(feature)\n // convenience methods themselves use internally.\n (classifier as EClassifierImpl).setClassifierID(classifierId++);\n }\n for (const classifier of pkg.getEClassifiers()) {\n if (!isEClass(classifier)) continue;\n // No recomputeAllLists() call needed anymore - generated get-bodied features cache automatically\n // (see EObjectImpl.getModelGeneration()), unlike hand-written core's old manual-recompute pattern\n // this used to rely on.\n classifier\n .getEAllStructuralFeatures()\n .forEach((feature, index) => (feature as EStructuralFeatureImpl).setFeatureID(index));\n classifier.getEAllOperations().forEach((op, index) => (op as EOperationImpl).setOperationID(index));\n }\n}\n\nfunction isEClass(classifier: EClassifier): classifier is EClass {\n return 'getEStructuralFeatures' in classifier;\n}\n","import { EPackage } from '@typemf/core';\nimport nunjucks from 'nunjucks';\nimport { FileExtension } from './file-extension.js';\nimport { GeneratedFile } from './generated-file.js';\nimport { assignFreshIds } from './id-assignment.js';\nimport { TemplateSet } from './template-set.js';\n\n/**\n * Renders `templateSet`'s main.njk once, over the whole `pkg`. Pure - no\n * disk I/O beyond reading the template files themselves; writing the\n * returned files anywhere is a separate, later step the caller owns. See\n * the design discussion for why `outputDir` deliberately isn't a\n * parameter here: every returned path is relative, so relative imports\n * between generated files are computable without knowing an eventual\n * absolute location.\n */\nexport function generate(\n pkg: EPackage,\n templateSet: TemplateSet,\n options: Record<string, unknown> = {}\n): GeneratedFile[] {\n assignFreshIds(pkg);\n\n const problems = templateSet.validate?.(pkg) ?? [];\n if (problems.length > 0) {\n throw new Error(\n `Cannot generate from this package - ${templateSet.name} found ${problems.length} unresolved problem(s):\\n` +\n problems.map((p) => ` - ${p}`).join('\\n')\n );\n }\n\n const loader = new nunjucks.FileSystemLoader(templateSet.baseFolder, { noCache: true });\n const env = new nunjucks.Environment(loader, { autoescape: false, trimBlocks: true, lstripBlocks: true });\n\n const fileExtension = new FileExtension(\n templateSet.postProcessFile ? (path, content) => templateSet.postProcessFile!(path, content, options) : undefined\n );\n env.addExtension('file', fileExtension);\n env.addGlobal('package', pkg);\n env.addGlobal('options', options);\n\n templateSet.configureEnvironment?.(env, { pkg, options });\n\n env.render('main.njk');\n\n return fileExtension.getCollected();\n}\n","import { GeneratedFile } from './generated-file.js';\n\n/**\n * `{% file somePathExpression %}...content...{% endfile %}` - the\n * mechanism that lets a single template produce any number of output\n * files. The path argument is a full Nunjucks expression (e.g.\n * `eClass.getName() + \"-impl.ts\"`), not a string literal.\n *\n * Content rendered OUTSIDE any {% file %} block is silently discarded -\n * deliberately, so `{% include %}`/`{% macro %}` plumbing and stray\n * whitespace between tags never leak into an actual output file, and so\n * every template-set author follows one uniform rule (\"wrap output in\n * {% file %}, always\") rather than a fallback that's sometimes needed and\n * sometimes isn't.\n *\n * `parser`/`nodes` below are typed as `any`: this is Nunjucks' low-level\n * custom-tag-authoring API (Environment.addExtension), which @types/nunjucks\n * doesn't cover at all (only the high-level render/configure surface is\n * typed) - verified empirically against the real runtime API rather than\n * assumed, since no type declarations exist to check against.\n */\nexport class FileExtension {\n tags = ['file'];\n private readonly collected: GeneratedFile[] = [];\n\n constructor(private readonly postProcess?: (path: string, content: string) => string) {}\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parse(parser: any, nodes: any): any {\n const tok = parser.nextToken();\n const pathExpr = parser.parseExpression();\n parser.advanceAfterBlockEnd(tok.value);\n\n const body = parser.parseUntilBlocks('endfile');\n parser.advanceAfterBlockEnd();\n\n return new nodes.CallExtensionAsync(this, 'run', new nodes.NodeList(tok.lineno, tok.colno, [pathExpr]), [body]);\n }\n\n run(\n _context: unknown,\n path: string,\n body: (callback: (err: unknown, res: string) => void) => void,\n callback: (err: unknown, res: string) => void\n ): void {\n body((err: unknown, content: string) => {\n if (err) {\n callback(err, '');\n return;\n }\n this.collected.push({ path, content: this.postProcess ? this.postProcess(path, content) : content });\n callback(null, '');\n });\n }\n\n /** Everything collected so far in this Environment's lifetime. */\n getCollected(): GeneratedFile[] {\n return this.collected;\n }\n}\n","import { EPackage } from '@typemf/core';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { GeneratorConfig } from './cli-config.js';\nimport { generate } from './generate.js';\nimport { resolveTemplateSet } from './template-set-registry.js';\n\nexport interface RunGenerationResult {\n writtenPaths: string[];\n outputRoot: string;\n}\n\n/**\n * `configDir` is the directory the config file itself lives in -\n * `config.outputDir` resolves relative to THAT, not the process's current\n * working directory, so a config file behaves identically regardless of\n * where the CLI happens to be invoked from.\n */\nexport async function runGeneration(\n config: GeneratorConfig,\n configDir: string,\n pkg: EPackage\n): Promise<RunGenerationResult> {\n const templateSet = resolveTemplateSet(config.templateSet);\n const files = generate(pkg, templateSet, config.options);\n\n const outputRoot = resolve(configDir, config.outputDir);\n const writtenPaths: string[] = [];\n for (const file of files) {\n const fullPath = join(outputRoot, file.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, file.content, 'utf-8');\n writtenPaths.push(fullPath);\n }\n\n return { writtenPaths, outputRoot };\n}\n","import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport type nunjucks from 'nunjucks';\nimport { TemplateSet } from './template-set.js';\nimport { beginGeneration } from './generation-context.js';\nimport { importCollector, ImportLocation, locationOfPath } from './import-collector.js';\nimport {\n argList,\n beanGetterName,\n concreteEClassesOf,\n detailsEntries,\n docComment,\n eClassesOf,\n factoryClassName,\n findEClassByName,\n groupOperationsByName,\n isEClass,\n isEDataType,\n isEEnum,\n isEReference,\n isOptional,\n isClassifierDerived,\n isBookkeepingOperation,\n findUnnamedElements,\n findUnresolvedCollisions,\n metaclassAccessorCollision,\n metaclassAccessorCollisionTypeNames,\n optionalParamList,\n isPrimitiveValueType,\n jsString,\n mergedParamList,\n mergedReturnType,\n featureGetter,\n featureSetter,\n isReadOnlyFeature,\n needsImplOnlySetter,\n customBodyNeedsOwnField,\n operationBody,\n overloadDispatch,\n registerBodyImports,\n packageClassName,\n paramList,\n primitiveDefaultValue,\n referencedApiTypes,\n referencedOperationTypes,\n singleValuedFeatures,\n superType,\n superTypeChain,\n switchClassName,\n trivialDerivedFormula,\n tsFeatureType,\n tsOperationReturnType,\n tsOptionalScalarType,\n tsScalarType,\n typeGuardsClassName,\n ucfirst,\n} from './typescript-filters.js';\n\n// One level up from this file (src/ or, after build, dist/) lands at the\n// package root either way, since both are direct children of it - see\n// NOTES.md for why this resolves correctly whether running from source\n// (tests) or from the built package.\nconst packageRoot = join(dirname(fileURLToPath(import.meta.url)), '..');\n\n/**\n * Records that the current file's body needs `name` from the given\n * location, returning `name` unchanged so it can be used inline exactly\n * where the type name would otherwise be written directly (e.g.\n * `{{ useImport(\"EAnnotation\", \"types\", {foundational: true}) }} | undefined`).\n * The recording is read back and rendered into real import statements by\n * postProcessFile below, once this file's whole body is known.\n */\nfunction useImport(name: string, location: ImportLocation, opts: { file?: string; foundational: boolean }): string {\n importCollector.add({ name, location, file: opts.file, foundational: opts.foundational });\n return name;\n}\n\nexport const typescriptTemplateSet: TemplateSet = {\n name: 'typescript',\n baseFolder: join(packageRoot, 'templates', 'typescript'),\n validate(pkg): string[] {\n return [\n ...findUnnamedElements(pkg),\n ...findUnresolvedCollisions(pkg).map(\n (c) => `${c.classifierName}.${c.memberName}: name collision between ${c.sources.join(' and ')}`\n ),\n ];\n },\n configureEnvironment(env: nunjucks.Environment, { pkg, options }): void {\n // Runs once per generate() call, before anything renders: drop any\n // reference a type-text function recorded outside a real generation\n // (a unit test calling tsScalarType directly, say) so it can't leak\n // into the first generated file's header.\n importCollector.clear();\n beginGeneration(pkg, options);\n env.addGlobal('docComment', docComment);\n env.addGlobal('operationBody', operationBody);\n env.addGlobal('featureGetter', featureGetter);\n env.addGlobal('featureSetter', featureSetter);\n env.addGlobal('isReadOnlyFeature', isReadOnlyFeature);\n env.addGlobal('needsImplOnlySetter', needsImplOnlySetter);\n env.addGlobal('customBodyNeedsOwnField', customBodyNeedsOwnField);\n env.addGlobal('registerBodyImports', registerBodyImports);\n env.addGlobal('overloadDispatch', overloadDispatch);\n env.addGlobal('tsScalarType', tsScalarType);\n env.addGlobal('tsFeatureType', tsFeatureType);\n env.addGlobal('tsOperationReturnType', tsOperationReturnType);\n env.addGlobal('isOptional', isOptional);\n env.addGlobal('isEClass', isEClass);\n env.addGlobal('isEEnum', isEEnum);\n env.addGlobal('isEDataType', isEDataType);\n env.addGlobal('isEReference', isEReference);\n env.addGlobal('paramList', paramList);\n env.addGlobal('argList', argList);\n env.addGlobal('ucfirst', ucfirst);\n env.addGlobal('packageClassName', packageClassName);\n env.addGlobal('factoryClassName', factoryClassName);\n env.addGlobal('switchClassName', switchClassName);\n env.addGlobal('superType', superType);\n env.addGlobal('superTypeChain', superTypeChain);\n env.addGlobal('referencedApiTypes', referencedApiTypes);\n env.addGlobal('referencedOperationTypes', referencedOperationTypes);\n env.addGlobal('eClassesOf', eClassesOf);\n env.addGlobal('concreteEClassesOf', concreteEClassesOf);\n env.addGlobal('singleValuedFeatures', singleValuedFeatures);\n env.addGlobal('trivialDerivedFormula', trivialDerivedFormula);\n env.addGlobal('findEClassByName', findEClassByName);\n env.addGlobal('jsString', jsString);\n env.addGlobal('detailsEntries', detailsEntries);\n env.addGlobal('beanGetterName', beanGetterName);\n env.addGlobal('isPrimitiveValueType', isPrimitiveValueType);\n env.addGlobal('primitiveDefaultValue', primitiveDefaultValue);\n env.addGlobal('tsOptionalScalarType', tsOptionalScalarType);\n env.addGlobal('groupOperationsByName', groupOperationsByName);\n env.addGlobal('mergedParamList', mergedParamList);\n env.addGlobal('mergedReturnType', mergedReturnType);\n env.addGlobal('isClassifierDerived', isClassifierDerived);\n env.addGlobal('isBookkeepingOperation', isBookkeepingOperation);\n env.addGlobal('metaclassAccessorCollision', metaclassAccessorCollision);\n env.addGlobal('metaclassAccessorCollisionTypeNames', metaclassAccessorCollisionTypeNames);\n env.addGlobal('optionalParamList', optionalParamList);\n env.addGlobal('typeGuardsClassName', typeGuardsClassName);\n env.addGlobal('useImport', useImport);\n },\n postProcessFile(path, content, options): string {\n const header = importCollector.render(locationOfPath(path), options);\n importCollector.clear();\n return header ? `${header}\\n\\n${content}` : content;\n },\n};\n","import { detailValue, EClassifier, EList, EModelElement, EStringToStringMapEntry } from '@typemf/core';\n\n/** The annotation source that says what to import and where it is imported from. */\nexport const IMPORT_ANNOTATION_SOURCE = 'https://typemf.dev/generator/import';\n\n/**\n * One import: which symbol, and where it comes from. (What TEXT a datatype\n * is emitted as is a separate matter - the `type` detail of the annotation\n * with source https://typemf.dev/generator; see resolveDataTypeTs. The two\n * usually name the same thing, but need not: the text may be `number |\n * undefined` while the symbol imported is something else.)\n *\n * - `type`: the symbol to import.\n * - `from`: the module other packages import it from - a module specifier,\n * used as written (e.g. \"@typemf/core\"). Applies to an EXTERNAL use:\n * the element belongs to a package other than the one being generated.\n * - `internalFrom`: where the package being generated imports it from,\n * relative to the ROOT of the generated package when it starts with\n * \"./\" or \"../\" (see ImportEntry.from). Applies to an INTERNAL use: the\n * element belongs to the package being generated. Falls back to `from`.\n */\nexport interface TypeImportInfo {\n type: string;\n from?: string;\n internalFrom?: string;\n}\n\n/** The same shape as the annotation's own detail keys, for entries supplied from outside the model (see TypeImportMapping). */\nexport type TypeImportEntries = Record<string, { type?: string; from?: string; 'internal-from'?: string }>;\n\nconst nonEmpty = (value: string | undefined): string | undefined =>\n value !== undefined && value !== '' ? value : undefined;\n\nfunction info(type: string, from: string | undefined, internalFrom: string | undefined): TypeImportInfo {\n const result: TypeImportInfo = { type };\n if (from !== undefined) result.from = from;\n if (internalFrom !== undefined) result.internalFrom = internalFrom;\n return result;\n}\n\nfunction importInfoOf(details: EList<EStringToStringMapEntry> | undefined): TypeImportInfo | undefined {\n const type = nonEmpty(details && detailValue(details, 'type'));\n if (type === undefined) return undefined;\n return info(\n type,\n nonEmpty(details && detailValue(details, 'from')),\n nonEmpty(details && detailValue(details, 'internal-from'))\n );\n}\n\n/**\n * The import information an element carries itself: the details `type`,\n * `from` and `internal-from` of its (first) annotation with source\n * https://typemf.dev/generator/import. Without a `type` the annotation says\n * nothing (there is no symbol to import) and is ignored. Values are used\n * as written - not checked, not interpreted; empty counts as absent.\n */\nexport function readImportAnnotation(element: EModelElement): TypeImportInfo | undefined {\n return importInfoOf(element.getEAnnotation(IMPORT_ANNOTATION_SOURCE)?.getDetails());\n}\n\n/**\n * EVERY import annotation on an element, in order - an element that needs\n * several imports (an operation whose body uses several symbols) carries\n * one annotation per import. Each is read like readImportAnnotation.\n */\nexport function readImportAnnotations(element: EModelElement): TypeImportInfo[] {\n const result: TypeImportInfo[] = [];\n for (const annotation of element.getEAnnotations()) {\n if (annotation.getSource() !== IMPORT_ANNOTATION_SOURCE) continue;\n const entry = importInfoOf(annotation.getDetails());\n if (entry !== undefined) result.push(entry);\n }\n return result;\n}\n\n/**\n * The one place import information for types is looked up. Today it is\n * fed by the annotations in the model (readImportAnnotation); explicit\n * entries - keyed `<package nsURI>#<classifier name>`, e.g.\n * \"http://www.eclipse.org/emf/2002/Ecore#EEList\" - take precedence over\n * an annotation and are the seam for supplying the same information from\n * outside the model (the generator config's mapping of ecore packages to\n * TypeScript modules): pre-populate them, and nothing else in the\n * generator changes. An explicit entry replaces the annotation entirely,\n * field by field is deliberately not merged.\n */\nexport class TypeImportMapping {\n private readonly explicit = new Map<string, TypeImportInfo>();\n\n constructor(entries: TypeImportEntries = {}) {\n for (const [key, entry] of Object.entries(entries)) {\n const type = nonEmpty(entry.type);\n if (type !== undefined) this.set(key, info(type, nonEmpty(entry.from), nonEmpty(entry['internal-from'])));\n }\n }\n\n static keyOf(classifier: EClassifier): string {\n return `${classifier.getEPackage()?.getNsURI() ?? ''}#${classifier.getName()}`;\n }\n\n set(key: string, value: TypeImportInfo): void {\n this.explicit.set(key, value);\n }\n\n lookup(classifier: EClassifier): TypeImportInfo | undefined {\n return this.explicit.get(TypeImportMapping.keyOf(classifier)) ?? readImportAnnotation(classifier);\n }\n}\n","import { EClassifier, EPackage } from '@typemf/core';\nimport { TypeImportEntries, TypeImportMapping } from './type-import-mapping.js';\n\n/**\n * What the type-resolution code needs to know about the generation in\n * progress: which package is being generated (so it can tell an internal\n * type from an external one), and the import mapping. A single shared\n * instance, like the import collector, set up once per generate() call by\n * the typescript template set (see beginGeneration) - the type-text\n * functions are called from templates and have no other way to reach it.\n */\nexport interface GenerationContext {\n pkg: EPackage | undefined;\n typeImports: TypeImportMapping;\n}\n\nexport const generationContext: GenerationContext = { pkg: undefined, typeImports: new TypeImportMapping() };\n\n/** The generation option that pre-populates the mapping - see TypeImportMapping. */\nexport const TYPE_IMPORTS_OPTION = 'type-imports';\n\nexport function beginGeneration(pkg: EPackage, options: Record<string, unknown>): void {\n generationContext.pkg = pkg;\n const entries = options[TYPE_IMPORTS_OPTION];\n const valid = typeof entries === 'object' && entries !== null && !Array.isArray(entries);\n generationContext.typeImports = new TypeImportMapping(valid ? (entries as TypeImportEntries) : {});\n}\n\n/** Back to \"no generation in progress\": nothing is external, the mapping is empty. */\nexport function resetGenerationContext(): void {\n generationContext.pkg = undefined;\n generationContext.typeImports = new TypeImportMapping();\n}\n\n/**\n * The internal/external decision, made per use during generation: a type\n * is EXTERNAL when it belongs to a package other than the one being\n * generated. With no generation in progress, or a type that belongs to no\n * package, nothing can be external.\n */\nexport function isExternal(classifier: EClassifier): boolean {\n const owner = classifier.getEPackage();\n return generationContext.pkg !== undefined && owner !== undefined && owner !== generationContext.pkg;\n}\n","import { posix } from 'node:path';\n\nexport type ImportLocation = 'root' | 'types' | 'impl' | 'util';\n\nexport interface ImportEntry {\n /** The identifier as it appears in generated code. */\n name: string;\n /** Which conceptual folder this name's own generated file lives in. */\n location: ImportLocation;\n /** File base name (no extension), if different from `name` - e.g. \"Ids\" and \"EcorePackage\" both come from the same file, \"EcorePackage.js\". */\n file?: string;\n /**\n * true for the foundational Ecore meta-types (EClass, EObjectImpl,\n * BasicEList, ...) that also exist as @typemf/core exports - these\n * resolve to '@typemf/core' in ordinary mode, and to a relative import\n * in generate-ecore mode (since that same file is being produced by\n * this generation run instead). false for names unique to the\n * metamodel being generated right now (the package class, its factory,\n * its Ref module, every classifier's own type) - these never exist in\n * @typemf/core at all, so they're always a relative import, regardless\n * of generate-ecore.\n */\n foundational: boolean;\n /**\n * An explicit module to import `name` from, overriding location/file/\n * foundational entirely - set from a type's import information (see\n * TypeImportMapping). A value starting with \"./\" or \"../\" is relative to the\n * ROOT of the generated package (where {Pkg}Package.ts lives), and gets\n * re-expressed relative to each importing file's own folder; anything\n * else is a bare module specifier, used verbatim.\n */\n from?: string;\n}\n\n/**\n * Computes the relative import path from a file in `from` to a file\n * named `file` living in `to` - both are the four conceptual folders\n * every generated package has (root alongside types/, impl/, util/).\n * Always a direct file path, never a barrel (`index.js`) - see\n * coreImportLine's old doc comment in git history for why: importing\n * from your own folder's barrel puts every file in that folder into one\n * strongly-connected component, which broke self-hosting's bootstrap\n * outright (confirmed empirically, not theoretical).\n */\nexport function relativeImportPath(from: ImportLocation, to: ImportLocation, file: string): string {\n if (from === to) return `./${file}.js`;\n if (from === 'root') return `./${to}/${file}.js`;\n if (to === 'root') return `../${file}.js`;\n return `../${to}/${file}.js`;\n}\n\n/**\n * Collects every type reference a template makes while rendering one\n * file's body (via `useType()`, see typescript-template-set.ts), then\n * renders the deduplicated, sorted, direct (never-barrel) import\n * statements for that file once its body is fully known.\n *\n * One instance lives for the whole generation run, reused across files:\n * call `clear()` between files (postProcessFile does this after each\n * file, in typescript-template-set.ts) rather than constructing a new\n * one - nunjucks globals are registered once for the whole Environment,\n * so this needs to be a single, stable object `useType` can find via\n * closure, not re-created per file.\n */\nexport class ImportCollector {\n /**\n * Every distinct way each name has been requested. Usually one; more\n * than one is only a problem if, once the mode and importing folder are\n * known (render time), they resolve to genuinely different modules.\n */\n private entries = new Map<string, ImportEntry[]>();\n\n add(entry: ImportEntry): void {\n const variants = this.entries.get(entry.name) ?? [];\n const sameSource = variants.findIndex(\n (v) => v.location === entry.location && (v.file ?? v.name) === (entry.file ?? entry.name) && v.from === entry.from\n );\n if (sameSource >= 0) {\n // Same source, different `foundational`: both resolve identically\n // once the mode is known (see ImportEntry's own doc comment) - this\n // genuinely happens for a real Ecore.ecore classifier that's ALSO\n // one of the fixed, always-present parameter/return types every\n // generated class has (e.g. \"EStructuralFeature\" in eGet(feature:\n // EStructuralFeature), separately from any reference to it AS a\n // classifier via referencedApiTypes). Prefer foundational: true -\n // the more general categorization, correct in both modes.\n if (entry.foundational && !variants[sameSource]!.foundational) variants[sameSource] = entry;\n } else {\n variants.push(entry);\n }\n this.entries.set(entry.name, variants);\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n isEmpty(): boolean {\n return this.entries.size === 0;\n }\n\n render(currentLocation: ImportLocation, options: Record<string, unknown>): string {\n const generateEcore = Boolean(options['generate-ecore']);\n const corePackageNames: string[] = [];\n const groups = new Map<string, { specifier: string; names: string[] }>();\n const addToGroup = (key: string, specifier: string, name: string) => {\n if (!groups.has(key)) groups.set(key, { specifier, names: [] });\n groups.get(key)!.names.push(name);\n };\n\n for (const name of [...this.entries.keys()].sort((a, b) => a.localeCompare(b))) {\n const resolved = this.entries\n .get(name)!\n .map((entry) => ({ entry, ...resolveEntry(entry, currentLocation, generateEcore) }));\n\n // Two requests for the same name are one import only if they name\n // the same module - \"the same module, however spelled\": the\n // extension is not significant (a datatype annotation's\n // an annotation's import path is used exactly as written, generated\n // paths always carry \".js\").\n const distinct = new Set(resolved.map((r) => r.specifier.replace(/\\.(js|ts)$/, '')));\n if (distinct.size > 1) {\n throw new Error(\n `Import collision while generating: \"${name}\" was requested from ` +\n `${resolved.map((r) => `\"${r.specifier}\"`).join(' and ')}. A single name must resolve to exactly one real source.`\n );\n }\n // An explicitly requested spelling (an annotation's own path) wins over a generated one.\n const chosen = resolved.find((r) => r.entry.from !== undefined) ?? resolved[0]!;\n if (chosen.core) corePackageNames.push(name);\n else addToGroup(chosen.key, chosen.specifier, name);\n }\n\n const lines: string[] = [];\n if (corePackageNames.length > 0) {\n lines.push(`import { ${corePackageNames.join(', ')} } from '@typemf/core';`);\n }\n for (const key of [...groups.keys()].sort()) {\n const { specifier, names } = groups.get(key)!;\n lines.push(`import { ${names.join(', ')} } from '${specifier}';`);\n }\n return lines.join('\\n');\n }\n}\n\nfunction resolveEntry(\n entry: ImportEntry,\n currentLocation: ImportLocation,\n generateEcore: boolean\n): { specifier: string; key: string; core: boolean } {\n if (entry.from !== undefined) {\n const specifier = explicitImportSpecifier(entry.from, currentLocation);\n // An explicitly requested \"@typemf/core\" IS the foundational package - one merged statement, not two.\n return { specifier, key: `~${specifier}`, core: specifier === '@typemf/core' };\n }\n if (entry.foundational && !generateEcore) return { specifier: '@typemf/core', key: '@typemf/core', core: true };\n const file = entry.file ?? entry.name;\n return {\n specifier: relativeImportPath(currentLocation, entry.location, file),\n key: `${entry.location}/${file}`,\n core: false,\n };\n}\n\n/** See ImportEntry.from. */\nexport function explicitImportSpecifier(from: string, currentLocation: ImportLocation): string {\n if (!from.startsWith('./') && !from.startsWith('../')) return from;\n const fromDir = posix.join('/pkg', currentLocation === 'root' ? '' : currentLocation);\n const relative = posix.relative(fromDir, posix.join('/pkg', from));\n return relative.startsWith('.') ? relative : `./${relative}`;\n}\n\n/**\n * The single collector shared by the whole typescript template set: both\n * templates (via useImport) and type-text functions (see\n * typescript-filters.ts's tsScalarType, which registers a datatype's\n * annotation-supplied import as it emits the type) record into this one\n * instance, and postProcessFile renders and clears it once per file.\n */\nexport const importCollector = new ImportCollector();\n\n/** Derives a file's ImportLocation from its own generated path (e.g. \"types/EClass.ts\" -> \"types\", \"EcorePackage.ts\" -> \"root\"). */\nexport function locationOfPath(path: string): ImportLocation {\n if (path.startsWith('types/')) return 'types';\n if (path.startsWith('impl/')) return 'impl';\n if (path.startsWith('util/')) return 'util';\n return 'root';\n}\n","import { generationContext, isExternal } from './generation-context.js';\nimport { importCollector } from './import-collector.js';\nimport { readImportAnnotations } from './type-import-mapping.js';\nimport {\n detailValue,\n EAnnotation,\n EClass,\n EClassifier,\n EDataType,\n EEnum,\n EGenericType,\n EModelElement,\n EOperation,\n EPackage,\n EStructuralFeature,\n ETypedElement,\n} from '@typemf/core';\n\n/** The generator's own annotation source. */\nexport const TYPEMF_GENERATOR_ANNOTATION_SOURCE = 'https://typemf.dev/generator';\n\n/** Real EMF's own GenModel annotation source - where its GenModel keeps an operation's `body`. */\nexport const ECLIPSE_GENMODEL_ANNOTATION_SOURCE = 'http://www.eclipse.org/emf/2002/GenModel';\n\n/** Real EMF's Ecore annotation source - the documentation fallback (real Ecore.ecore uses it for `constraints`). */\nexport const ECLIPSE_ECORE_ANNOTATION_SOURCE = 'http://www.eclipse.org/emf/2002/Ecore';\n\n/**\n * The layering rule shared by everything that is read from an element's\n * annotations under a plain key: the `key` detail of the annotation with\n * source https://typemf.dev/generator first, then the same key in the\n * annotation with source `fallbackSource`. Which fallback source applies\n * is decided per thing being read (see documentationOf, operationBody),\n * not globally. Used as written - not checked, not interpreted; an empty\n * value counts as absent (so it falls through to the next layer).\n */\nexport function layeredAnnotationDetail(\n element: EModelElement,\n key: string,\n fallbackSource: string\n): string | undefined {\n for (const source of [TYPEMF_GENERATOR_ANNOTATION_SOURCE, fallbackSource]) {\n const details = element.getEAnnotation(source)?.getDetails();\n const value = details && detailValue(details, key);\n if (value !== undefined && value !== '') return value;\n }\n return undefined;\n}\n\n/**\n * An element's documentation: the `documentation` detail, layered - the\n * typemf generator annotation first, the annotation with source\n * http://www.eclipse.org/emf/2002/Ecore as the fallback.\n *\n * NOTE: real EMF keeps `documentation` in the GenModel source\n * (http://www.eclipse.org/emf/2002/GenModel), not the Ecore one - so that\n * is deliberately NOT read here: documentation an EMF-authored .ecore\n * carries under GenModel is ignored unless it is also supplied under one\n * of the two sources above.\n */\nexport function documentationOf(element: EModelElement): string | undefined {\n return layeredAnnotationDetail(element, 'documentation', ECLIPSE_ECORE_ANNOTATION_SOURCE);\n}\n\n/**\n * Renders a JSDoc block from documentationOf(), or '' if there is none.\n * Deliberately WITHOUT a trailing newline: every template writes\n * `{{ docComment(x) }}` on its own line and puts the declaration on the\n * next one, so the template's own newline is what separates them - a\n * trailing newline here as well used to leave a blank line between every\n * doc comment and the declaration it documents.\n */\nexport function docComment(element: EModelElement, indent = ''): string {\n const doc = documentationOf(element);\n if (!doc) return '';\n const lines = doc.trim().split('\\n');\n if (lines.length === 1) {\n return `${indent}/** ${lines[0]} */`;\n }\n const body = lines.map((line) => `${indent} * ${line}`).join('\\n');\n return `${indent}/**\\n${body}\\n${indent} */`;\n}\n\n/**\n * An operation's body, in strict priority order:\n *\n * 1. the `body` detail of the annotation with source\n * https://typemf.dev/generator\n * 2. the `body` detail of the annotation with source\n * http://www.eclipse.org/emf/2002/GenModel\n *\n * Used as written - not checked, not interpreted; an empty value counts\n * as absent (the operation then gets the throwing stub). Note the second\n * layer is real EMF's own key, where the value is Java source: a real\n * EMF-authored .ecore that carries Java bodies there will have that Java\n * emitted verbatim unless a layer-1 body overrides it - which is the\n * point of the ordering, and the reason a layer-1 body should be added\n * to any operation whose GenModel body isn't valid TypeScript.\n *\n * (Earlier versions read a per-template-set key, `body:typescript`, on\n * the reasoning that one shared key would be ambiguous across multiple\n * target languages. Replaced on request by these two layers.)\n */\nexport function operationBody(operation: EOperation): string | undefined {\n return layeredAnnotationDetail(operation, 'body', ECLIPSE_GENMODEL_ANNOTATION_SOURCE);\n}\n\n/**\n * The annotation source for a structural feature's own custom getter/setter\n * bodies: `get` and `set` details of the annotation with source\n * https://typemf.dev/generator/feature. Deliberately NOT layered with a\n * GenModel fallback (unlike documentationOf/operationBody) - this source\n * was specified on its own, with no second layer requested.\n */\nexport const FEATURE_ANNOTATION_SOURCE = 'https://typemf.dev/generator/feature';\n\nfunction featureDetail(feature: EStructuralFeature, key: string): string | undefined {\n const details = feature.getEAnnotation(FEATURE_ANNOTATION_SOURCE)?.getDetails();\n const value = details && detailValue(details, key);\n return value !== undefined && value !== '' ? value : undefined;\n}\n\n/**\n * A feature's custom getter body (`get` detail), used verbatim as the body\n * of its bean getter method - and, so reflective access agrees with the\n * real implementation (the bug found and fixed for\n * EClass.getEAllStructuralFeatures: the generated eGet used to read the\n * STORED FIELD directly, bypassing any computed getter entirely), as what\n * `eGet` calls too. A feature with a custom getter has NO stored field at\n * all - there is nothing for the old field-reading shape to read.\n */\nexport function featureGetter(feature: EStructuralFeature): string | undefined {\n return featureDetail(feature, 'get');\n}\n\n/**\n * A feature's custom setter body (`set` detail), used verbatim as the body\n * of its bean setter method, and what `eSet` delegates to reflectively -\n * replacing the default oldValue/eBasicSetValue/eDidAdd/eDidRemove\n * machinery entirely, since a custom setter defines the feature's true\n * write semantics itself. Only meaningful for a SINGLE-valued feature: a\n * many-valued feature never has a setter method to begin with (real EMF\n * convention - the getter's EList is mutated directly), so a `set` on one\n * is a no-op, flagged by findFeatureAnnotationProblems.\n */\nexport function featureSetter(feature: EStructuralFeature): string | undefined {\n return featureDetail(feature, 'set');\n}\n\n/**\n * Whether a feature with both a custom getter and a custom setter genuinely needs its own backing\n * field - true only when at least one of the two bodies actually references it (`this._name`).\n * EEnumLiteral.literal's getter/setter do (\"this._literal ?? this.getName()\", \"this._literal =\n * value\") - it needs a field. A feature whose getter/setter delegate entirely to a DIFFERENT\n * feature (e.g. a \"shout\" getter/setter that only ever reads/writes \"raw\") does not - declaring an\n * unused field for it would be dead weight, and checking `eIsSet`/`eUnset` against that field would\n * be flatly wrong (the field never changes, so \"is set\" would never reflect reality). Found by\n * running this exact case: an earlier version of this rule declared a field for EVERY getter+setter\n * pair unconditionally, breaking any feature that delegates to another one entirely.\n */\nexport function customBodyNeedsOwnField(feature: EStructuralFeature): boolean {\n const getter = featureGetter(feature);\n const setter = featureSetter(feature);\n if (!getter && !setter) return false;\n const ownFieldRef = new RegExp(`\\\\bthis\\\\._${feature.getName()}\\\\b`);\n return (getter !== undefined && ownFieldRef.test(getter)) || (setter !== undefined && ownFieldRef.test(setter));\n}\n\n/**\n * Whether a single-valued feature has no setter at all: either a\n * trivialDerivedFormula (pre-existing, hard-coded), or a custom getter\n * with no custom setter (a feature computed by featureGetter, and nothing\n * says how to write it back). A many-valued feature is unaffected by this\n * (it never has a setter regardless).\n */\nexport function isReadOnlyFeature(feature: EStructuralFeature): boolean {\n return (\n trivialDerivedFormula(feature) !== undefined ||\n (featureGetter(feature) !== undefined && featureSetter(feature) === undefined)\n );\n}\n\n/**\n * A changeable=false feature that isn't otherwise read-only (not derived, no custom getter) still\n * needs a real setter SOMEWHERE - real EMF's own convention (matches this session's earlier\n * containerClass work): a plain, impl-only setter that bypasses eSet/eDidAdd/eDidRemove entirely\n * (direct field assignment, no notification), reachable only by callers with the concrete impl type\n * (bootstrap code, the loader), never through the public interface or reflective eSet.\n */\nexport function needsImplOnlySetter(feature: EStructuralFeature): boolean {\n return !isReadOnlyFeature(feature) && !feature.isChangeable();\n}\n\n/** findDataTypeAnnotationProblems's counterpart for feature get/set annotations: a `set` on a many-valued feature is a no-op (see featureSetter), reported rather than silently ignored. */\nexport function findFeatureAnnotationProblems(pkg: EPackage): string[] {\n const problems: string[] = [];\n for (const classifier of pkg.getEClassifiers()) {\n if (!isEClass(classifier)) continue;\n for (const feature of classifier.getEStructuralFeatures()) {\n if (feature.isMany() && featureSetter(feature) !== undefined) {\n problems.push(\n `${classifier.getName()}.${feature.getName()}: has a \\`set\\` annotation, but is many-valued - many-valued features never have a setter, so it is ignored`\n );\n }\n }\n }\n return problems;\n}\n\n/**\n * Real, correct formula bodies for the four derived ETypedElement/\n * EReference features that are trivially computable from the same\n * instance's OTHER stored fields - deliberately NOT extended to the\n * ~14 traversal-based derived features real Ecore.ecore also has\n * (eAllSuperTypes, eAllStructuralFeatures, ...): those would need a real,\n * generically-applicable traversal algorithm, which risks exactly the\n * kind of rushed, undertested logic this project has repeatedly caught\n * bugs in when attempted under time pressure. Applied only at the bean\n * accessor level (getMany(), not the reflective eGet() switch) - a\n * narrow, deliberate, documented inconsistency between the two access\n * paths for just these four features, not a general pattern.\n */\nconst TRIVIAL_DERIVED_FORMULAS: Record<string, string> = {\n many: 'this.getUpperBound() === -1 || this.getUpperBound() > 1',\n // Verified directly against real EMF's own ETypedElementImpl.isRequired()\n // source (org.eclipse.emf.ecore.impl) while implementing the equivalent\n // reflective dispatch in @typemf/core: it is exactly `lowerBound >= 1`,\n // with NO `!many` check. An earlier version of this formula incorrectly\n // added one; caught only because the hand-written @typemf/core port\n // (built independently, then checked against the same source) disagreed\n // with this file.\n required: 'this.getLowerBound() >= 1',\n container: '(this.getEOpposite()?.isContainment() ?? false)',\n eReferenceType: '(this.getEType() as EClass | undefined)',\n eAttributeType: '(this.getEType() as EDataType | undefined)',\n};\n\n/** The real formula body for a trivially-computable derived feature, or undefined if `feature` isn't one of the four. */\nexport function trivialDerivedFormula(feature: EStructuralFeature): string | undefined {\n if (!feature.isDerived()) return undefined;\n return TRIVIAL_DERIVED_FORMULAS[feature.getName()!];\n}\n\n/**\n * The TypeScript type name for a classifier's scalar form (no EList\n * wrapping). `undefined` specifically means \"this feature's type is\n * Ecore's own EObject classifier\" - the generator never produces its own\n * api/gen/impl files for a classifier named \"EObject\" (matches the\n * existing no-declared-supertype convention, which already falls back to\n * the real @typemf/core EObject rather than generating a redundant,\n * shadowing one - see eclass.njk / main.njk). The dynamic-to-typed\n * conversion step that builds a real metamodel from a parsed .ecore file\n * deliberately leaves such a feature's eType unset for exactly this\n * reason, so `undefined` reaching here always means EObject.\n */\nexport function tsScalarType(type: EClassifier | ETypedElement | undefined): string {\n if (type !== undefined && isTypedElement(type)) return tsTypeReference(type.getEType(), type.getEGenericType());\n return tsTypeReference(type, undefined);\n}\n\n/** ETypedElement vs EClassifier - only a typed element has getEType(). */\nfunction isTypedElement(x: EClassifier | ETypedElement): x is ETypedElement {\n return 'getEType' in x;\n}\n\n/**\n * The TypeScript text for a reference to `classifier`, including type\n * arguments when the classifier is generic (declares eTypeParameters):\n * one argument per declared parameter, in order - the corresponding\n * eTypeArgument of `genericType` where it is present and bound (to a\n * classifier, or to an enclosing type parameter), and `unknown` where it\n * is missing or unbound (Ecore's `<eTypeArguments/>`). So an EJavaClass\n * used with no argument at all and one used with an explicitly empty\n * argument both read `TypeScriptClass<unknown>`, and EJavaClass<EString>\n * reads `TypeScriptClass<string>` (through the argument's own datatype\n * resolution).\n */\nfunction tsTypeReference(classifier: EClassifier | undefined, genericType: EGenericType | undefined): string {\n const base = tsBaseType(classifier);\n const parameterCount = classifier?.getETypeParameters().size() ?? 0;\n if (parameterCount === 0) return base;\n const given = genericType?.getETypeArguments();\n const args: string[] = [];\n for (let i = 0; i < parameterCount; i++) {\n const argument = given !== undefined && i < given.size() ? given.get(i) : undefined;\n args.push(argument === undefined ? 'unknown' : tsGenericArgument(argument));\n }\n return `${base}<${args.join(', ')}>`;\n}\n\nfunction tsGenericArgument(argument: EGenericType): string {\n const classifier = argument.getEClassifier();\n if (classifier) return tsTypeReference(classifier, argument);\n const parameter = argument.getETypeParameter();\n if (parameter) return parameter.getName()!;\n return 'unknown';\n}\n\n/**\n * Every classifier bound anywhere inside `genericType`'s type arguments,\n * recursively (not `genericType`'s own classifier - that is the element's\n * eType, handled separately) - needed so the templates can register the\n * imports the emitted type arguments require.\n */\nexport function genericArgumentClassifiers(genericType: EGenericType | undefined): EClassifier[] {\n const result: EClassifier[] = [];\n const visit = (gt: EGenericType) => {\n for (const argument of gt.getETypeArguments()) {\n const classifier = argument.getEClassifier();\n if (classifier) result.push(classifier);\n visit(argument);\n }\n };\n if (genericType) visit(genericType);\n return result;\n}\n\n/** The type's own name/text with no type arguments: EObject for an absent type, the layered datatype text, or the classifier's name. */\nfunction tsBaseType(classifier: EClassifier | undefined): string {\n if (!classifier) {\n // Emitting a bare \"EObject\" is a real reference to the foundational\n // type - record it, same as any other emitted type. (Missed by the\n // first cut of the import-collector rewrite: confirmed against real\n // Ecore.ecore, where EAnnotation.contents/references - typed EObject,\n // whose eType the loader deliberately leaves unset - generated an\n // \"EObject\" with no import at all.)\n importCollector.add({ name: 'EObject', location: 'types', foundational: true });\n return 'EObject';\n }\n if (isEDataType(classifier)) return tsPrimitiveType(classifier);\n // EClass or EEnum: the generated api-layer type shares the classifier's own name.\n return classifier.getName()!;\n}\n\nexport interface ResolvedDataTypeText {\n /** The TypeScript type text to emit wherever this datatype is used. */\n text: string;\n /** The import this use needs, if the datatype has import information that applies (see resolveDataTypeTs): the symbol and the module it comes from (see ImportEntry.from). Independent of where `text` came from. */\n importName?: string;\n importFrom?: string;\n}\n\n/**\n * The layered resolution of what TypeScript type text an EDataType\n * stands for, wherever it occurs (attribute/reference type, operation\n * return type, parameter type, ...), in strict priority order - and with\n * NO built-in knowledge of any datatype: every mapping comes from the\n * metamodel (or the mapping supplied alongside it), and a missing one is\n * a fix there, not something the generator papers over.\n *\n * 1. The `type` detail of the datatype's annotation with source\n * https://typemf.dev/generator - the text, as written.\n * 2. The datatype's `instanceClassName`, as written, if set.\n * 3. The datatype's name, as written.\n *\n * Separately from which layer supplied the text, the datatype's IMPORT\n * information (TypeImportMapping: the explicit mapping entry if there is\n * one, else its annotation with source https://typemf.dev/generator/import)\n * says what to import when it is used: its `type` symbol, from `from` if\n * the datatype is EXTERNAL (belongs to a package other than the one being\n * generated) or from `internal-from` (falling back to `from`) if INTERNAL.\n * If the key that applies is absent, no import is registered - the text is\n * still emitted, so a missing import shows up as a compile error naming\n * the type.\n *\n * Nothing is checked or interpreted.\n */\nexport function resolveDataTypeTs(dataType: EDataType): ResolvedDataTypeText {\n const resolved = resolveDataTypeText(dataType);\n const importInfo = generationContext.typeImports.lookup(dataType);\n if (importInfo !== undefined) {\n const source = isExternal(dataType) ? importInfo.from : (importInfo.internalFrom ?? importInfo.from);\n if (source !== undefined) return { ...resolved, importName: importInfo.type, importFrom: source };\n }\n return resolved;\n}\n\nfunction resolveDataTypeText(dataType: EDataType): ResolvedDataTypeText {\n const ownDetails = dataType.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();\n const annotated = ownDetails && detailValue(ownDetails, 'type');\n if (annotated !== undefined && annotated !== '') return { text: annotated };\n const instanceClassName = dataType.getInstanceClassName();\n if (instanceClassName !== undefined && instanceClassName !== '') return { text: instanceClassName };\n return { text: dataType.getName()! };\n}\n\n/**\n * Registers the imports a body declares - an operation's, or (see\n * FEATURE_ANNOTATION_SOURCE) a feature's custom getter/setter: one\n * annotation with source https://typemf.dev/generator/import per import\n * (`type` = the symbol; `from` / `internal-from` reuse a datatype's detail\n * names, but NOT its external/internal MEANING - see below).\n *\n * A body is always internal: it is source code that becomes part of the\n * package being generated, in every generation, never a reference to a\n * type belonging to some other package. So there is no isExternal()\n * check here (contrast resolveDataTypeTs, where a datatype genuinely can\n * belong to a different package) - `internal-from` applies, falling back\n * to `from` only as an alternate spelling of the same (internal) path,\n * not as a distinct external case. Returns '' - it is called for its\n * effect, from the template that emits the body.\n */\nexport function registerBodyImports(element: EModelElement): string {\n for (const entry of readImportAnnotations(element)) {\n const source = entry.internalFrom ?? entry.from;\n if (source !== undefined)\n importCollector.add({ name: entry.type, location: 'root', foundational: false, from: source });\n }\n return '';\n}\n\nfunction tsPrimitiveType(dataType: EDataType): string {\n const resolved = resolveDataTypeTs(dataType);\n if (resolved.importName !== undefined && resolved.importFrom !== undefined) {\n importCollector.add({\n name: resolved.importName,\n location: 'root',\n foundational: false,\n from: resolved.importFrom,\n });\n }\n return resolved.text;\n}\n\n/**\n * The EDataTypes that map to real TypeScript primitives with a genuine\n * zero-value, mirroring real Java EMF's own primitive/wrapper distinction\n * exactly: EBoolean/EInt/ELong/EFloat/EDouble/EShort/EByte correspond to\n * Java's `boolean`/`int`/`long`/`float`/`double`/`short`/`byte` (never\n * null, always has a real default) - EBooleanObject/EIntegerObject/etc.\n * are the wrapper counterparts (can be null/absent) and are NOT included\n * here. EString is deliberately excluded too: `String` has no primitive\n * counterpart in Java at all, unlike the numeric/boolean types.\n *\n * Only EBoolean/EInt/EFloat/EDouble were named explicitly in the request\n * that added this; ELong/EShort/EByte were added here for consistency\n * with the same underlying Java primitive-vs-wrapper reasoning - flagged\n * as an interpretive extension, not a literal instruction.\n */\nconst PRIMITIVE_VALUE_DATATYPE_NAMES = new Set(['EBoolean', 'EInt', 'ELong', 'EFloat', 'EDouble', 'EShort', 'EByte']);\n\nexport function isPrimitiveValueType(classifier: EClassifier | undefined): boolean {\n return (\n classifier !== undefined && isEDataType(classifier) && PRIMITIVE_VALUE_DATATYPE_NAMES.has(classifier.getName()!)\n );\n}\n\n/**\n * The feature's own declared `defaultValueLiteral` when it has one (e.g. `changeable`'s real\n * declared default is \"true\", not the generic zero-default) - otherwise 'false' for EBoolean, '0' for\n * every other primitive numeric EDataType (the real Java-primitive zero-default). Used as a stored\n * field's initial value instead of `undefined`.\n */\nexport function primitiveDefaultValue(feature: ETypedElement): string {\n const literal =\n 'getDefaultValueLiteral' in feature ? (feature as EStructuralFeature).getDefaultValueLiteral() : undefined;\n if (literal !== undefined && literal !== '') return literal;\n const classifier = feature.getEType();\n return classifier?.getName() === 'EBoolean' ? 'false' : '0';\n}\n\n/**\n * A feature's scalar TypeScript type, with \" | undefined\" appended UNLESS\n * the type is one of the real JS-primitive-with-a-zero-value EDataTypes\n * (see isPrimitiveValueType) - those never need the union, since a\n * generated field for one always has a real value (the zero-default),\n * never a genuine absence. Prefer this over manually appending\n * \" | undefined\" to tsScalarType()'s result in a template, so the\n * primitive-type exception lives in one place.\n */\nexport function tsOptionalScalarType(type: EClassifier | ETypedElement | undefined): string {\n const scalar = tsScalarType(type);\n const classifier = type !== undefined && isTypedElement(type) ? type.getEType() : type;\n if (classifier && isPrimitiveValueType(classifier)) return scalar;\n // `unknown | undefined` is just `unknown` - already includes \"unset\".\n if (scalar === 'unknown') return scalar;\n return `${scalar} | undefined`;\n}\n\n/**\n * \"getTitle\" or, for a single-valued EBoolean attribute specifically,\n * \"isPublished\" - matching the common convention (real EMF does this too,\n * gated on the same isMany()===false && type===EBoolean condition).\n * Deliberately does NOT affect many-valued features (an EList<boolean>\n * has no sensible \"isX\" reading) or the setter (which stays \"setX\"\n * regardless - only asked for the getter to change).\n */\nexport function beanGetterName(feature: EStructuralFeature): string {\n const type = feature.getEType();\n if (!feature.isMany() && type && type.getName() === 'EBoolean') {\n return `is${ucfirst(feature.getName()!)}`;\n }\n return `get${ucfirst(feature.getName()!)}`;\n}\n\n/** The full TypeScript type for a feature's getter/setter, including EList<T> for many-valued features. */\nexport function tsFeatureType(feature: ETypedElement): string {\n const scalar = tsScalarType(feature);\n if ('isMany' in feature && (feature as { isMany(): boolean }).isMany()) {\n return `EList<${scalar}>`;\n }\n return scalar;\n}\n\n/** Whether a single-valued feature's getter/setter type should be nullable (unset is a real possibility). */\nexport function isOptional(feature: EStructuralFeature): boolean {\n return !feature.isRequired();\n}\n\nexport function isEClass(classifier: EClassifier): classifier is EClass {\n return 'getEStructuralFeatures' in classifier;\n}\n\nexport function isEEnum(classifier: EClassifier): classifier is EEnum {\n return 'getELiterals' in classifier;\n}\n\nexport function isEDataType(classifier: EClassifier): classifier is EDataType {\n return !isEClass(classifier) && !isEEnum(classifier);\n}\n\nexport function isEReference(feature: EStructuralFeature): boolean {\n return 'isContainment' in feature;\n}\n\n/** \"name: Type, name2: Type2\" for an operation's parameter list. */\nexport function paramList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => `${p.getName()}: ${tsFeatureType(p)}`)\n .join(', ');\n}\n\n/** Like paramList, but every parameter is optional (\"name?: type\") - for the merged implementation signature of an auto-resolved overload set (see metaclassAccessorCollision). */\nexport function optionalParamList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => `${p.getName()}?: ${tsFeatureType(p)}`)\n .join(', ');\n}\n\n/** \"name, name2\" - just the argument names, e.g. for a super-call passthrough. */\nexport function argList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => p.getName())\n .join(', ');\n}\n\n/**\n * Groups a class's own operations by name, preserving first-seen order -\n * needed because real Ecore.ecore has genuine overloaded operations\n * (EEnum.getEEnumLiteral, by name and by value) and a TS class can only\n * have ONE method body per name, unlike an interface, which supports\n * overloads natively (so only the impl side needs this grouping, not the\n * types/ interface side - see the loop in eclass.njk). Scoped to\n * same-arity overloads only, matching what real Ecore.ecore actually\n * has - a genuine arity mismatch within one name is not handled (see\n * NOTES.md).\n */\nexport function groupOperationsByName(operations: Iterable<EOperation>): EOperation[][] {\n const groups = new Map<string, EOperation[]>();\n for (const op of operations) {\n const list = groups.get(op.getName()!);\n if (list) list.push(op);\n else groups.set(op.getName()!, [op]);\n }\n return [...groups.values()];\n}\n\n/** \"name\" if every name in `names` is identical, otherwise \"nameOrValueOrEtc\" - used to synthesize a merged parameter name for an overload group. */\nfunction mergeNames(names: string[]): string {\n const unique = [...new Set(names)];\n return (\n unique[0] +\n unique\n .slice(1)\n .map((n) => `Or${ucfirst(n)}`)\n .join('')\n );\n}\n\ninterface MergedParam {\n name: string;\n type: string;\n /** Present in only some of the overloads - so optional in the implementation signature. */\n optional: boolean;\n}\n\n/**\n * The implementation signature's parameters for a group of same-named\n * operations, one per position up to the LONGEST overload: each position's\n * type is the union of every overload's type there (among the overloads\n * that have that position), and its name is synthesized via mergeNames()\n * when they used different names (getEEnumLiteral(name)/getEEnumLiteral(value)\n * merges to \"nameOrValue\"). A position not every overload has is optional -\n * positions are prefixes, so the required ones always come first.\n */\nfunction mergedParams(group: EOperation[]): MergedParam[] {\n const arity = Math.max(...group.map((op) => op.getEParameters().size()));\n const params: MergedParam[] = [];\n for (let i = 0; i < arity; i++) {\n const having = group.filter((op) => op.getEParameters().size() > i);\n params.push({\n name: mergeNames(having.map((op) => op.getEParameters().get(i)!.getName()!)),\n type: [...new Set(having.map((op) => tsFeatureType(op.getEParameters().get(i)!)))].join(' | '),\n optional: having.length < group.length,\n });\n }\n return params;\n}\n\n/**\n * The merged implementation signature's parameter list for a group of\n * same-named operations (see mergedParams; different arities included).\n * For a group of exactly one operation, this is identical to paramList().\n */\nexport function mergedParamList(group: EOperation[]): string {\n const first = group[0]!;\n if (group.length === 1) return paramList(first);\n return mergedParams(group)\n .map((p) => `${p.name}${p.optional ? '?' : ''}: ${p.type}`)\n .join(', ');\n}\n\nexport interface OverloadBranch {\n operation: EOperation;\n /** The TypeScript condition that selects this overload. */\n condition: string;\n /** The overload's body (layered, see operationBody), or undefined -> the branch throws its own \"no body\" error. */\n body: string | undefined;\n /** `const <own name> = <merged name> as <own type>;` for each of the overload's own parameter names its body actually uses. */\n aliases: string[];\n /** e.g. \"EClass.getEStructuralFeature(featureID)\", for error messages. */\n label: string;\n}\n\nexport interface OverloadDispatch {\n /** Set when the group is NOT dispatched: the whole implementation is one throwing stub with this message. */\n stubMessage?: string;\n branches: OverloadBranch[];\n}\n\n/**\n * Runtime-testable TypeScript primitive: `typeof x === 'string'` and so\n * on. This is knowledge about TypeScript itself, not about any Ecore\n * datatype - what the parameter's resolved TS TEXT is, is still decided by\n * the model. Anything else (a generated interface, a many-valued\n * parameter, a compound type) has no runtime test.\n */\nfunction primitiveTest(name: string, tsText: string): string | undefined {\n return ['string', 'number', 'boolean', 'bigint'].includes(tsText) ? `typeof ${name} === '${tsText}'` : undefined;\n}\n\n/**\n * `source` with string literals and comments blanked out, so that finding\n * an identifier in it means USING it: 'by-name:' is not a use of `name`.\n * The expressions inside a template literal's `${...}` are code and are kept.\n */\nfunction codeOnly(source: string): string {\n let out = '';\n let i = 0;\n const n = source.length;\n while (i < n) {\n const c = source[i]!;\n const next = source[i + 1];\n if (c === '/' && next === '/') {\n while (i < n && source[i] !== '\\n') i++;\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2);\n i = end === -1 ? n : end + 2;\n } else if (c === \"'\" || c === '\"') {\n i++;\n while (i < n && source[i] !== c) i += source[i] === '\\\\' ? 2 : 1;\n i++;\n out += ' ';\n } else if (c === '`') {\n i++;\n while (i < n && source[i] !== '`') {\n if (source[i] === '\\\\') i += 2;\n else if (source[i] === '$' && source[i + 1] === '{') {\n let depth = 1;\n i += 2;\n while (i < n && depth > 0) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') depth--;\n if (depth > 0) out += source[i];\n i++;\n }\n out += ' ';\n } else i++;\n }\n i++;\n out += ' ';\n } else {\n out += c;\n i++;\n }\n }\n return out;\n}\n\nconst escapeForSingleQuotes = (text: string) => text.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n\n/**\n * How the implementation of an overload group selects the overload to\n * run. Per overload, in order:\n *\n * 1. an explicit `dispatch` detail on the overload's annotation with\n * source https://typemf.dev/generator, used as written (a condition\n * over the MERGED parameter names) - for cases the derivation cannot\n * handle;\n * 2. otherwise a condition derived from the parameters, combined with &&,\n * for each position: a position the overload does not have must be\n * `=== undefined`; where the overloads having the position differ in\n * type, the overload's own type must be a runtime-testable primitive\n * (`typeof x === 'string'`); where the type is the same everywhere but\n * the position is optional, `!== undefined`.\n *\n * The group is NOT dispatched - the implementation stays a single\n * throwing stub whose message says why - when no overload has a body,\n * when a needed test cannot be derived and no explicit condition was\n * given, or when two overloads end up with the same condition (they could\n * never be told apart, so the second would be unreachable).\n */\nexport function overloadDispatch(group: EOperation[], className: string): OverloadDispatch {\n const name = group[0]!.getName();\n const stub = (why: string): OverloadDispatch => ({\n branches: [],\n stubMessage: escapeForSingleQuotes(`${className}.${name}() is overloaded and ${why} - nothing to generate.`),\n });\n\n if (!group.some((op) => operationBody(op) !== undefined))\n return stub('none of its overloads has a `body` annotation');\n\n const merged = mergedParams(group);\n const branches: OverloadBranch[] = [];\n\n for (const op of group) {\n const params = [...op.getEParameters()];\n const label = `${className}.${name}(${params.map((p) => p.getName()).join(', ')})`;\n\n const dispatchDetails = op.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();\n let condition = dispatchDetails && detailValue(dispatchDetails, 'dispatch');\n if (condition === undefined || condition === '') {\n const parts: string[] = [];\n for (let i = 0; i < merged.length; i++) {\n const m = merged[i]!;\n const own = params[i];\n if (own === undefined) {\n parts.push(`${m.name} === undefined`);\n continue;\n }\n const havingTypes = new Set(\n group.filter((o) => o.getEParameters().size() > i).map((o) => tsFeatureType(o.getEParameters().get(i)!))\n );\n if (havingTypes.size > 1) {\n const test = 'isMany' in own && own.isMany() ? undefined : primitiveTest(m.name, tsScalarType(own));\n if (test === undefined) {\n return stub(\n `cannot be dispatched: the parameter \\`${own.getName()}\\` of ${label} has type ${tsFeatureType(own)}, ` +\n 'which has no runtime test - add a `dispatch` detail to the overload'\n );\n }\n parts.push(test);\n } else if (m.optional) {\n parts.push(`${m.name} !== undefined`);\n }\n }\n condition = parts.join(' && ');\n }\n\n const body = operationBody(op);\n const code = body === undefined ? '' : codeOnly(body);\n const aliases =\n body === undefined\n ? []\n : params.flatMap((p, i) => {\n const merged_i = merged[i]!;\n const own = p.getName()!;\n return own !== merged_i.name && new RegExp(`(?<![\\\\w$])${own.replace(/[$]/g, '\\\\$')}(?![\\\\w$])`).test(code)\n ? [`const ${own} = ${merged_i.name} as ${tsFeatureType(p)};`]\n : [];\n });\n branches.push({ operation: op, condition, body, aliases, label });\n }\n\n const seen = new Map<string, string>();\n for (const b of branches) {\n const earlier = seen.get(b.condition);\n if (earlier !== undefined || b.condition === '') {\n return stub(\n `cannot be dispatched: ${earlier ?? b.label} and ${b.label} have the same dispatch condition ` +\n `(${b.condition === '' ? 'none' : b.condition}), so they cannot be told apart at runtime - add a \\`dispatch\\` detail`\n );\n }\n seen.set(b.condition, b.label);\n }\n return { branches };\n}\n\n/**\n * An operation's return type, with \" | undefined\" appended only if its\n * OWN declared multiplicity says the result may genuinely be absent\n * (not required - lowerBound < 1) - unlike tsOptionalScalarType() (used\n * for structural features' getters), which appends it unconditionally\n * for every non-primitive type. Operations need this per-operation check\n * instead of a blanket rule: most operations (isSuperTypeOf(): boolean,\n * getClassifierID(): number, ...) are genuinely never-null by their own\n * declared multiplicity, and blanket-appending | undefined to every one\n * of them would be wrong - unlike structural features, where treating\n * every single-valued reference as \"may be unset\" is the reasonable\n * default.\n *\n * This is the fix for a real, confirmed gap: real Ecore.ecore's own\n * EModelElement.getEAnnotation(source) has no declared lowerBound (real\n * EMF's default there is 0 - not required), meaning the operation is\n * genuinely allowed to return nothing when no annotation with that\n * source is attached - but the generator previously always emitted the\n * bare, non-optional return type for every operation regardless.\n */\nexport function tsOperationReturnType(op: EOperation): string {\n const scalar = tsScalarType(op);\n if (isPrimitiveValueType(op.getEType())) return scalar;\n if (op.isRequired()) return scalar;\n if (scalar === 'unknown') return scalar; // `unknown | undefined` is just `unknown`\n return `${scalar} | undefined`;\n}\n\n/** The merged implementation signature's return type for a group - the union of every overload's OWN (possibly optional) return type via tsOperationReturnType(), deduplicated (so an all-identical group collapses to just that one type, not a redundant self-union). */\nexport function mergedReturnType(group: EOperation[]): string {\n return [...new Set(group.map((op) => tsOperationReturnType(op)))].join(' | ');\n}\n\n/**\n * Uppercases only the first character, leaving the rest untouched -\n * NOT the same as Nunjucks' built-in `capitalize` filter, which mirrors\n * Jinja2's and lowercases everything after the first letter (breaking any\n * camelCase name: \"pageCount\" -> \"Pagecount\"). Used to build bean-style\n * accessor names (\"pageCount\" -> \"getPageCount\") without corrupting them.\n */\nexport function ucfirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** The generated Package singleton class name for a package, e.g. \"library\" -> \"LibraryPackage\". */\nexport function packageClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Package`;\n}\n\nexport function factoryClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Factory`;\n}\n\nexport function switchClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Switch`;\n}\n\nexport function typeGuardsClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}TypeGuards`;\n}\n\n/** The EClass's single supertype for TS `extends` purposes, or undefined - see NOTES.md on multiple inheritance. */\nexport function superType(eClass: EClass): EClass | undefined {\n const supers = eClass.getESuperTypes();\n return supers.size() > 0 ? supers.get(0) : undefined;\n}\n\n/** eClass itself, then each ancestor in turn (via superType()), nearest first. */\nexport function superTypeChain(eClass: EClass): EClass[] {\n const chain: EClass[] = [eClass];\n let current = superType(eClass);\n while (current) {\n chain.push(current);\n current = superType(current);\n }\n return chain;\n}\n\n/**\n * Whether this class descends from (or is) \"EClassifier\" - needed\n * specifically for self-hosting Ecore.ecore: classifierID is internal\n * dispatch bookkeeping, not a real modeled Ecore feature, so it's never\n * emitted by the ordinary feature-driven getter/setter generation - but\n * bootstrap code constructing the metamodel's own classifier shells\n * (which ARE real EClassifier-derived instances, e.g. EClassImpl,\n * EDataTypeImpl) genuinely needs to set it. Confirmed as a real,\n * necessary gap by actually running self-hosted bootstrap code, not\n * assumed - see NOTES.md.\n */\nexport function isClassifierDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EClassifier');\n}\n\n/** The featureID analog of isClassifierDerived() - same reasoning, same real gap found the same way (see NOTES.md). */\nexport function isStructuralFeatureDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EStructuralFeature');\n}\n\n/** The operationID analog of isClassifierDerived()/isStructuralFeatureDerived() - added for point 4. */\nexport function isOperationDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EOperation');\n}\n\n/**\n * Whether a real EOperation's name collides with a hand-added bookkeeping\n * method (classifierID/featureID - see isClassifierDerived/\n * isStructuralFeatureDerived's own doc comments). Real Ecore.ecore\n * genuinely declares both \"EClassifier.getClassifierID(): EInt\" and\n * \"EStructuralFeature.getFeatureID(): EInt\" as real, zero-arg operations\n * - colliding, by name, with exactly the bookkeeping getters added for\n * the self-hosting bootstrap fix. Confirmed directly against the real\n * file before excluding these operations from the generic,\n * throwing-stub-generating operation loop, not assumed - see NOTES.md.\n */\nexport function isBookkeepingOperation(op: EOperation, eClass: EClass): boolean {\n if (op.getName() === 'getClassifierID' && op.getEParameters().isEmpty() && isClassifierDerived(eClass)) return true;\n if (op.getName() === 'getFeatureID' && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))\n return true;\n if (op.getName() === 'getOperationID' && op.getEParameters().isEmpty() && isOperationDerived(eClass)) return true;\n if (op.getName() === 'getContainerClass' && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))\n return true;\n return false;\n}\n\n/**\n * Whether classifier `classifierName`'s zero-arg metaclass accessor\n * (get{ClassifierName}(), generated directly on the package class for\n * every classifier the package declares) collides with a real EOperation\n * inherited by the package class from one of ITS OWN ancestors. Only\n * relevant when self-hosting - \"EPackage\" (the package class's own\n * superclass) is itself one of the metamodel's declared classifiers only\n * in that case; an ordinary metamodel never has this situation at all,\n * so this always returns undefined for one.\n *\n * General by design, not hardcoded to specific names: real Ecore.ecore\n * happens to have exactly two instances of this shape\n * (EModelElement.getEAnnotation(source), EPackage.getEClassifier(name)),\n * found by a systematic scan across every classifier's own+inherited\n * generated members, not by inspection - confirmed nothing else in the\n * real file collides this way (or any other way) - see NOTES.md. This\n * function exists so the SAME resolution automatically covers any future\n * metamodel with a classifier sharing a name with one of the package\n * class's own inherited operations, without needing another hardcoded\n * exclusion added by hand each time one is found.\n */\nexport function metaclassAccessorCollision(classifierName: string, pkg: EPackage): EOperation | undefined {\n const ePackageClassifier = [...pkg.getEClassifiers()].find((c) => c.getName() === 'EPackage' && isEClass(c));\n if (!ePackageClassifier) return undefined;\n const accessorName = 'get' + classifierName;\n for (const ancestor of superTypeChain(ePackageClassifier as EClass)) {\n for (const op of ancestor.getEOperations()) {\n if (op.getName() === accessorName) return op;\n }\n }\n return undefined;\n}\n\n/**\n * Distinct, non-primitive classifier names referenced by any metaclass-\n * accessor collision's own signature (return type or parameter types) in\n * `pkg` - needed for {Pkg}Package.ts's own import line, general rather\n * than hardcoding \"EAnnotation\" (real Ecore.ecore's one actual instance\n * today): a future metamodel's own colliding operation could return or\n * accept any classifier at all.\n */\nexport function metaclassAccessorCollisionTypeNames(pkg: EPackage): string[] {\n const names = new Set<string>();\n const maybeAdd = (type: EClassifier | undefined) => {\n if (type && (isEClass(type) || isEEnum(type))) names.add(type.getName()!);\n };\n for (const classifier of pkg.getEClassifiers()) {\n const collision = metaclassAccessorCollision(classifier.getName()!, pkg);\n if (!collision) continue;\n maybeAdd(collision.getEType());\n for (const param of collision.getEParameters()) maybeAdd(param.getEType());\n }\n return [...names];\n}\n\n/**\n * A general validation pass, meant to run during generation (not just as\n * a one-off diagnostic): for every classifier in `pkg`, checks every name\n * that would be generated as one of its members - own or inherited bean\n * accessors, real operations, bookkeeping methods (classifierID/\n * featureID), and (for the package class specifically) metaclass\n * accessors - for a collision with something else generated under the\n * same name, EXCLUDING the two patterns the generator already resolves\n * correctly on its own (isBookkeepingOperation's exclusion, and\n * metaclassAccessorCollision's automatic overload-set generation).\n * Anything left over is a genuine, unhandled collision that would\n * silently produce wrong runtime behaviour (the later declaration wins,\n * no compile error) - generation should refuse to proceed rather than\n * emit it silently.\n *\n * Deliberately reuses the same real helpers the templates themselves\n * use (isBookkeepingOperation, groupOperationsByName, beanGetterName,\n * metaclassAccessorCollision) rather than a parallel reimplementation,\n * so this can never silently drift out of sync with what actually gets\n * generated.\n */\nexport interface MemberCollision {\n classifierName: string;\n memberName: string;\n sources: string[];\n}\n\n/**\n * Every classifier, feature, operation, parameter, and enum literal in `pkg` genuinely needs a name -\n * code generation cannot produce a meaningful `class {name} {}`/`get{name}()`/etc. for one that has\n * none (real Ecore.ecore's own `name` attribute is optional, matching real EMF, so this is a real,\n * reachable state, not a hypothetical one). Checked once, up front, via the same validate() hook every\n * other model-level problem goes through - so every OTHER function in this file can safely assert a\n * name is present (`!`) rather than re-checking it at every one of the many call sites that need one,\n * confident generate() would have already refused to run otherwise.\n */\nexport function findUnnamedElements(pkg: EPackage): string[] {\n const problems: string[] = [];\n const check = (element: { getName(): string | undefined }, kind: string, where: string): void => {\n if (element.getName() === undefined) problems.push(`${where}: a ${kind} with no name`);\n };\n for (const classifier of pkg.getEClassifiers()) {\n check(classifier, 'classifier', pkg.getName() ?? '(this package)');\n if (isEClass(classifier)) {\n for (const feature of classifier.getEStructuralFeatures())\n check(feature, 'feature', classifier.getName() ?? '(unnamed classifier)');\n for (const op of classifier.getEOperations()) {\n check(op, 'operation', classifier.getName() ?? '(unnamed classifier)');\n for (const param of op.getEParameters())\n check(\n param,\n 'parameter',\n `${classifier.getName() ?? '(unnamed classifier)'}.${op.getName() ?? '(unnamed operation)'}`\n );\n }\n } else if (isEEnum(classifier)) {\n for (const literal of classifier.getELiterals())\n check(literal, 'enum literal', classifier.getName() ?? '(unnamed classifier)');\n }\n }\n return problems;\n}\n\nexport function findUnresolvedCollisions(pkg: EPackage): MemberCollision[] {\n const packageClassifierName = 'EPackage';\n const isSelfHosting = [...pkg.getEClassifiers()].some((c) => c.getName() === packageClassifierName && isEClass(c));\n const classifiers = [...pkg.getEClassifiers()].filter(isEClass);\n const results: MemberCollision[] = [];\n\n function scan(chainRoot: EClass, label: string, extra: Array<[string, string]>): void {\n const chain = superTypeChain(chainRoot);\n const byName = new Map<string, string[]>();\n const add = (name: string, source: string) => {\n if (!byName.has(name)) byName.set(name, []);\n byName.get(name)!.push(source);\n };\n\n for (const [name, source] of extra) add(name, source);\n\n for (const anc of chain) {\n const ancName = anc.getName()!;\n for (const f of anc.getEStructuralFeatures()) {\n add(beanGetterName(f), `${ancName}.${f.getName()} getter`);\n if (!f.isMany()) {\n add('set' + f.getName()![0]!.toUpperCase() + f.getName()!.slice(1), `${ancName}.${f.getName()} setter`);\n }\n }\n for (const group of groupOperationsByName(anc.getEOperations())) {\n const op = group[0]!;\n if (isBookkeepingOperation(op, anc)) continue; // already correctly excluded from generation\n add(op.getName()!, `${ancName}.${op.getName()} operation`);\n }\n if (isClassifierDerived(anc) && ancName === 'EClassifier') {\n add('getClassifierID', `${ancName} bookkeeping`);\n add('setClassifierID', `${ancName} bookkeeping`);\n }\n if (isStructuralFeatureDerived(anc) && ancName === 'EStructuralFeature') {\n add('getFeatureID', `${ancName} bookkeeping`);\n add('setFeatureID', `${ancName} bookkeeping`);\n }\n }\n\n for (const [name, sources] of byName) {\n if (sources.length > 1) {\n results.push({ classifierName: label, memberName: name, sources });\n }\n }\n }\n\n for (const c of classifiers) {\n scan(c, c.getName()!, []);\n }\n\n if (isSelfHosting) {\n // EcorePackage (the synthetic, generated package class) is never\n // itself one of pkg.getEClassifiers() - it extends the real \"EPackage\"\n // classifier, plus has its own metaclass accessors (one per\n // classifier the package declares), auto-resolved by\n // metaclassAccessorCollision where a real inherited operation exists.\n const ePackageClassifier = classifiers.find((c) => c.getName() === packageClassifierName)!;\n const ownAccessors: Array<[string, string]> = [];\n for (const classifier of pkg.getEClassifiers()) {\n if (metaclassAccessorCollision(classifier.getName()!, pkg)) continue; // already auto-resolved\n ownAccessors.push(['get' + classifier.getName(), `EcorePackage.get${classifier.getName()} metaclass accessor`]);\n }\n scan(ePackageClassifier, 'EcorePackage', ownAccessors);\n }\n\n return results;\n}\n\n/**\n * Distinct EClass/EEnum type names referenced by `features` (an EClass or\n * EEnum's own attribute/reference types) that need their own import\n * statement - EDataType primitives (string/number/boolean/Date) never do.\n * A TS helper rather than a Nunjucks loop with manual dedup, since\n * template-level array mutation is awkward without extra Nunjucks\n * extensions - matches the \"templates handle structure, TS computes\"\n * principle.\n */\nexport function referencedApiTypes(features: Iterable<EStructuralFeature>, ...excludeTypeNames: string[]): string[] {\n const exclude = new Set(excludeTypeNames);\n const names = new Set<string>();\n for (const feature of features) {\n const type = feature.getEType();\n if (type && (isEReference(feature) || isEEnum(type)) && !exclude.has(type.getName()!)) names.add(type.getName()!);\n // Classes/enums bound inside type arguments need importing too.\n for (const argument of genericArgumentClassifiers(feature.getEGenericType())) {\n if ((isEClass(argument) || isEEnum(argument)) && !exclude.has(argument.getName()!))\n names.add(argument.getName()!);\n }\n }\n return [...names];\n}\n\n/**\n * The operation-scoped analog of referencedApiTypes, for the identical\n * \"needs its own import statement\" reason - but operations weren't\n * scanned by anything at all before this existed, a genuine gap: an\n * operation's return type or any parameter's type can be any classifier,\n * including a non-primitive EDataType (real Ecore.ecore's own\n * EClassifier.getContainerClass(): EJavaClass, for one) - unlike\n * features, where only EClass/EEnum ever need an import (a plain\n * EDataType-typed feature is always one of the handful of TS-primitive-\n * mapped names). Confirmed as a real, previously-missing import by\n * actually generating real Ecore.ecore and type-checking the merged\n * output, not assumed - see NOTES.md.\n */\nexport function referencedOperationTypes(operations: Iterable<EOperation>, ...excludeTypeNames: string[]): string[] {\n const exclude = new Set(excludeTypeNames);\n const names = new Set<string>();\n const maybeAdd = (type: EClassifier | undefined) => {\n if (type && (isEClass(type) || isEEnum(type)) && !exclude.has(type.getName()!)) {\n names.add(type.getName()!);\n }\n };\n for (const op of operations) {\n maybeAdd(op.getEType());\n for (const argument of genericArgumentClassifiers(op.getEGenericType())) maybeAdd(argument);\n for (const param of op.getEParameters()) {\n maybeAdd(param.getEType());\n for (const argument of genericArgumentClassifiers(param.getEGenericType())) maybeAdd(argument);\n }\n }\n return [...names];\n}\n\n/**\n * Nunjucks 3.2.4 silently does not support Jinja2's inline `{% for x in y\n * if cond %}` for-loop filter syntax (it parses without error but produces\n * wrong output - verified empirically, not assumed) - these pre-filtered\n * helpers replace every case a template would otherwise want that syntax\n * for, consistent with keeping templates dumb.\n */\n/**\n * Safely emits a metamodel-supplied string as a TypeScript string literal,\n * via JSON.stringify() - handles quotes, apostrophes, newlines, backslashes,\n * anything. Every place a template interpolates a name/label/annotation\n * value from the metamodel into generated source needs this, not naive\n * single-quote wrapping - annotation `details` values in particular are\n * often free-form prose (GenModel documentation, validation constraint\n * text) and are genuinely likely to contain apostrophes or multi-line\n * text, which naive interpolation would turn into broken generated code.\n */\nexport function jsString(value: string | undefined): string {\n if (value === undefined) {\n throw new Error(\n 'jsString() received undefined - this means required metamodel data (a name, nsURI, nsPrefix, or ' +\n 'annotation value) is missing on the source EPackage. JSON.stringify(undefined) is not a string, so ' +\n 'this would otherwise silently emit an empty/malformed argument into generated code rather than ' +\n 'failing clearly at generation time.'\n );\n }\n return JSON.stringify(value);\n}\n\n/**\n * Nunjucks' {% for %} reliably iterates plain objects and arrays, but not\n * necessarily a real ES6 Map instance the same way (its object-iteration\n * path likely uses Object.keys(), which is empty for a Map's own\n * enumerable properties - the entries live internally, not as own\n * properties). Converting to a plain array here avoids relying on\n * behavior that was never actually verified.\n */\nexport function detailsEntries(annotation: EAnnotation): { key: string; value: string }[] {\n return [...annotation.getDetails()].map((entry) => ({ key: entry.getKey() ?? '', value: entry.getValue() ?? '' }));\n}\n\nexport function eClassesOf(pkg: EPackage): EClass[] {\n return pkg\n .getEClassifiers()\n .toArray()\n .filter((c): c is EClass => isEClass(c) && c.getName() !== 'EObject');\n}\n\nexport function concreteEClassesOf(pkg: EPackage): EClass[] {\n return eClassesOf(pkg).filter((c) => !c.isAbstract());\n}\n\n/**\n * Finds an EClass by exact name within the package, or undefined if none\n * matches - used specifically for the EFactory/{Pkg}Factory unification\n * special case (see efactory.njk): when a metamodel models a classifier\n * literally named \"EFactory\" (as real Ecore.ecore does), the package-level\n * generated Factory extends ITS generated impl instead of the generic\n * @typemf/core EFactoryImpl base, matching real EMF's own\n * EcoreFactoryImpl-extends-EFactoryImpl design. Ordinary metamodels (no\n * \"EFactory\" classifier) are unaffected.\n */\nexport function findEClassByName(pkg: EPackage, name: string): EClass | undefined {\n return eClassesOf(pkg).find((c) => c.getName() === name);\n}\n\nexport function singleValuedFeatures(features: Iterable<EStructuralFeature>): EStructuralFeature[] {\n return [...features].filter((f) => !f.isMany());\n}\n","import { TemplateSet } from './template-set.js';\nimport { typescriptTemplateSet } from './typescript-template-set.js';\n\nconst builtinTemplateSets: Record<string, TemplateSet> = {\n typescript: typescriptTemplateSet,\n};\n\n/**\n * Resolves a config file's \"templateSet\" name string to a real\n * TemplateSet. Only built-in sets are known here for now - a third-party\n * set (e.g. a Java one) would need its own registration mechanism, not yet\n * built; see NOTES.md.\n */\nexport function resolveTemplateSet(name: string): TemplateSet {\n const set = builtinTemplateSets[name];\n if (!set) {\n const known = Object.keys(builtinTemplateSets).join(', ');\n throw new Error(`Unknown template set '${name}'. Known built-in sets: ${known}.`);\n }\n return set;\n}\n"],"mappings":"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","names":["EcorePackageImpl","EAttributeImpl","EClassImpl","EDataTypeImpl","EPackageImpl","EReferenceImpl","EDataTypeImpl","EClassImpl","EAttributeImpl","EReferenceImpl","EPackageImpl","EcorePackageImpl","dirname","join","detailValue","isEClass","byName","isEClass","join","dirname"]}
1
+ {"version":3,"sources":["../src/cli-config.ts","../src/ecore-loader.ts","../src/ecore-dynamic-to-typed.ts","../src/ecore-meta-schema.ts","../src/id-assignment.ts","../src/generate.ts","../src/file-extension.ts","../src/run-generation.ts","../src/typescript-template-set.ts","../src/type-import-mapping.ts","../src/generation-context.ts","../src/import-collector.ts","../src/typescript-filters.ts","../src/template-set-registry.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\n/**\n * One config, one template set, one .ecore file, one outputDir - per the\n * design discussion. Multi-language generation is achieved by running the\n * CLI multiple times with different config files (e.g.\n * typescript.typemf-generator.json, java.typemf-generator.json), not by\n * one config handling multiple sets.\n */\nexport interface GeneratorConfig {\n ecoreFile: string;\n outputDir: string;\n templateSet: string;\n options: Record<string, unknown>;\n}\n\nexport async function loadConfig(configPath: string): Promise<GeneratorConfig> {\n let raw: string;\n try {\n raw = await readFile(configPath, 'utf-8');\n } catch (err) {\n throw new Error(`Could not read config file '${configPath}': ${(err as Error).message}`, { cause: err });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(`Failed to parse '${configPath}' as JSON: ${(err as Error).message}`, { cause: err });\n }\n\n return validateConfig(parsed, configPath);\n}\n\nfunction validateConfig(value: unknown, configPath: string): GeneratorConfig {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`'${configPath}' must contain a JSON object.`);\n }\n const obj = value as Record<string, unknown>;\n\n for (const key of ['ecoreFile', 'outputDir', 'templateSet']) {\n if (typeof obj[key] !== 'string' || obj[key] === '') {\n throw new Error(`'${configPath}': \"${key}\" is required and must be a non-empty string.`);\n }\n }\n\n if (\n obj.options !== undefined &&\n (typeof obj.options !== 'object' || obj.options === null || Array.isArray(obj.options))\n ) {\n throw new Error(`'${configPath}': \"options\", if present, must be a JSON object.`);\n }\n\n return {\n ecoreFile: obj.ecoreFile as string,\n outputDir: obj.outputDir as string,\n templateSet: obj.templateSet as string,\n options: (obj.options as Record<string, unknown> | undefined) ?? {},\n };\n}\n","import { EcorePackageImpl, EPackage, ResourceSetImpl, URI } from '@typemf/core';\nimport { NodeFileUriConverter } from '@typemf/node';\nimport { registerXmiFormat } from '@typemf/xmi';\nimport { convertDynamicEcoreToTyped } from './ecore-dynamic-to-typed.js';\nimport { buildEcoreMetaSchema } from './ecore-meta-schema.js';\n\n/**\n * Loads a real .ecore file into a typed EPackage. A .ecore file is an\n * ordinary XMI instance document whose root happens to be an EPackage -\n * read here by @typemf/xmi's own generic XmiSerializer, with no separate\n * parsing logic of its own. Interpreting it correctly needs a registered\n * meta-schema describing what \"EClass\"/\"EAttribute\"/etc mean (see\n * ecore-meta-schema.ts) - this produces a DYNAMIC EObject graph, which\n * gets converted (see ecore-dynamic-to-typed.ts) into the real, typed\n * EPackage generate() actually needs as input. See NOTES.md for the full\n * bootstrapping story and why this two-step shape is necessary - NOT\n * because hand-written classes lack eSet() support (they support it fully\n * for every real, modeled feature now, confirmed directly), but because\n * bookkeeping fields (classifierID, featureID, containerClass,\n * operationID) are deliberately excluded from eSet() by design, matching\n * real EMF, and generate()'s own internals need those set too (via plain\n * methods and id-assignment.ts, not eSet) - so a pure eSet-driven read\n * could never be sufficient on its own regardless.\n */\nexport async function loadEcorePackage(ecoreFilePath: string): Promise<EPackage> {\n // Post-swap, every @typemf/core setter (setName() included) routes through getEcorePackageRef(),\n // which needs Ecore's own metaclass system bootstrapped first - this triggers that safely, once,\n // right here (the single earliest entry point), before buildEcoreMetaSchema() OR\n // convertDynamicEcoreToTyped() construct a single typed metaclass instance. See NOTES.md's point\n // 6/7 write-ups.\n void EcorePackageImpl.eINSTANCE;\n const resourceSet = new ResourceSetImpl();\n resourceSet.getUriConverterRegistry().register(new NodeFileUriConverter());\n registerXmiFormat(resourceSet.getResourceFactoryRegistry());\n\n const metaSchema = buildEcoreMetaSchema();\n resourceSet.getPackageRegistry().register(metaSchema.pkg);\n\n const uri = URI.createFileURI(ecoreFilePath);\n const resource = await resourceSet.getResource(uri, true);\n if (!resource) {\n throw new Error(`Could not load '${ecoreFilePath}'.`);\n }\n\n const roots = resource.getContents().toArray();\n const dynamicPkg = roots[0];\n if (!dynamicPkg) {\n throw new Error(`'${ecoreFilePath}' has no root element - expected a single EPackage.`);\n }\n\n return convertDynamicEcoreToTyped(dynamicPkg);\n}\n","import {\n EAnnotationImpl,\n EAttributeImpl,\n EClass,\n setDetailValue,\n EClassifier,\n EClassImpl,\n EcorePackageImpl,\n EDataTypeImpl,\n EEnumImpl,\n EEnumLiteralImpl,\n EGenericTypeImpl,\n EModelElement,\n EObject,\n EOperationImpl,\n EPackage,\n EPackageImpl,\n ETypeParameterImpl,\n EParameterImpl,\n EReferenceImpl,\n EStructuralFeature,\n getProxyURI,\n isEClassifier,\n resolveAgainstPackage,\n type EGenericType,\n type ETypedElement,\n type ETypeParameter,\n} from '@typemf/core';\n\n/**\n * Converts a dynamic EObject graph - produced by parsing a real .ecore\n * file against the meta-schema (see ecore-meta-schema.ts) - into a real,\n * typed EPackage built from @typemf/core's own hand-written classes. This\n * is the piece generate() actually needs as input; a dynamic graph, even\n * though it fully supports eGet/eSet reflectively, doesn't have the plain\n * convenience methods (setClassifierID(), recomputeAllLists(), ...)\n * generate()'s own internals call directly - only the real typed classes\n * do. This conversion writes via the real classes' own plain methods\n * throughout, not because eSet() itself is unsupported there (it is, for\n * every real, modeled feature - confirmed directly, this comment used to\n * claim otherwise), but because bookkeeping (classifierID, featureID,\n * containerClass, operationID) is deliberately unreachable via eSet by\n * design, matching real EMF, and this conversion needs to set exactly\n * that bookkeeping too - so writing everything through the SAME plain\n * methods uniformly is simpler than splitting eSet-for-real-features from\n * plain-calls-for-bookkeeping. It reads reflectively throughout (eGet, by\n * name, off whatever meta-schema classifier each dynamic object happens\n * to be an instance of).\n *\n * A classifier named \"EObject\" in the source graph (present only so\n * \"#//EObject\" fragments resolve during parsing - see\n * ecore-meta-schema.ts) is deliberately NOT converted into a real\n * classifier here: any reference to it becomes `undefined` on the real\n * side, matching the generator's own existing convention for a classifier\n * with no explicit type (which already means \"real @typemf/core EObject\").\n */\nexport function convertDynamicEcoreToTyped(dynamicPkg: EObject): EPackage {\n const realPkg = new EPackageImpl();\n realPkg.setName(byName<string>(dynamicPkg, 'name') ?? '');\n realPkg.setNsURI(byName<string>(dynamicPkg, 'nsURI') ?? '');\n realPkg.setNsPrefix(byName<string>(dynamicPkg, 'nsPrefix') ?? '');\n copyAnnotations(dynamicPkg, realPkg);\n\n const dynamicClassifiers = listByName(dynamicPkg, 'eClassifiers');\n\n // dynamic classifier instance -> real classifier (EObject-named ones map\n // to undefined - see doc comment).\n const classifierMap = new Map<EObject, EClassifier | undefined>();\n // dynamic feature instance -> real feature (for eOpposite wiring, a\n // second pass after every feature on every class already exists).\n const featureMap = new Map<EObject, EStructuralFeature>();\n // dynamic type-parameter instance -> real ETypeParameter (so an\n // EGenericType that refers to one can be wired up).\n const typeParameterMap = new Map<EObject, ETypeParameter>();\n\n // Pass 1: every classifier as a real, empty shell - keyed by what KIND\n // of thing the dynamic instance itself reflectively is (an instance of\n // the meta-schema's own \"EClass\"/\"EDataType\"/\"EEnum\" classifier).\n for (const dyn of dynamicClassifiers) {\n const kind = dyn.eClass().getName();\n const name = byName<string>(dyn, 'name') ?? '';\n if (name === 'EObject') {\n classifierMap.set(dyn, undefined);\n continue;\n }\n if (kind === 'EClass') {\n const c = new EClassImpl();\n c.setName(name);\n copyAnnotations(dyn, c);\n classifierMap.set(dyn, c);\n } else if (kind === 'EEnum') {\n const e = new EEnumImpl();\n e.setName(name);\n copyAnnotations(dyn, e);\n classifierMap.set(dyn, e);\n } else {\n // EDataType (or an unrecognized classifier kind - treated\n // defensively as a plain named datatype).\n const d = new EDataTypeImpl();\n d.setName(name);\n copyAnnotations(dyn, d);\n classifierMap.set(dyn, d);\n }\n }\n\n /**\n * The real classifier a dynamic classifier reference denotes: one of this package's own, or, for a\n * proxy into Ecore (e.g. `http://www.eclipse.org/emf/2002/Ecore#//EString`), Ecore's own. Ecore's\n * EObject maps to undefined, like a local one.\n */\n function classifierOf(dynClassifier: EObject): EClassifier | undefined {\n if (classifierMap.has(dynClassifier)) return classifierMap.get(dynClassifier);\n const uri = dynClassifier.eIsProxy() ? getProxyURI(dynClassifier) : undefined;\n const ecore = EcorePackageImpl.eINSTANCE;\n if (uri && uri.trimFragment().toString() === ecore.getNsURI()) {\n const fragment = uri.getFragment() ?? '';\n if (fragment === '//EObject') return undefined;\n const resolved = resolveAgainstPackage(ecore, fragment);\n if (isEClassifier(resolved)) return resolved;\n }\n throw new Error(\n `Cannot resolve the classifier reference '${uri?.toString() ?? dynClassifier.fullId()}': only classifiers of this package and of Ecore are supported.`\n );\n }\n\n /** Resolves a dynamic classifier reference, or reads eGenericType.eClassifier as a fallback when eType itself is unset. */\n function resolveType(dynFeature: EObject): EClassifier | undefined {\n const dynType = byNameRaw(dynFeature, 'eType') as EObject | undefined;\n if (dynType) return classifierOf(dynType);\n const dynGeneric = byNameRaw(dynFeature, 'eGenericType') as EObject | undefined;\n if (dynGeneric) {\n const dynClassifier = byNameRaw(dynGeneric, 'eClassifier') as EObject | undefined;\n if (dynClassifier) return classifierOf(dynClassifier);\n }\n return undefined;\n }\n\n /**\n * A real EGenericType mirroring a dynamic one, recursively: its\n * classifier and type parameter (each only if set AND resolvable - an\n * EObject-bound reference resolves to undefined here, the same\n * documented loss as anywhere else EObject is dropped, so it reads as\n * \"unbound\"), and every type argument in order (an argument with\n * neither is Ecore's `<eTypeArguments/>`: unbound).\n */\n function convertGenericType(dynGeneric: EObject): EGenericType {\n const gt = new EGenericTypeImpl();\n const dynClassifier = byNameRaw(dynGeneric, 'eClassifier') as EObject | undefined;\n if (dynClassifier) gt.setEClassifier(classifierOf(dynClassifier));\n const dynParameter = byNameRaw(dynGeneric, 'eTypeParameter') as EObject | undefined;\n if (dynParameter) gt.setETypeParameter(typeParameterMap.get(dynParameter));\n for (const dynArgument of listByName(dynGeneric, 'eTypeArguments')) {\n gt.getETypeArguments().add(convertGenericType(dynArgument));\n }\n return gt;\n }\n\n /** Sets a real typed element's type from its dynamic counterpart: the full generic type when it has one (which also sets eType), else the plain eType. */\n function applyType(dynTyped: EObject, real: ETypedElement): void {\n const dynGeneric = byNameRaw(dynTyped, 'eGenericType') as EObject | undefined;\n if (dynGeneric) {\n real.setEGenericType(convertGenericType(dynGeneric));\n return;\n }\n const type = resolveType(dynTyped);\n if (type) real.setEType(type);\n }\n\n // Pass 2: classifier-level scalar properties + EClass.eSuperTypes (every\n // classifier now exists, so cross-references resolve).\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real) continue;\n const kind = dyn.eClass().getName();\n\n for (const dynParameter of listByName(dyn, 'eTypeParameters')) {\n const parameter = new ETypeParameterImpl();\n parameter.setName(byName<string>(dynParameter, 'name') ?? '');\n real.getETypeParameters().add(parameter);\n typeParameterMap.set(dynParameter, parameter);\n }\n\n // instanceClassName (on every EClassifier in real Ecore.ecore, not just\n // EDataType) - consumed by the typescript template set's layered\n // EDataType-to-TypeScript-type resolution (see typescript-filters.ts).\n const instanceClassName = byName<string>(dyn, 'instanceClassName');\n if (instanceClassName !== undefined && instanceClassName !== '') real.setInstanceClassName(instanceClassName);\n\n if (kind === 'EClass') {\n const c = real as EClass;\n if (byName<boolean>(dyn, 'abstract')) c.setAbstract(true);\n if (byName<boolean>(dyn, 'interface')) c.setInterface(true);\n for (const dynSuper of listByName(dyn, 'eSuperTypes')) {\n const realSuper = classifierOf(dynSuper);\n if (realSuper) c.getESuperTypes().add(realSuper as EClass);\n }\n }\n }\n\n // Pass 3: structural features + operations, for every EClass.\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real || dyn.eClass().getName() !== 'EClass') continue;\n const realClass = real as EClass;\n\n for (const dynFeature of listByName(dyn, 'eStructuralFeatures')) {\n const featureKind = dynFeature.eClass().getName();\n const name = byName<string>(dynFeature, 'name') ?? '';\n const lowerBound = byName<number>(dynFeature, 'lowerBound');\n const upperBound = byName<number>(dynFeature, 'upperBound');\n\n if (featureKind === 'EReference') {\n const r = new EReferenceImpl();\n r.setName(name);\n applyType(dynFeature, r);\n if (typeof lowerBound === 'number') r.setLowerBound(lowerBound);\n if (typeof upperBound === 'number') r.setUpperBound(upperBound);\n if (byName<boolean>(dynFeature, 'containment')) r.setContainment(true);\n if (byName<boolean>(dynFeature, 'resolveProxies') === false) r.setResolveProxies(false);\n r.setEContainingClass(realClass);\n copyFeatureFlags(dynFeature, r);\n copyAnnotations(dynFeature, r);\n realClass.getEStructuralFeatures().add(r);\n featureMap.set(dynFeature, r);\n } else {\n // EAttribute\n const a = new EAttributeImpl();\n a.setName(name);\n applyType(dynFeature, a);\n if (typeof lowerBound === 'number') a.setLowerBound(lowerBound);\n if (typeof upperBound === 'number') a.setUpperBound(upperBound);\n if (byName<boolean>(dynFeature, 'iD')) a.setID(true);\n copyFeatureFlags(dynFeature, a); // now copies defaultValueLiteral too - see copyFeatureFlags\n a.setEContainingClass(realClass);\n copyAnnotations(dynFeature, a);\n realClass.getEStructuralFeatures().add(a);\n featureMap.set(dynFeature, a);\n }\n }\n\n for (const dynOp of listByName(dyn, 'eOperations')) {\n const op = new EOperationImpl();\n op.setName(byName<string>(dynOp, 'name') ?? '');\n applyType(dynOp, op);\n copyAnnotations(dynOp, op);\n const opLowerBound = byName<number>(dynOp, 'lowerBound');\n const opUpperBound = byName<number>(dynOp, 'upperBound');\n if (typeof opLowerBound === 'number') op.setLowerBound(opLowerBound);\n if (typeof opUpperBound === 'number') op.setUpperBound(opUpperBound);\n for (const dynParam of listByName(dynOp, 'eParameters')) {\n const param = new EParameterImpl();\n param.setName(byName<string>(dynParam, 'name') ?? '');\n applyType(dynParam, param);\n const paramLowerBound = byName<number>(dynParam, 'lowerBound');\n const paramUpperBound = byName<number>(dynParam, 'upperBound');\n if (typeof paramLowerBound === 'number') param.setLowerBound(paramLowerBound);\n if (typeof paramUpperBound === 'number') param.setUpperBound(paramUpperBound);\n op.getEParameters().add(param);\n }\n realClass.getEOperations().add(op);\n }\n }\n\n // Pass 4: EEnum.eLiterals (deferred until here purely for readability;\n // no cross-classifier dependency involved).\n for (const dyn of dynamicClassifiers) {\n const real = classifierMap.get(dyn);\n if (!real || dyn.eClass().getName() !== 'EEnum') continue;\n for (const dynLiteral of listByName(dyn, 'eLiterals')) {\n const lit = new EEnumLiteralImpl();\n lit.setName(byName<string>(dynLiteral, 'name') ?? '');\n lit.setValue(byName<number>(dynLiteral, 'value') ?? 0);\n lit.setLiteral(byName<string>(dynLiteral, 'literal') ?? byName<string>(dynLiteral, 'name') ?? '');\n copyAnnotations(dynLiteral, lit);\n // addLiteral() no longer exists - @typemf/core's own EEnumLiteralImpl is itself now generated\n // code, properly extending EObjectImpl, so the ordinary getELiterals().add() path correctly\n // wires the eEnum opposite automatically (see NOTES.md's point 6/7 write-ups, and the matching\n // fix in epackage.njk).\n (real as EEnumImpl).getELiterals().add(lit);\n }\n }\n\n // Pass 5: eOpposite (every feature on every class now exists).\n for (const [dynFeature, realFeature] of featureMap) {\n const dynOpposite = byNameRaw(dynFeature, 'eOpposite') as EObject | undefined;\n if (!dynOpposite) continue;\n const realOpposite = featureMap.get(dynOpposite);\n if (realOpposite && 'setEOpposite' in realFeature) {\n (realFeature as EReferenceImpl).setEOpposite(realOpposite as EReferenceImpl);\n }\n }\n\n // Pass 6 (recompute EAll* caches for every real EClass) removed - recomputeAllLists() no longer\n // exists at all post-swap; generated get-bodied features cache automatically (see\n // EObjectImpl.getModelGeneration()), needing no manual recompute step.\n\n // Assemble.\n for (const real of classifierMap.values()) {\n if (real) realPkg.getEClassifiers().add(real);\n }\n\n return realPkg;\n}\n\n/**\n * Copies every EAnnotation (source + details) from a dynamic element onto\n * the corresponding real, typed one - package, classifier, feature,\n * operation and enum literal (not parameters). Operations matter because\n * that is where the generator reads an operation's `body` from (see\n * operationBody); they were left out here originally on the reasoning\n * that a converted operation has no runtime representation to attach to,\n * which is true of the GENERATED package's bootstrap (it builds no\n * operations, so emits no operation annotations) but not of this input\n * model, where a body written in a real .ecore file could otherwise\n * never reach the generator.\n */\nfunction copyAnnotations(dyn: EObject, real: EModelElement): void {\n for (const dynAnnotation of listByName(dyn, 'eAnnotations')) {\n const annotation = new EAnnotationImpl();\n const source = byName<string>(dynAnnotation, 'source');\n if (source !== undefined) annotation.setSource(source);\n for (const dynDetail of listByName(dynAnnotation, 'details')) {\n const key = byName<string>(dynDetail, 'key');\n const value = byName<string>(dynDetail, 'value');\n if (key !== undefined && value !== undefined) {\n setDetailValue(annotation.getDetails(), key, value);\n }\n }\n real.getEAnnotations().add(annotation);\n }\n}\n\n/**\n * Copies changeable/volatile/transient/derived/unsettable from a dynamic\n * feature onto the real one. A real, previously-missed gap: without this,\n * EVERY feature converted from a real .ecore file loses these flags\n * entirely (defaulting to changeable=true, everything else false) -\n * regardless of what the source file actually declares. Concretely, this\n * silently broke the generator's derived-feature formula treatment\n * (TRIVIAL_DERIVED_FORMULAS checks feature.isDerived() first) for every\n * real file this pipeline has ever converted, including real Ecore.ecore\n * itself - \"required\"/\"many\"/etc were generating as ordinary stored\n * fields, not the intended formulas, until this was added.\n */\nfunction copyFeatureFlags(dyn: EObject, real: EStructuralFeature): void {\n const changeable = byName<boolean>(dyn, 'changeable');\n if (changeable === false) real.setChangeable(false);\n if (byName<boolean>(dyn, 'volatile')) real.setVolatile(true);\n if (byName<boolean>(dyn, 'transient')) real.setTransient(true);\n if (byName<boolean>(dyn, 'derived')) real.setDerived(true);\n if (byName<boolean>(dyn, 'unsettable')) real.setUnsettable(true);\n const defaultValueLiteral = byName<string>(dyn, 'defaultValueLiteral');\n if (defaultValueLiteral !== undefined) real.setDefaultValueLiteral(defaultValueLiteral);\n}\n\n/** Reads a named feature's value reflectively, off whatever classifier `obj` happens to be an instance of. */\nfunction byNameRaw(obj: EObject, featureName: string): unknown {\n const feature = obj.eClass().getEStructuralFeature(featureName);\n if (!feature) return undefined;\n return obj.eGet(feature);\n}\n\nfunction byName<T>(obj: EObject, featureName: string): T | undefined {\n return byNameRaw(obj, featureName) as T | undefined;\n}\n\nfunction listByName(obj: EObject, featureName: string): EObject[] {\n const value = byNameRaw(obj, featureName);\n if (!value) return [];\n return [...(value as Iterable<EObject>)];\n}\n","import {\n DynamicEFactoryImpl,\n EAttributeImpl,\n EClassImpl,\n EDataTypeImpl,\n EPackageImpl,\n EReferenceImpl,\n type EClass,\n} from '@typemf/core';\nimport { assignFreshIds } from './id-assignment.js';\n\n/**\n * A hand-authored graph mirroring real Ecore.ecore's own full structure -\n * every EClass, every EDataType, every declared feature (including\n * derived/transient ones - these ARE present in the real file as ordinary\n * <eStructuralFeatures> descriptions of what features a class HAS; what's\n * never serialized is a VALUE for a derived feature on some downstream\n * instance, which never comes up while parsing Ecore.ecore itself, since\n * this file describes structure, not instances-of-that-structure).\n *\n * Two distinct roles, same shape:\n * 1. Registered as the meta-schema the generic XmiSerializer needs to\n * interpret the real Ecore.ecore file at all (a .ecore file is an\n * ordinary XMI instance document whose root is an EPackage - reading\n * it needs SOME registered EPackage describing what \"EClass\"/\n * \"EAttribute\"/etc mean, or there's nothing to dispatch xsi:type\n * against).\n * 2. The target shape the dynamic-graph -> typed-EPackage conversion step\n * produces after parsing - what actually gets fed to generate().\n *\n * EObject gets a real classifier shell here (needed so \"#//EObject\"\n * fragments - e.g. EAnnotation.contents: EObject[] - resolve during\n * parsing) but is deliberately excluded from what the GENERATOR treats as\n * a real classifier to produce files for: it's the one name the generator\n * special-cases exactly the way it already handles \"no declared supertype\"\n * (see eclass.njk) - any reference to a classifier named \"EObject\"\n * resolves to @typemf/core's own real EObject instead of generating a\n * redundant, shadowing one.\n *\n * Does NOT model EString/EInt/EBoolean/etc as anything other than bare\n * EDataType shells - no instanceClassName is set here beyond a name;\n * `serializable`/`defaultValueLiteral` on real Ecore.ecore's own\n * EDataType declarations are read during conversion where present, not\n * hardcoded into this meta-schema (the meta-schema only needs to recognize\n * these as valid attributes to parse, not carry their real values itself).\n */\nexport function buildEcoreMetaSchema() {\n // --- Primitive EDataTypes (bare shells; real Ecore.ecore's own\n // instanceClassName/serializable/etc values are read from the file\n // itself during conversion, not hardcoded here).\n const primitiveNames = [\n 'EBigDecimal',\n 'EBigInteger',\n 'EBoolean',\n 'EBooleanObject',\n 'EByte',\n 'EByteArray',\n 'EByteObject',\n 'EChar',\n 'ECharacterObject',\n 'EDate',\n 'EDiagnosticChain',\n 'EDouble',\n 'EDoubleObject',\n 'EEList',\n 'EEnumerator',\n 'EFeatureMap',\n 'EFeatureMapEntry',\n 'EFloat',\n 'EFloatObject',\n 'EInt',\n 'EIntegerObject',\n 'EJavaClass',\n 'EJavaObject',\n 'ELong',\n 'ELongObject',\n 'EMap',\n 'EResource',\n 'EResourceSet',\n 'EShort',\n 'EShortObject',\n 'EString',\n 'ETreeIterator',\n 'EInvocationTargetException',\n ];\n const primitives = new Map(\n primitiveNames.map((n) => [\n n,\n (() => {\n const d = new EDataTypeImpl();\n d.setName(n);\n return d;\n })(),\n ])\n );\n const p = (name: string) => primitives.get(name)!;\n\n // --- Pass 1: every EClass as an empty shell.\n const eObject = new EClassImpl();\n eObject.setName('EObject');\n const eModelElement = new EClassImpl();\n eModelElement.setName('EModelElement');\n eModelElement.setAbstract(true);\n const eAnnotation = new EClassImpl();\n eAnnotation.setName('EAnnotation');\n const eNamedElement = new EClassImpl();\n eNamedElement.setName('ENamedElement');\n eNamedElement.setAbstract(true);\n const eTypedElement = new EClassImpl();\n eTypedElement.setName('ETypedElement');\n eTypedElement.setAbstract(true);\n const eClassifier = new EClassImpl();\n eClassifier.setName('EClassifier');\n eClassifier.setAbstract(true);\n const eStructuralFeature = new EClassImpl();\n eStructuralFeature.setName('EStructuralFeature');\n eStructuralFeature.setAbstract(true);\n const eAttribute = new EClassImpl();\n eAttribute.setName('EAttribute');\n const eReference = new EClassImpl();\n eReference.setName('EReference');\n const eClass = new EClassImpl();\n eClass.setName('EClass');\n const ePackage = new EClassImpl();\n ePackage.setName('EPackage');\n const eDataType = new EClassImpl();\n eDataType.setName('EDataType');\n const eEnum = new EClassImpl();\n eEnum.setName('EEnum');\n const eEnumLiteral = new EClassImpl();\n eEnumLiteral.setName('EEnumLiteral');\n const eFactory = new EClassImpl();\n eFactory.setName('EFactory');\n const eOperation = new EClassImpl();\n eOperation.setName('EOperation');\n const eParameter = new EClassImpl();\n eParameter.setName('EParameter');\n const eStringToStringMapEntry = new EClassImpl();\n eStringToStringMapEntry.setName('EStringToStringMapEntry');\n const eGenericType = new EClassImpl();\n eGenericType.setName('EGenericType');\n const eTypeParameter = new EClassImpl();\n eTypeParameter.setName('ETypeParameter');\n\n // --- Pass 2: supertypes.\n eAnnotation.getESuperTypes().add(eModelElement);\n eNamedElement.getESuperTypes().add(eModelElement);\n eTypedElement.getESuperTypes().add(eNamedElement);\n eClassifier.getESuperTypes().add(eNamedElement);\n eStructuralFeature.getESuperTypes().add(eTypedElement);\n eAttribute.getESuperTypes().add(eStructuralFeature);\n eReference.getESuperTypes().add(eStructuralFeature);\n eClass.getESuperTypes().add(eClassifier);\n ePackage.getESuperTypes().add(eNamedElement);\n eDataType.getESuperTypes().add(eClassifier);\n eEnum.getESuperTypes().add(eDataType);\n eEnumLiteral.getESuperTypes().add(eNamedElement);\n eFactory.getESuperTypes().add(eModelElement);\n eOperation.getESuperTypes().add(eTypedElement);\n eParameter.getESuperTypes().add(eTypedElement);\n eTypeParameter.getESuperTypes().add(eNamedElement);\n\n const allClasses: EClass[] = [\n eObject,\n eModelElement,\n eAnnotation,\n eNamedElement,\n eTypedElement,\n eClassifier,\n eStructuralFeature,\n eAttribute,\n eReference,\n eClass,\n ePackage,\n eDataType,\n eEnum,\n eEnumLiteral,\n eFactory,\n eOperation,\n eParameter,\n eStringToStringMapEntry,\n eGenericType,\n eTypeParameter,\n ];\n\n // --- Small helpers to keep pass 3 readable - mirror real Ecore.ecore's\n // own feature declarations line-for-line, not a generalized DSL.\n function attr(\n owner: EClass,\n name: string,\n type: EClass | ReturnType<typeof p>,\n opts: { many?: boolean; changeable?: boolean; volatile?: boolean; transient?: boolean; derived?: boolean } = {}\n ) {\n const a = new EAttributeImpl();\n a.setName(name);\n a.setEType(type);\n if (opts.many) a.setUpperBound(-1);\n if (opts.changeable === false) a.setChangeable(false);\n if (opts.volatile) a.setVolatile(true);\n if (opts.transient) a.setTransient(true);\n if (opts.derived) a.setDerived(true);\n a.setEContainingClass(owner);\n owner.getEStructuralFeatures().add(a);\n return a;\n }\n function ref(\n owner: EClass,\n name: string,\n type: EClass,\n opts: {\n many?: boolean;\n containment?: boolean;\n changeable?: boolean;\n volatile?: boolean;\n transient?: boolean;\n derived?: boolean;\n } = {}\n ) {\n const r = new EReferenceImpl();\n r.setName(name);\n r.setEType(type);\n if (opts.many) r.setUpperBound(-1);\n if (opts.containment) r.setContainment(true);\n if (opts.changeable === false) r.setChangeable(false);\n if (opts.volatile) r.setVolatile(true);\n if (opts.transient) r.setTransient(true);\n if (opts.derived) r.setDerived(true);\n r.setEContainingClass(owner);\n owner.getEStructuralFeatures().add(r);\n return r;\n }\n\n // --- Pass 3: features, per class, matching real Ecore.ecore's own\n // declaration order.\n\n // EModelElement\n const eAnnotations = ref(eModelElement, 'eAnnotations', eAnnotation, { many: true, containment: true });\n\n // EAnnotation\n attr(eAnnotation, 'source', p('EString'));\n ref(eAnnotation, 'details', eStringToStringMapEntry, { many: true, containment: true });\n const annotation_eModelElement = ref(eAnnotation, 'eModelElement', eModelElement, { transient: true });\n ref(eAnnotation, 'contents', eObject, { many: true, containment: true });\n ref(eAnnotation, 'references', eObject, { many: true });\n\n // ENamedElement\n attr(eNamedElement, 'name', p('EString'));\n\n // ETypedElement\n attr(eTypedElement, 'ordered', p('EBoolean'));\n attr(eTypedElement, 'unique', p('EBoolean'));\n attr(eTypedElement, 'lowerBound', p('EInt'));\n attr(eTypedElement, 'upperBound', p('EInt'));\n attr(eTypedElement, 'many', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n attr(eTypedElement, 'required', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n const eType = ref(eTypedElement, 'eType', eClassifier, { volatile: true });\n ref(eTypedElement, 'eGenericType', eGenericType, { containment: true, volatile: true });\n\n // EClassifier\n const classifier_ePackage = ref(eClassifier, 'ePackage', ePackage, { changeable: false, transient: true });\n ref(eClassifier, 'eTypeParameters', eTypeParameter, { many: true, containment: true });\n attr(eClassifier, 'instanceClassName', p('EString'), { volatile: true });\n attr(eClassifier, 'instanceClass', p('EJavaClass'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eClassifier, 'defaultValue', p('EJavaObject'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eClassifier, 'instanceTypeName', p('EString'), { volatile: true });\n\n // EStructuralFeature\n attr(eStructuralFeature, 'changeable', p('EBoolean'));\n attr(eStructuralFeature, 'volatile', p('EBoolean'));\n attr(eStructuralFeature, 'transient', p('EBoolean'));\n attr(eStructuralFeature, 'defaultValueLiteral', p('EString'));\n attr(eStructuralFeature, 'defaultValue', p('EJavaObject'), {\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n attr(eStructuralFeature, 'unsettable', p('EBoolean'));\n attr(eStructuralFeature, 'derived', p('EBoolean'));\n const feature_eContainingClass = ref(eStructuralFeature, 'eContainingClass', eClass, {\n changeable: false,\n transient: true,\n });\n\n // EAttribute\n attr(eAttribute, 'iD', p('EBoolean'));\n ref(eAttribute, 'eAttributeType', eDataType, { changeable: false, volatile: true, transient: true, derived: true });\n\n // EReference\n attr(eReference, 'containment', p('EBoolean'));\n attr(eReference, 'container', p('EBoolean'), { changeable: false, volatile: true, transient: true, derived: true });\n attr(eReference, 'resolveProxies', p('EBoolean'));\n const eOpposite = ref(eReference, 'eOpposite', eReference, {});\n ref(eReference, 'eReferenceType', eClass, { changeable: false, volatile: true, transient: true, derived: true });\n ref(eReference, 'eKeys', eAttribute, { many: true });\n\n // EClass\n attr(eClass, 'abstract', p('EBoolean'));\n attr(eClass, 'interface', p('EBoolean'));\n ref(eClass, 'eSuperTypes', eClass, { many: true });\n const eOperations = ref(eClass, 'eOperations', eOperation, { many: true, containment: true });\n ref(eClass, 'eAllAttributes', eAttribute, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllReferences', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eReferences', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAttributes', eAttribute, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllContainments', eReference, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllOperations', eOperation, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllStructuralFeatures', eStructuralFeature, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eAllSuperTypes', eClass, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n ref(eClass, 'eIDAttribute', eAttribute, { changeable: false, volatile: true, transient: true, derived: true });\n const eStructuralFeatures = ref(eClass, 'eStructuralFeatures', eStructuralFeature, { many: true, containment: true });\n ref(eClass, 'eGenericSuperTypes', eGenericType, { many: true, containment: true });\n ref(eClass, 'eAllGenericSuperTypes', eGenericType, {\n many: true,\n changeable: false,\n volatile: true,\n transient: true,\n derived: true,\n });\n\n // EDataType\n attr(eDataType, 'serializable', p('EBoolean'));\n\n // EEnum\n const eLiterals = ref(eEnum, 'eLiterals', eEnumLiteral, { many: true, containment: true });\n\n // EEnumLiteral\n attr(eEnumLiteral, 'value', p('EInt'));\n attr(eEnumLiteral, 'instance', p('EEnumerator'), { transient: true });\n attr(eEnumLiteral, 'literal', p('EString'));\n const eEnumLiteral_eEnum = ref(eEnumLiteral, 'eEnum', eEnum, { changeable: false, transient: true });\n\n // EFactory\n const factory_ePackage = ref(eFactory, 'ePackage', ePackage, { transient: true });\n\n // EObject - reflective operations only, no structural features of its\n // own (matches the real file), and no eOperations shell needed here\n // since nothing in Ecore.ecore itself declares operations ON an EObject\n // instance the way it does for EClass etc.\n\n // EOperation\n const operation_eContainingClass = ref(eOperation, 'eContainingClass', eClass, {\n changeable: false,\n transient: true,\n });\n ref(eOperation, 'eTypeParameters', eTypeParameter, { many: true, containment: true });\n const eParameters = ref(eOperation, 'eParameters', eParameter, { many: true, containment: true });\n ref(eOperation, 'eExceptions', eClassifier, { many: true });\n ref(eOperation, 'eGenericExceptions', eGenericType, { many: true, containment: true });\n\n // EPackage\n attr(ePackage, 'nsURI', p('EString'));\n attr(ePackage, 'nsPrefix', p('EString'));\n const eFactoryInstance = ref(ePackage, 'eFactoryInstance', eFactory, { transient: true });\n const eClassifiers = ref(ePackage, 'eClassifiers', eClassifier, { many: true, containment: true });\n const eSubpackages = ref(ePackage, 'eSubpackages', ePackage, { many: true, containment: true });\n const eSuperPackage = ref(ePackage, 'eSuperPackage', ePackage, { changeable: false, transient: true });\n\n // EParameter\n const parameter_eOperation = ref(eParameter, 'eOperation', eOperation, { changeable: false, transient: true });\n\n // EStringToStringMapEntry\n attr(eStringToStringMapEntry, 'key', p('EString'));\n attr(eStringToStringMapEntry, 'value', p('EString'));\n\n // EGenericType\n ref(eGenericType, 'eUpperBound', eGenericType, { containment: true });\n ref(eGenericType, 'eTypeArguments', eGenericType, { many: true, containment: true });\n ref(eGenericType, 'eRawType', eClassifier, { changeable: false, transient: true, derived: true });\n ref(eGenericType, 'eLowerBound', eGenericType, { containment: true });\n ref(eGenericType, 'eTypeParameter', eTypeParameter, {});\n ref(eGenericType, 'eClassifier', eClassifier, {});\n\n // ETypeParameter\n ref(eTypeParameter, 'eBounds', eGenericType, { many: true, containment: true });\n\n // --- Pass 4: opposites (symmetric pairs; matches real Ecore.ecore's own\n // eOpposite declarations exactly).\n eAnnotations.setEOpposite(annotation_eModelElement);\n annotation_eModelElement.setEOpposite(eAnnotations);\n classifier_ePackage.setEOpposite(eClassifiers);\n eClassifiers.setEOpposite(classifier_ePackage);\n feature_eContainingClass.setEOpposite(eStructuralFeatures);\n eStructuralFeatures.setEOpposite(feature_eContainingClass);\n operation_eContainingClass.setEOpposite(eOperations);\n eOperations.setEOpposite(operation_eContainingClass);\n parameter_eOperation.setEOpposite(eParameters);\n eParameters.setEOpposite(parameter_eOperation);\n factory_ePackage.setEOpposite(eFactoryInstance);\n eFactoryInstance.setEOpposite(factory_ePackage);\n eSubpackages.setEOpposite(eSuperPackage);\n eSuperPackage.setEOpposite(eSubpackages);\n eEnumLiteral_eEnum.setEOpposite(eLiterals);\n eLiterals.setEOpposite(eEnumLiteral_eEnum);\n // eOpposite itself is intentionally NOT paired with a reverse eOpposite -\n // matches real Ecore.ecore exactly (EMF handles the symmetry at runtime,\n // not via a modeled self-loop).\n void eOpposite;\n void eType;\n\n // Assemble the package. Real Ecore's own nsURI/nsPrefix/name.\n const pkg = new EPackageImpl();\n pkg.setName('ecore');\n pkg.setNsURI('http://www.eclipse.org/emf/2002/Ecore');\n pkg.setNsPrefix('ecore');\n for (const d of primitives.values()) pkg.getEClassifiers().add(d);\n for (const c of allClasses) pkg.getEClassifiers().add(c);\n pkg.setEFactoryInstance(new DynamicEFactoryImpl());\n\n // Pass 5: assign real, unique featureIDs to every feature (also\n // recomputes EAll* caches internally). Critical, not cosmetic here:\n // DynamicEObjectImpl indexes its own internal storage by featureID, so\n // every feature needs a distinct one before any dynamic instance is\n // constructed against this schema - without this, every feature\n // defaults to the same -1 and many-valued lists silently collide.\n assignFreshIds(pkg);\n\n return {\n pkg,\n eObject,\n eModelElement,\n eAnnotation,\n eNamedElement,\n eTypedElement,\n eClassifier,\n eStructuralFeature,\n eAttribute,\n eReference,\n eClass,\n ePackage,\n eDataType,\n eEnum,\n eEnumLiteral,\n eFactory,\n eOperation,\n eParameter,\n eStringToStringMapEntry,\n eGenericType,\n eTypeParameter,\n };\n}\n","import { EClass, EClassifier, EClassifierImpl, EOperationImpl, EPackage, EStructuralFeatureImpl } from '@typemf/core';\n\n/**\n * Assigns classifierID/featureID freshly, in declaration order, mutating\n * the EClass/EStructuralFeature objects directly - matches real EMF's own\n * behaviour (these are recomputed-every-build implementation details of\n * the generated code, not values meant to persist anywhere). See the\n * design discussion: our wire formats (json/xmi) address by name, never by\n * numeric ID, so this never threatens file compatibility - the only\n * observable effect is generated-code diff noise across unrelated\n * metamodel edits, a cosmetic cost judged acceptable given it matches\n * upstream EMF precedent.\n *\n * featureID is assigned over getEAllStructuralFeatures() (inherited-then-\n * own, matching real EMF), NOT a per-class restart at 0 - a subclass's\n * generated eGet/eSet needs one flat ID space covering both its inherited\n * and its own features (a generated subclass typically delegates any\n * featureID it doesn't recognize to `super.eGet()`/`super.eSet()`), so an\n * inherited feature and a subclass's own new feature must never collide.\n * Reassigning via any subclass's getEAllStructuralFeatures() is safe to\n * repeat for the same feature across multiple classes in the hierarchy -\n * the computed index is the same regardless of which class's perspective\n * computes it, since supertype features always come first in the same\n * relative order.\n *\n * operationID follows the exact same shape and rationale, over\n * getEAllOperations() instead - added for point 4 (EOperation.\n * getOperationID(), which just exposes this).\n */\nexport function assignFreshIds(pkg: EPackage): void {\n let classifierId = 0;\n for (const classifier of pkg.getEClassifiers()) {\n // classifierID/featureID/operationID are deliberately impl-only - not on the public interfaces at\n // all, matching real EMF's own design (see EStructuralFeature.getContainerClass()'s doc comment\n // for the fullest version of this reasoning). assignFreshIds() IS the legitimate \"set once during\n // bootstrap\" caller these setters exist for, so casting to the concrete impl here is correct, not\n // a workaround - the same pattern the generated getOperationID(operation)/getFeatureID(feature)\n // convenience methods themselves use internally.\n (classifier as EClassifierImpl).setClassifierID(classifierId++);\n }\n for (const classifier of pkg.getEClassifiers()) {\n if (!isEClass(classifier)) continue;\n // No recomputeAllLists() call needed anymore - generated get-bodied features cache automatically\n // (see EObjectImpl.getModelGeneration()), unlike hand-written core's old manual-recompute pattern\n // this used to rely on.\n classifier\n .getEAllStructuralFeatures()\n .forEach((feature, index) => (feature as EStructuralFeatureImpl).setFeatureID(index));\n classifier.getEAllOperations().forEach((op, index) => (op as EOperationImpl).setOperationID(index));\n }\n}\n\nfunction isEClass(classifier: EClassifier): classifier is EClass {\n return 'getEStructuralFeatures' in classifier;\n}\n","import { EPackage } from '@typemf/core';\nimport nunjucks from 'nunjucks';\nimport { FileExtension } from './file-extension.js';\nimport { GeneratedFile } from './generated-file.js';\nimport { assignFreshIds } from './id-assignment.js';\nimport { TemplateSet } from './template-set.js';\n\n/**\n * Renders `templateSet`'s main.njk once, over the whole `pkg`. Pure - no\n * disk I/O beyond reading the template files themselves; writing the\n * returned files anywhere is a separate, later step the caller owns. See\n * the design discussion for why `outputDir` deliberately isn't a\n * parameter here: every returned path is relative, so relative imports\n * between generated files are computable without knowing an eventual\n * absolute location.\n */\nexport function generate(\n pkg: EPackage,\n templateSet: TemplateSet,\n options: Record<string, unknown> = {}\n): GeneratedFile[] {\n assignFreshIds(pkg);\n\n const problems = templateSet.validate?.(pkg) ?? [];\n if (problems.length > 0) {\n throw new Error(\n `Cannot generate from this package - ${templateSet.name} found ${problems.length} unresolved problem(s):\\n` +\n problems.map((p) => ` - ${p}`).join('\\n')\n );\n }\n\n const loader = new nunjucks.FileSystemLoader(templateSet.baseFolder, { noCache: true });\n const env = new nunjucks.Environment(loader, { autoescape: false, trimBlocks: true, lstripBlocks: true });\n\n const fileExtension = new FileExtension(\n templateSet.postProcessFile ? (path, content) => templateSet.postProcessFile!(path, content, options) : undefined\n );\n env.addExtension('file', fileExtension);\n env.addGlobal('package', pkg);\n env.addGlobal('options', options);\n\n templateSet.configureEnvironment?.(env, { pkg, options });\n\n env.render('main.njk');\n\n return fileExtension.getCollected();\n}\n","import { GeneratedFile } from './generated-file.js';\n\n/**\n * `{% file somePathExpression %}...content...{% endfile %}` - the\n * mechanism that lets a single template produce any number of output\n * files. The path argument is a full Nunjucks expression (e.g.\n * `eClass.getName() + \"-impl.ts\"`), not a string literal.\n *\n * Content rendered OUTSIDE any {% file %} block is silently discarded -\n * deliberately, so `{% include %}`/`{% macro %}` plumbing and stray\n * whitespace between tags never leak into an actual output file, and so\n * every template-set author follows one uniform rule (\"wrap output in\n * {% file %}, always\") rather than a fallback that's sometimes needed and\n * sometimes isn't.\n *\n * `parser`/`nodes` below are typed as `any`: this is Nunjucks' low-level\n * custom-tag-authoring API (Environment.addExtension), which @types/nunjucks\n * doesn't cover at all (only the high-level render/configure surface is\n * typed) - verified empirically against the real runtime API rather than\n * assumed, since no type declarations exist to check against.\n */\nexport class FileExtension {\n tags = ['file'];\n private readonly collected: GeneratedFile[] = [];\n\n constructor(private readonly postProcess?: (path: string, content: string) => string) {}\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parse(parser: any, nodes: any): any {\n const tok = parser.nextToken();\n const pathExpr = parser.parseExpression();\n parser.advanceAfterBlockEnd(tok.value);\n\n const body = parser.parseUntilBlocks('endfile');\n parser.advanceAfterBlockEnd();\n\n return new nodes.CallExtensionAsync(this, 'run', new nodes.NodeList(tok.lineno, tok.colno, [pathExpr]), [body]);\n }\n\n run(\n _context: unknown,\n path: string,\n body: (callback: (err: unknown, res: string) => void) => void,\n callback: (err: unknown, res: string) => void\n ): void {\n body((err: unknown, content: string) => {\n if (err) {\n callback(err, '');\n return;\n }\n this.collected.push({ path, content: this.postProcess ? this.postProcess(path, content) : content });\n callback(null, '');\n });\n }\n\n /** Everything collected so far in this Environment's lifetime. */\n getCollected(): GeneratedFile[] {\n return this.collected;\n }\n}\n","import { EPackage } from '@typemf/core';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { GeneratorConfig } from './cli-config.js';\nimport { generate } from './generate.js';\nimport { resolveTemplateSet } from './template-set-registry.js';\n\nexport interface RunGenerationResult {\n writtenPaths: string[];\n outputRoot: string;\n}\n\n/**\n * `configDir` is the directory the config file itself lives in -\n * `config.outputDir` resolves relative to THAT, not the process's current\n * working directory, so a config file behaves identically regardless of\n * where the CLI happens to be invoked from.\n */\nexport async function runGeneration(\n config: GeneratorConfig,\n configDir: string,\n pkg: EPackage\n): Promise<RunGenerationResult> {\n const templateSet = resolveTemplateSet(config.templateSet);\n const files = generate(pkg, templateSet, config.options);\n\n const outputRoot = resolve(configDir, config.outputDir);\n const writtenPaths: string[] = [];\n for (const file of files) {\n const fullPath = join(outputRoot, file.path);\n await mkdir(dirname(fullPath), { recursive: true });\n await writeFile(fullPath, file.content, 'utf-8');\n writtenPaths.push(fullPath);\n }\n\n return { writtenPaths, outputRoot };\n}\n","import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport type nunjucks from 'nunjucks';\nimport { TemplateSet } from './template-set.js';\nimport { beginGeneration } from './generation-context.js';\nimport { importCollector, ImportLocation, locationOfPath } from './import-collector.js';\nimport {\n argList,\n beanGetterName,\n concreteEClassesOf,\n detailsEntries,\n docComment,\n eClassesOf,\n factoryClassName,\n findEClassByName,\n groupOperationsByName,\n isEClass,\n isEDataType,\n isEEnum,\n isEReference,\n isOptional,\n isClassifierDerived,\n isBookkeepingOperation,\n findUnnamedElements,\n findUnresolvedCollisions,\n metaclassAccessorCollision,\n metaclassAccessorCollisionTypeNames,\n optionalParamList,\n isPrimitiveValueType,\n jsString,\n mergedParamList,\n mergedReturnType,\n featureGetter,\n featureSetter,\n isReadOnlyFeature,\n needsImplOnlySetter,\n customBodyNeedsOwnField,\n operationBody,\n overloadDispatch,\n registerBodyImports,\n packageClassName,\n paramList,\n primitiveDefaultValue,\n referencedApiTypes,\n referencedOperationTypes,\n singleValuedFeatures,\n superType,\n superTypeChain,\n switchClassName,\n trivialDerivedFormula,\n tsFeatureType,\n tsOperationReturnType,\n tsOptionalScalarType,\n tsScalarType,\n typeGuardsClassName,\n ucfirst,\n} from './typescript-filters.js';\n\n// One level up from this file (src/ or, after build, dist/) lands at the\n// package root either way, since both are direct children of it - see\n// NOTES.md for why this resolves correctly whether running from source\n// (tests) or from the built package.\nconst packageRoot = join(dirname(fileURLToPath(import.meta.url)), '..');\n\n/**\n * Records that the current file's body needs `name` from the given\n * location, returning `name` unchanged so it can be used inline exactly\n * where the type name would otherwise be written directly (e.g.\n * `{{ useImport(\"EAnnotation\", \"types\", {foundational: true}) }} | undefined`).\n * The recording is read back and rendered into real import statements by\n * postProcessFile below, once this file's whole body is known.\n */\nfunction useImport(name: string, location: ImportLocation, opts: { file?: string; foundational: boolean }): string {\n importCollector.add({ name, location, file: opts.file, foundational: opts.foundational });\n return name;\n}\n\nexport const typescriptTemplateSet: TemplateSet = {\n name: 'typescript',\n baseFolder: join(packageRoot, 'templates', 'typescript'),\n validate(pkg): string[] {\n return [\n ...findUnnamedElements(pkg),\n ...findUnresolvedCollisions(pkg).map(\n (c) => `${c.classifierName}.${c.memberName}: name collision between ${c.sources.join(' and ')}`\n ),\n ];\n },\n configureEnvironment(env: nunjucks.Environment, { pkg, options }): void {\n // Runs once per generate() call, before anything renders: drop any\n // reference a type-text function recorded outside a real generation\n // (a unit test calling tsScalarType directly, say) so it can't leak\n // into the first generated file's header.\n importCollector.clear();\n beginGeneration(pkg, options);\n env.addGlobal('docComment', docComment);\n env.addGlobal('operationBody', operationBody);\n env.addGlobal('featureGetter', featureGetter);\n env.addGlobal('featureSetter', featureSetter);\n env.addGlobal('isReadOnlyFeature', isReadOnlyFeature);\n env.addGlobal('needsImplOnlySetter', needsImplOnlySetter);\n env.addGlobal('customBodyNeedsOwnField', customBodyNeedsOwnField);\n env.addGlobal('registerBodyImports', registerBodyImports);\n env.addGlobal('overloadDispatch', overloadDispatch);\n env.addGlobal('tsScalarType', tsScalarType);\n env.addGlobal('tsFeatureType', tsFeatureType);\n env.addGlobal('tsOperationReturnType', tsOperationReturnType);\n env.addGlobal('isOptional', isOptional);\n env.addGlobal('isEClass', isEClass);\n env.addGlobal('isEEnum', isEEnum);\n env.addGlobal('isEDataType', isEDataType);\n env.addGlobal('isEReference', isEReference);\n env.addGlobal('paramList', paramList);\n env.addGlobal('argList', argList);\n env.addGlobal('ucfirst', ucfirst);\n env.addGlobal('packageClassName', packageClassName);\n env.addGlobal('factoryClassName', factoryClassName);\n env.addGlobal('switchClassName', switchClassName);\n env.addGlobal('superType', superType);\n env.addGlobal('superTypeChain', superTypeChain);\n env.addGlobal('referencedApiTypes', referencedApiTypes);\n env.addGlobal('referencedOperationTypes', referencedOperationTypes);\n env.addGlobal('eClassesOf', eClassesOf);\n env.addGlobal('concreteEClassesOf', concreteEClassesOf);\n env.addGlobal('singleValuedFeatures', singleValuedFeatures);\n env.addGlobal('trivialDerivedFormula', trivialDerivedFormula);\n env.addGlobal('findEClassByName', findEClassByName);\n env.addGlobal('jsString', jsString);\n env.addGlobal('detailsEntries', detailsEntries);\n env.addGlobal('beanGetterName', beanGetterName);\n env.addGlobal('isPrimitiveValueType', isPrimitiveValueType);\n env.addGlobal('primitiveDefaultValue', primitiveDefaultValue);\n env.addGlobal('tsOptionalScalarType', tsOptionalScalarType);\n env.addGlobal('groupOperationsByName', groupOperationsByName);\n env.addGlobal('mergedParamList', mergedParamList);\n env.addGlobal('mergedReturnType', mergedReturnType);\n env.addGlobal('isClassifierDerived', isClassifierDerived);\n env.addGlobal('isBookkeepingOperation', isBookkeepingOperation);\n env.addGlobal('metaclassAccessorCollision', metaclassAccessorCollision);\n env.addGlobal('metaclassAccessorCollisionTypeNames', metaclassAccessorCollisionTypeNames);\n env.addGlobal('optionalParamList', optionalParamList);\n env.addGlobal('typeGuardsClassName', typeGuardsClassName);\n env.addGlobal('useImport', useImport);\n },\n postProcessFile(path, content, options): string {\n const header = importCollector.render(locationOfPath(path), options);\n importCollector.clear();\n return header ? `${header}\\n\\n${content}` : content;\n },\n};\n","import { detailValue, EClassifier, EList, EModelElement, EStringToStringMapEntry } from '@typemf/core';\n\n/** The annotation source that says what to import and where it is imported from. */\nexport const IMPORT_ANNOTATION_SOURCE = 'https://typemf.dev/generator/import';\n\n/**\n * One import: which symbol, and where it comes from. (What TEXT a datatype\n * is emitted as is a separate matter - the `type` detail of the annotation\n * with source https://typemf.dev/generator; see resolveDataTypeTs. The two\n * usually name the same thing, but need not: the text may be `number |\n * undefined` while the symbol imported is something else.)\n *\n * - `type`: the symbol to import.\n * - `from`: the module other packages import it from - a module specifier,\n * used as written (e.g. \"@typemf/core\"). Applies to an EXTERNAL use:\n * the element belongs to a package other than the one being generated.\n * - `internalFrom`: where the package being generated imports it from,\n * relative to the ROOT of the generated package when it starts with\n * \"./\" or \"../\" (see ImportEntry.from). Applies to an INTERNAL use: the\n * element belongs to the package being generated. Falls back to `from`.\n */\nexport interface TypeImportInfo {\n type: string;\n from?: string;\n internalFrom?: string;\n}\n\n/** The same shape as the annotation's own detail keys, for entries supplied from outside the model (see TypeImportMapping). */\nexport type TypeImportEntries = Record<string, { type?: string; from?: string; 'internal-from'?: string }>;\n\nconst nonEmpty = (value: string | undefined): string | undefined =>\n value !== undefined && value !== '' ? value : undefined;\n\nfunction info(type: string, from: string | undefined, internalFrom: string | undefined): TypeImportInfo {\n const result: TypeImportInfo = { type };\n if (from !== undefined) result.from = from;\n if (internalFrom !== undefined) result.internalFrom = internalFrom;\n return result;\n}\n\nfunction importInfoOf(details: EList<EStringToStringMapEntry> | undefined): TypeImportInfo | undefined {\n const type = nonEmpty(details && detailValue(details, 'type'));\n if (type === undefined) return undefined;\n return info(\n type,\n nonEmpty(details && detailValue(details, 'from')),\n nonEmpty(details && detailValue(details, 'internal-from'))\n );\n}\n\n/**\n * The import information an element carries itself: the details `type`,\n * `from` and `internal-from` of its (first) annotation with source\n * https://typemf.dev/generator/import. Without a `type` the annotation says\n * nothing (there is no symbol to import) and is ignored. Values are used\n * as written - not checked, not interpreted; empty counts as absent.\n */\nexport function readImportAnnotation(element: EModelElement): TypeImportInfo | undefined {\n return importInfoOf(element.getEAnnotation(IMPORT_ANNOTATION_SOURCE)?.getDetails());\n}\n\n/**\n * EVERY import annotation on an element, in order - an element that needs\n * several imports (an operation whose body uses several symbols) carries\n * one annotation per import. Each is read like readImportAnnotation.\n */\nexport function readImportAnnotations(element: EModelElement): TypeImportInfo[] {\n const result: TypeImportInfo[] = [];\n for (const annotation of element.getEAnnotations()) {\n if (annotation.getSource() !== IMPORT_ANNOTATION_SOURCE) continue;\n const entry = importInfoOf(annotation.getDetails());\n if (entry !== undefined) result.push(entry);\n }\n return result;\n}\n\n/**\n * The one place import information for types is looked up. Today it is\n * fed by the annotations in the model (readImportAnnotation); explicit\n * entries - keyed `<package nsURI>#<classifier name>`, e.g.\n * \"http://www.eclipse.org/emf/2002/Ecore#EEList\" - take precedence over\n * an annotation and are the seam for supplying the same information from\n * outside the model (the generator config's mapping of ecore packages to\n * TypeScript modules): pre-populate them, and nothing else in the\n * generator changes. An explicit entry replaces the annotation entirely,\n * field by field is deliberately not merged.\n */\nexport class TypeImportMapping {\n private readonly explicit = new Map<string, TypeImportInfo>();\n\n constructor(entries: TypeImportEntries = {}) {\n for (const [key, entry] of Object.entries(entries)) {\n const type = nonEmpty(entry.type);\n if (type !== undefined) this.set(key, info(type, nonEmpty(entry.from), nonEmpty(entry['internal-from'])));\n }\n }\n\n static keyOf(classifier: EClassifier): string {\n return `${classifier.getEPackage()?.getNsURI() ?? ''}#${classifier.getName()}`;\n }\n\n set(key: string, value: TypeImportInfo): void {\n this.explicit.set(key, value);\n }\n\n lookup(classifier: EClassifier): TypeImportInfo | undefined {\n return this.explicit.get(TypeImportMapping.keyOf(classifier)) ?? readImportAnnotation(classifier);\n }\n}\n","import { EClassifier, EPackage } from '@typemf/core';\nimport { TypeImportEntries, TypeImportMapping } from './type-import-mapping.js';\n\n/**\n * What the type-resolution code needs to know about the generation in\n * progress: which package is being generated (so it can tell an internal\n * type from an external one), and the import mapping. A single shared\n * instance, like the import collector, set up once per generate() call by\n * the typescript template set (see beginGeneration) - the type-text\n * functions are called from templates and have no other way to reach it.\n */\nexport interface GenerationContext {\n pkg: EPackage | undefined;\n typeImports: TypeImportMapping;\n}\n\nexport const generationContext: GenerationContext = { pkg: undefined, typeImports: new TypeImportMapping() };\n\n/** The generation option that pre-populates the mapping - see TypeImportMapping. */\nexport const TYPE_IMPORTS_OPTION = 'type-imports';\n\nexport function beginGeneration(pkg: EPackage, options: Record<string, unknown>): void {\n generationContext.pkg = pkg;\n const entries = options[TYPE_IMPORTS_OPTION];\n const valid = typeof entries === 'object' && entries !== null && !Array.isArray(entries);\n generationContext.typeImports = new TypeImportMapping(valid ? (entries as TypeImportEntries) : {});\n}\n\n/** Back to \"no generation in progress\": nothing is external, the mapping is empty. */\nexport function resetGenerationContext(): void {\n generationContext.pkg = undefined;\n generationContext.typeImports = new TypeImportMapping();\n}\n\n/**\n * The internal/external decision, made per use during generation: a type\n * is EXTERNAL when it belongs to a package other than the one being\n * generated. With no generation in progress, or a type that belongs to no\n * package, nothing can be external.\n */\nexport function isExternal(classifier: EClassifier): boolean {\n const owner = classifier.getEPackage();\n return generationContext.pkg !== undefined && owner !== undefined && owner !== generationContext.pkg;\n}\n","import { posix } from 'node:path';\n\nexport type ImportLocation = 'root' | 'types' | 'impl' | 'util';\n\nexport interface ImportEntry {\n /** The identifier as it appears in generated code. */\n name: string;\n /** Which conceptual folder this name's own generated file lives in. */\n location: ImportLocation;\n /** File base name (no extension), if different from `name` - e.g. \"Ids\" and \"EcorePackage\" both come from the same file, \"EcorePackage.js\". */\n file?: string;\n /**\n * true for the foundational Ecore meta-types (EClass, EObjectImpl,\n * BasicEList, ...) that also exist as @typemf/core exports - these\n * resolve to '@typemf/core' in ordinary mode, and to a relative import\n * in generate-ecore mode (since that same file is being produced by\n * this generation run instead). false for names unique to the\n * metamodel being generated right now (the package class, its factory,\n * its Ref module, every classifier's own type) - these never exist in\n * @typemf/core at all, so they're always a relative import, regardless\n * of generate-ecore.\n */\n foundational: boolean;\n /**\n * An explicit module to import `name` from, overriding location/file/\n * foundational entirely - set from a type's import information (see\n * TypeImportMapping). A value starting with \"./\" or \"../\" is relative to the\n * ROOT of the generated package (where {Pkg}Package.ts lives), and gets\n * re-expressed relative to each importing file's own folder; anything\n * else is a bare module specifier, used verbatim.\n */\n from?: string;\n}\n\n/**\n * Computes the relative import path from a file in `from` to a file\n * named `file` living in `to` - both are the four conceptual folders\n * every generated package has (root alongside types/, impl/, util/).\n * Always a direct file path, never a barrel (`index.js`) - see\n * coreImportLine's old doc comment in git history for why: importing\n * from your own folder's barrel puts every file in that folder into one\n * strongly-connected component, which broke self-hosting's bootstrap\n * outright (confirmed empirically, not theoretical).\n */\nexport function relativeImportPath(from: ImportLocation, to: ImportLocation, file: string): string {\n if (from === to) return `./${file}.js`;\n if (from === 'root') return `./${to}/${file}.js`;\n if (to === 'root') return `../${file}.js`;\n return `../${to}/${file}.js`;\n}\n\n/**\n * Collects every type reference a template makes while rendering one\n * file's body (via `useType()`, see typescript-template-set.ts), then\n * renders the deduplicated, sorted, direct (never-barrel) import\n * statements for that file once its body is fully known.\n *\n * One instance lives for the whole generation run, reused across files:\n * call `clear()` between files (postProcessFile does this after each\n * file, in typescript-template-set.ts) rather than constructing a new\n * one - nunjucks globals are registered once for the whole Environment,\n * so this needs to be a single, stable object `useType` can find via\n * closure, not re-created per file.\n */\nexport class ImportCollector {\n /**\n * Every distinct way each name has been requested. Usually one; more\n * than one is only a problem if, once the mode and importing folder are\n * known (render time), they resolve to genuinely different modules.\n */\n private entries = new Map<string, ImportEntry[]>();\n\n add(entry: ImportEntry): void {\n const variants = this.entries.get(entry.name) ?? [];\n const sameSource = variants.findIndex(\n (v) => v.location === entry.location && (v.file ?? v.name) === (entry.file ?? entry.name) && v.from === entry.from\n );\n if (sameSource >= 0) {\n // Same source, different `foundational`: both resolve identically\n // once the mode is known (see ImportEntry's own doc comment) - this\n // genuinely happens for a real Ecore.ecore classifier that's ALSO\n // one of the fixed, always-present parameter/return types every\n // generated class has (e.g. \"EStructuralFeature\" in eGet(feature:\n // EStructuralFeature), separately from any reference to it AS a\n // classifier via referencedApiTypes). Prefer foundational: true -\n // the more general categorization, correct in both modes.\n if (entry.foundational && !variants[sameSource]!.foundational) variants[sameSource] = entry;\n } else {\n variants.push(entry);\n }\n this.entries.set(entry.name, variants);\n }\n\n clear(): void {\n this.entries.clear();\n }\n\n isEmpty(): boolean {\n return this.entries.size === 0;\n }\n\n render(currentLocation: ImportLocation, options: Record<string, unknown>): string {\n const generateEcore = Boolean(options['generate-ecore']);\n const corePackageNames: string[] = [];\n const groups = new Map<string, { specifier: string; names: string[] }>();\n const addToGroup = (key: string, specifier: string, name: string) => {\n if (!groups.has(key)) groups.set(key, { specifier, names: [] });\n groups.get(key)!.names.push(name);\n };\n\n for (const name of [...this.entries.keys()].sort((a, b) => a.localeCompare(b))) {\n const resolved = this.entries\n .get(name)!\n .map((entry) => ({ entry, ...resolveEntry(entry, currentLocation, generateEcore) }));\n\n // Two requests for the same name are one import only if they name\n // the same module - \"the same module, however spelled\": the\n // extension is not significant (a datatype annotation's\n // an annotation's import path is used exactly as written, generated\n // paths always carry \".js\").\n const distinct = new Set(resolved.map((r) => r.specifier.replace(/\\.(js|ts)$/, '')));\n if (distinct.size > 1) {\n throw new Error(\n `Import collision while generating: \"${name}\" was requested from ` +\n `${resolved.map((r) => `\"${r.specifier}\"`).join(' and ')}. A single name must resolve to exactly one real source.`\n );\n }\n // An explicitly requested spelling (an annotation's own path) wins over a generated one.\n const chosen = resolved.find((r) => r.entry.from !== undefined) ?? resolved[0]!;\n if (chosen.core) corePackageNames.push(name);\n else addToGroup(chosen.key, chosen.specifier, name);\n }\n\n const lines: string[] = [];\n if (corePackageNames.length > 0) {\n lines.push(`import { ${corePackageNames.join(', ')} } from '@typemf/core';`);\n }\n for (const key of [...groups.keys()].sort()) {\n const { specifier, names } = groups.get(key)!;\n lines.push(`import { ${names.join(', ')} } from '${specifier}';`);\n }\n return lines.join('\\n');\n }\n}\n\nfunction resolveEntry(\n entry: ImportEntry,\n currentLocation: ImportLocation,\n generateEcore: boolean\n): { specifier: string; key: string; core: boolean } {\n if (entry.from !== undefined) {\n const specifier = explicitImportSpecifier(entry.from, currentLocation);\n // An explicitly requested \"@typemf/core\" IS the foundational package - one merged statement, not two.\n return { specifier, key: `~${specifier}`, core: specifier === '@typemf/core' };\n }\n if (entry.foundational && !generateEcore) return { specifier: '@typemf/core', key: '@typemf/core', core: true };\n const file = entry.file ?? entry.name;\n return {\n specifier: relativeImportPath(currentLocation, entry.location, file),\n key: `${entry.location}/${file}`,\n core: false,\n };\n}\n\n/** See ImportEntry.from. */\nexport function explicitImportSpecifier(from: string, currentLocation: ImportLocation): string {\n if (!from.startsWith('./') && !from.startsWith('../')) return from;\n const fromDir = posix.join('/pkg', currentLocation === 'root' ? '' : currentLocation);\n const relative = posix.relative(fromDir, posix.join('/pkg', from));\n return relative.startsWith('.') ? relative : `./${relative}`;\n}\n\n/**\n * The single collector shared by the whole typescript template set: both\n * templates (via useImport) and type-text functions (see\n * typescript-filters.ts's tsScalarType, which registers a datatype's\n * annotation-supplied import as it emits the type) record into this one\n * instance, and postProcessFile renders and clears it once per file.\n */\nexport const importCollector = new ImportCollector();\n\n/** Derives a file's ImportLocation from its own generated path (e.g. \"types/EClass.ts\" -> \"types\", \"EcorePackage.ts\" -> \"root\"). */\nexport function locationOfPath(path: string): ImportLocation {\n if (path.startsWith('types/')) return 'types';\n if (path.startsWith('impl/')) return 'impl';\n if (path.startsWith('util/')) return 'util';\n return 'root';\n}\n","import { generationContext, isExternal } from './generation-context.js';\nimport { importCollector } from './import-collector.js';\nimport { readImportAnnotations } from './type-import-mapping.js';\nimport {\n detailValue,\n EAnnotation,\n EClass,\n EClassifier,\n EDataType,\n EEnum,\n EGenericType,\n EModelElement,\n EOperation,\n EPackage,\n EStructuralFeature,\n ETypedElement,\n} from '@typemf/core';\n\n/** The generator's own annotation source. */\nexport const TYPEMF_GENERATOR_ANNOTATION_SOURCE = 'https://typemf.dev/generator';\n\n/** Real EMF's own GenModel annotation source - where its GenModel keeps an operation's `body`. */\nexport const ECLIPSE_GENMODEL_ANNOTATION_SOURCE = 'http://www.eclipse.org/emf/2002/GenModel';\n\n/** Real EMF's Ecore annotation source - the documentation fallback (real Ecore.ecore uses it for `constraints`). */\nexport const ECLIPSE_ECORE_ANNOTATION_SOURCE = 'http://www.eclipse.org/emf/2002/Ecore';\n\n/**\n * The layering rule shared by everything that is read from an element's\n * annotations under a plain key: the `key` detail of the annotation with\n * source https://typemf.dev/generator first, then the same key in the\n * annotation with source `fallbackSource`. Which fallback source applies\n * is decided per thing being read (see documentationOf, operationBody),\n * not globally. Used as written - not checked, not interpreted; an empty\n * value counts as absent (so it falls through to the next layer).\n */\nexport function layeredAnnotationDetail(\n element: EModelElement,\n key: string,\n fallbackSource: string\n): string | undefined {\n for (const source of [TYPEMF_GENERATOR_ANNOTATION_SOURCE, fallbackSource]) {\n const details = element.getEAnnotation(source)?.getDetails();\n const value = details && detailValue(details, key);\n if (value !== undefined && value !== '') return value;\n }\n return undefined;\n}\n\n/**\n * An element's documentation: the `documentation` detail, layered - the\n * typemf generator annotation first, the annotation with source\n * http://www.eclipse.org/emf/2002/Ecore as the fallback.\n *\n * NOTE: real EMF keeps `documentation` in the GenModel source\n * (http://www.eclipse.org/emf/2002/GenModel), not the Ecore one - so that\n * is deliberately NOT read here: documentation an EMF-authored .ecore\n * carries under GenModel is ignored unless it is also supplied under one\n * of the two sources above.\n */\nexport function documentationOf(element: EModelElement): string | undefined {\n return layeredAnnotationDetail(element, 'documentation', ECLIPSE_ECORE_ANNOTATION_SOURCE);\n}\n\n/**\n * Renders a JSDoc block from documentationOf(), or '' if there is none.\n * Deliberately WITHOUT a trailing newline: every template writes\n * `{{ docComment(x) }}` on its own line and puts the declaration on the\n * next one, so the template's own newline is what separates them - a\n * trailing newline here as well used to leave a blank line between every\n * doc comment and the declaration it documents.\n */\nexport function docComment(element: EModelElement, indent = ''): string {\n const doc = documentationOf(element);\n if (!doc) return '';\n const lines = doc.trim().split('\\n');\n if (lines.length === 1) {\n return `${indent}/** ${lines[0]} */`;\n }\n const body = lines.map((line) => `${indent} * ${line}`).join('\\n');\n return `${indent}/**\\n${body}\\n${indent} */`;\n}\n\n/**\n * An operation's body, in strict priority order:\n *\n * 1. the `body` detail of the annotation with source\n * https://typemf.dev/generator\n * 2. the `body` detail of the annotation with source\n * http://www.eclipse.org/emf/2002/GenModel\n *\n * Used as written - not checked, not interpreted; an empty value counts\n * as absent (the operation then gets the throwing stub). Note the second\n * layer is real EMF's own key, where the value is Java source: a real\n * EMF-authored .ecore that carries Java bodies there will have that Java\n * emitted verbatim unless a layer-1 body overrides it - which is the\n * point of the ordering, and the reason a layer-1 body should be added\n * to any operation whose GenModel body isn't valid TypeScript.\n *\n * (Earlier versions read a per-template-set key, `body:typescript`, on\n * the reasoning that one shared key would be ambiguous across multiple\n * target languages. Replaced on request by these two layers.)\n */\nexport function operationBody(operation: EOperation): string | undefined {\n return layeredAnnotationDetail(operation, 'body', ECLIPSE_GENMODEL_ANNOTATION_SOURCE);\n}\n\n/**\n * The annotation source for a structural feature's own custom getter/setter\n * bodies: `get` and `set` details of the annotation with source\n * https://typemf.dev/generator/feature. Deliberately NOT layered with a\n * GenModel fallback (unlike documentationOf/operationBody) - this source\n * was specified on its own, with no second layer requested.\n */\nexport const FEATURE_ANNOTATION_SOURCE = 'https://typemf.dev/generator/feature';\n\nfunction featureDetail(feature: EStructuralFeature, key: string): string | undefined {\n const details = feature.getEAnnotation(FEATURE_ANNOTATION_SOURCE)?.getDetails();\n const value = details && detailValue(details, key);\n return value !== undefined && value !== '' ? value : undefined;\n}\n\n/**\n * A feature's custom getter body (`get` detail), used verbatim as the body\n * of its bean getter method - and, so reflective access agrees with the\n * real implementation (the bug found and fixed for\n * EClass.getEAllStructuralFeatures: the generated eGet used to read the\n * STORED FIELD directly, bypassing any computed getter entirely), as what\n * `eGet` calls too. A feature with a custom getter has NO stored field at\n * all - there is nothing for the old field-reading shape to read.\n */\nexport function featureGetter(feature: EStructuralFeature): string | undefined {\n return featureDetail(feature, 'get');\n}\n\n/**\n * A feature's custom setter body (`set` detail), used verbatim as the body\n * of its bean setter method, and what `eSet` delegates to reflectively -\n * replacing the default oldValue/eBasicSetValue/eDidAdd/eDidRemove\n * machinery entirely, since a custom setter defines the feature's true\n * write semantics itself. Only meaningful for a SINGLE-valued feature: a\n * many-valued feature never has a setter method to begin with (real EMF\n * convention - the getter's EList is mutated directly), so a `set` on one\n * is a no-op, flagged by findFeatureAnnotationProblems.\n */\nexport function featureSetter(feature: EStructuralFeature): string | undefined {\n return featureDetail(feature, 'set');\n}\n\n/**\n * Whether a feature with both a custom getter and a custom setter genuinely needs its own backing\n * field - true only when at least one of the two bodies actually references it (`this._name`).\n * EEnumLiteral.literal's getter/setter do (\"this._literal ?? this.getName()\", \"this._literal =\n * value\") - it needs a field. A feature whose getter/setter delegate entirely to a DIFFERENT\n * feature (e.g. a \"shout\" getter/setter that only ever reads/writes \"raw\") does not - declaring an\n * unused field for it would be dead weight, and checking `eIsSet`/`eUnset` against that field would\n * be flatly wrong (the field never changes, so \"is set\" would never reflect reality). Found by\n * running this exact case: an earlier version of this rule declared a field for EVERY getter+setter\n * pair unconditionally, breaking any feature that delegates to another one entirely.\n */\nexport function customBodyNeedsOwnField(feature: EStructuralFeature): boolean {\n const getter = featureGetter(feature);\n const setter = featureSetter(feature);\n if (!getter && !setter) return false;\n const ownFieldRef = new RegExp(`\\\\bthis\\\\._${feature.getName()}\\\\b`);\n return (getter !== undefined && ownFieldRef.test(getter)) || (setter !== undefined && ownFieldRef.test(setter));\n}\n\n/**\n * Whether a single-valued feature has no setter at all: either a\n * trivialDerivedFormula (pre-existing, hard-coded), or a custom getter\n * with no custom setter (a feature computed by featureGetter, and nothing\n * says how to write it back). A many-valued feature is unaffected by this\n * (it never has a setter regardless).\n */\nexport function isReadOnlyFeature(feature: EStructuralFeature): boolean {\n return (\n trivialDerivedFormula(feature) !== undefined ||\n (featureGetter(feature) !== undefined && featureSetter(feature) === undefined)\n );\n}\n\n/**\n * A changeable=false feature that isn't otherwise read-only (not derived, no custom getter) still\n * needs a real setter SOMEWHERE - real EMF's own convention (matches this session's earlier\n * containerClass work): a plain, impl-only setter that bypasses eSet/eDidAdd/eDidRemove entirely\n * (direct field assignment, no notification), reachable only by callers with the concrete impl type\n * (bootstrap code, the loader), never through the public interface or reflective eSet.\n */\nexport function needsImplOnlySetter(feature: EStructuralFeature): boolean {\n return !isReadOnlyFeature(feature) && !feature.isChangeable();\n}\n\n/** findDataTypeAnnotationProblems's counterpart for feature get/set annotations: a `set` on a many-valued feature is a no-op (see featureSetter), reported rather than silently ignored. */\nexport function findFeatureAnnotationProblems(pkg: EPackage): string[] {\n const problems: string[] = [];\n for (const classifier of pkg.getEClassifiers()) {\n if (!isEClass(classifier)) continue;\n for (const feature of classifier.getEStructuralFeatures()) {\n if (feature.isMany() && featureSetter(feature) !== undefined) {\n problems.push(\n `${classifier.getName()}.${feature.getName()}: has a \\`set\\` annotation, but is many-valued - many-valued features never have a setter, so it is ignored`\n );\n }\n }\n }\n return problems;\n}\n\n/**\n * Real, correct formula bodies for the four derived ETypedElement/\n * EReference features that are trivially computable from the same\n * instance's OTHER stored fields - deliberately NOT extended to the\n * ~14 traversal-based derived features real Ecore.ecore also has\n * (eAllSuperTypes, eAllStructuralFeatures, ...): those would need a real,\n * generically-applicable traversal algorithm, which risks exactly the\n * kind of rushed, undertested logic this project has repeatedly caught\n * bugs in when attempted under time pressure. Applied only at the bean\n * accessor level (getMany(), not the reflective eGet() switch) - a\n * narrow, deliberate, documented inconsistency between the two access\n * paths for just these four features, not a general pattern.\n */\nconst TRIVIAL_DERIVED_FORMULAS: Record<string, string> = {\n many: 'this.getUpperBound() === -1 || this.getUpperBound() > 1',\n // Verified directly against real EMF's own ETypedElementImpl.isRequired()\n // source (org.eclipse.emf.ecore.impl) while implementing the equivalent\n // reflective dispatch in @typemf/core: it is exactly `lowerBound >= 1`,\n // with NO `!many` check. An earlier version of this formula incorrectly\n // added one; caught only because the hand-written @typemf/core port\n // (built independently, then checked against the same source) disagreed\n // with this file.\n required: 'this.getLowerBound() >= 1',\n container: '(this.getEOpposite()?.isContainment() ?? false)',\n eReferenceType: '(this.getEType() as EClass | undefined)',\n eAttributeType: '(this.getEType() as EDataType | undefined)',\n};\n\n/** The real formula body for a trivially-computable derived feature, or undefined if `feature` isn't one of the four. */\nexport function trivialDerivedFormula(feature: EStructuralFeature): string | undefined {\n if (!feature.isDerived()) return undefined;\n return TRIVIAL_DERIVED_FORMULAS[feature.getName()!];\n}\n\n/**\n * The TypeScript type name for a classifier's scalar form (no EList\n * wrapping). `undefined` specifically means \"this feature's type is\n * Ecore's own EObject classifier\" - the generator never produces its own\n * api/gen/impl files for a classifier named \"EObject\" (matches the\n * existing no-declared-supertype convention, which already falls back to\n * the real @typemf/core EObject rather than generating a redundant,\n * shadowing one - see eclass.njk / main.njk). The dynamic-to-typed\n * conversion step that builds a real metamodel from a parsed .ecore file\n * deliberately leaves such a feature's eType unset for exactly this\n * reason, so `undefined` reaching here always means EObject.\n */\nexport function tsScalarType(type: EClassifier | ETypedElement | undefined): string {\n if (type !== undefined && isTypedElement(type)) return tsTypeReference(type.getEType(), type.getEGenericType());\n return tsTypeReference(type, undefined);\n}\n\n/** ETypedElement vs EClassifier - only a typed element has getEType(). */\nfunction isTypedElement(x: EClassifier | ETypedElement): x is ETypedElement {\n return 'getEType' in x;\n}\n\n/**\n * The TypeScript text for a reference to `classifier`, including type\n * arguments when the classifier is generic (declares eTypeParameters):\n * one argument per declared parameter, in order - the corresponding\n * eTypeArgument of `genericType` where it is present and bound (to a\n * classifier, or to an enclosing type parameter), and `unknown` where it\n * is missing or unbound (Ecore's `<eTypeArguments/>`). So an EJavaClass\n * used with no argument at all and one used with an explicitly empty\n * argument both read `TypeScriptClass<unknown>`, and EJavaClass<EString>\n * reads `TypeScriptClass<string>` (through the argument's own datatype\n * resolution).\n */\nfunction tsTypeReference(classifier: EClassifier | undefined, genericType: EGenericType | undefined): string {\n const base = tsBaseType(classifier);\n const parameterCount = classifier?.getETypeParameters().size() ?? 0;\n if (parameterCount === 0) return base;\n const given = genericType?.getETypeArguments();\n const args: string[] = [];\n for (let i = 0; i < parameterCount; i++) {\n const argument = given !== undefined && i < given.size() ? given.get(i) : undefined;\n args.push(argument === undefined ? 'unknown' : tsGenericArgument(argument));\n }\n return `${base}<${args.join(', ')}>`;\n}\n\nfunction tsGenericArgument(argument: EGenericType): string {\n const classifier = argument.getEClassifier();\n if (classifier) return tsTypeReference(classifier, argument);\n const parameter = argument.getETypeParameter();\n if (parameter) return parameter.getName()!;\n return 'unknown';\n}\n\n/**\n * Every classifier bound anywhere inside `genericType`'s type arguments,\n * recursively (not `genericType`'s own classifier - that is the element's\n * eType, handled separately) - needed so the templates can register the\n * imports the emitted type arguments require.\n */\nexport function genericArgumentClassifiers(genericType: EGenericType | undefined): EClassifier[] {\n const result: EClassifier[] = [];\n const visit = (gt: EGenericType) => {\n for (const argument of gt.getETypeArguments()) {\n const classifier = argument.getEClassifier();\n if (classifier) result.push(classifier);\n visit(argument);\n }\n };\n if (genericType) visit(genericType);\n return result;\n}\n\n/** The type's own name/text with no type arguments: EObject for an absent type, the layered datatype text, or the classifier's name. */\nfunction tsBaseType(classifier: EClassifier | undefined): string {\n if (!classifier) {\n // Emitting a bare \"EObject\" is a real reference to the foundational\n // type - record it, same as any other emitted type. (Missed by the\n // first cut of the import-collector rewrite: confirmed against real\n // Ecore.ecore, where EAnnotation.contents/references - typed EObject,\n // whose eType the loader deliberately leaves unset - generated an\n // \"EObject\" with no import at all.)\n importCollector.add({ name: 'EObject', location: 'types', foundational: true });\n return 'EObject';\n }\n if (isEDataType(classifier)) return tsPrimitiveType(classifier);\n // EClass or EEnum: the generated api-layer type shares the classifier's own name.\n return classifier.getName()!;\n}\n\nexport interface ResolvedDataTypeText {\n /** The TypeScript type text to emit wherever this datatype is used. */\n text: string;\n /** The import this use needs, if the datatype has import information that applies (see resolveDataTypeTs): the symbol and the module it comes from (see ImportEntry.from). Independent of where `text` came from. */\n importName?: string;\n importFrom?: string;\n}\n\n/**\n * The layered resolution of what TypeScript type text an EDataType\n * stands for, wherever it occurs (attribute/reference type, operation\n * return type, parameter type, ...), in strict priority order - and with\n * NO built-in knowledge of any datatype: every mapping comes from the\n * metamodel (or the mapping supplied alongside it), and a missing one is\n * a fix there, not something the generator papers over.\n *\n * 1. The `type` detail of the datatype's annotation with source\n * https://typemf.dev/generator - the text, as written.\n * 2. The datatype's `instanceClassName`, as written, if set.\n * 3. The datatype's name, as written.\n *\n * Separately from which layer supplied the text, the datatype's IMPORT\n * information (TypeImportMapping: the explicit mapping entry if there is\n * one, else its annotation with source https://typemf.dev/generator/import)\n * says what to import when it is used: its `type` symbol, from `from` if\n * the datatype is EXTERNAL (belongs to a package other than the one being\n * generated) or from `internal-from` (falling back to `from`) if INTERNAL.\n * If the key that applies is absent, no import is registered - the text is\n * still emitted, so a missing import shows up as a compile error naming\n * the type.\n *\n * Nothing is checked or interpreted.\n */\nexport function resolveDataTypeTs(dataType: EDataType): ResolvedDataTypeText {\n const resolved = resolveDataTypeText(dataType);\n const importInfo = generationContext.typeImports.lookup(dataType);\n if (importInfo !== undefined) {\n const source = isExternal(dataType) ? importInfo.from : (importInfo.internalFrom ?? importInfo.from);\n if (source !== undefined) return { ...resolved, importName: importInfo.type, importFrom: source };\n }\n return resolved;\n}\n\nfunction resolveDataTypeText(dataType: EDataType): ResolvedDataTypeText {\n const ownDetails = dataType.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();\n const annotated = ownDetails && detailValue(ownDetails, 'type');\n if (annotated !== undefined && annotated !== '') return { text: annotated };\n const instanceClassName = dataType.getInstanceClassName();\n if (instanceClassName !== undefined && instanceClassName !== '') return { text: instanceClassName };\n return { text: dataType.getName()! };\n}\n\n/**\n * Registers the imports a body declares - an operation's, or (see\n * FEATURE_ANNOTATION_SOURCE) a feature's custom getter/setter: one\n * annotation with source https://typemf.dev/generator/import per import\n * (`type` = the symbol; `from` / `internal-from` reuse a datatype's detail\n * names, but NOT its external/internal MEANING - see below).\n *\n * A body is always internal: it is source code that becomes part of the\n * package being generated, in every generation, never a reference to a\n * type belonging to some other package. So there is no isExternal()\n * check here (contrast resolveDataTypeTs, where a datatype genuinely can\n * belong to a different package) - `internal-from` applies, falling back\n * to `from` only as an alternate spelling of the same (internal) path,\n * not as a distinct external case. Returns '' - it is called for its\n * effect, from the template that emits the body.\n */\nexport function registerBodyImports(element: EModelElement): string {\n for (const entry of readImportAnnotations(element)) {\n const source = entry.internalFrom ?? entry.from;\n if (source !== undefined)\n importCollector.add({ name: entry.type, location: 'root', foundational: false, from: source });\n }\n return '';\n}\n\nfunction tsPrimitiveType(dataType: EDataType): string {\n const resolved = resolveDataTypeTs(dataType);\n if (resolved.importName !== undefined && resolved.importFrom !== undefined) {\n importCollector.add({\n name: resolved.importName,\n location: 'root',\n foundational: false,\n from: resolved.importFrom,\n });\n }\n return resolved.text;\n}\n\n/**\n * The EDataTypes that map to real TypeScript primitives with a genuine\n * zero-value, mirroring real Java EMF's own primitive/wrapper distinction\n * exactly: EBoolean/EInt/ELong/EFloat/EDouble/EShort/EByte correspond to\n * Java's `boolean`/`int`/`long`/`float`/`double`/`short`/`byte` (never\n * null, always has a real default) - EBooleanObject/EIntegerObject/etc.\n * are the wrapper counterparts (can be null/absent) and are NOT included\n * here. EString is deliberately excluded too: `String` has no primitive\n * counterpart in Java at all, unlike the numeric/boolean types.\n *\n * Only EBoolean/EInt/EFloat/EDouble were named explicitly in the request\n * that added this; ELong/EShort/EByte were added here for consistency\n * with the same underlying Java primitive-vs-wrapper reasoning - flagged\n * as an interpretive extension, not a literal instruction.\n */\nconst PRIMITIVE_VALUE_DATATYPE_NAMES = new Set(['EBoolean', 'EInt', 'ELong', 'EFloat', 'EDouble', 'EShort', 'EByte']);\n\nexport function isPrimitiveValueType(classifier: EClassifier | undefined): boolean {\n return (\n classifier !== undefined && isEDataType(classifier) && PRIMITIVE_VALUE_DATATYPE_NAMES.has(classifier.getName()!)\n );\n}\n\n/**\n * The feature's own declared `defaultValueLiteral` when it has one (e.g. `changeable`'s real\n * declared default is \"true\", not the generic zero-default) - otherwise 'false' for EBoolean, '0' for\n * every other primitive numeric EDataType (the real Java-primitive zero-default). Used as a stored\n * field's initial value instead of `undefined`.\n */\nexport function primitiveDefaultValue(feature: ETypedElement): string {\n const literal =\n 'getDefaultValueLiteral' in feature ? (feature as EStructuralFeature).getDefaultValueLiteral() : undefined;\n if (literal !== undefined && literal !== '') return literal;\n const classifier = feature.getEType();\n return classifier?.getName() === 'EBoolean' ? 'false' : '0';\n}\n\n/**\n * A feature's scalar TypeScript type, with \" | undefined\" appended UNLESS\n * the type is one of the real JS-primitive-with-a-zero-value EDataTypes\n * (see isPrimitiveValueType) - those never need the union, since a\n * generated field for one always has a real value (the zero-default),\n * never a genuine absence. Prefer this over manually appending\n * \" | undefined\" to tsScalarType()'s result in a template, so the\n * primitive-type exception lives in one place.\n */\nexport function tsOptionalScalarType(type: EClassifier | ETypedElement | undefined): string {\n const scalar = tsScalarType(type);\n const classifier = type !== undefined && isTypedElement(type) ? type.getEType() : type;\n if (classifier && isPrimitiveValueType(classifier)) return scalar;\n // `unknown | undefined` is just `unknown` - already includes \"unset\".\n if (scalar === 'unknown') return scalar;\n return `${scalar} | undefined`;\n}\n\n/**\n * \"getTitle\" or, for a single-valued EBoolean attribute specifically,\n * \"isPublished\" - matching the common convention (real EMF does this too,\n * gated on the same isMany()===false && type===EBoolean condition).\n * Deliberately does NOT affect many-valued features (an EList<boolean>\n * has no sensible \"isX\" reading) or the setter (which stays \"setX\"\n * regardless - only asked for the getter to change).\n */\nexport function beanGetterName(feature: EStructuralFeature): string {\n const type = feature.getEType();\n if (!feature.isMany() && type && type.getName() === 'EBoolean') {\n return `is${ucfirst(feature.getName()!)}`;\n }\n return `get${ucfirst(feature.getName()!)}`;\n}\n\n/** The full TypeScript type for a feature's getter/setter, including EList<T> for many-valued features. */\nexport function tsFeatureType(feature: ETypedElement): string {\n const scalar = tsScalarType(feature);\n if ('isMany' in feature && (feature as { isMany(): boolean }).isMany()) {\n return `EList<${scalar}>`;\n }\n return scalar;\n}\n\n/** Whether a single-valued feature's getter/setter type should be nullable (unset is a real possibility). */\nexport function isOptional(feature: EStructuralFeature): boolean {\n return !feature.isRequired();\n}\n\nexport function isEClass(classifier: EClassifier): classifier is EClass {\n return 'getEStructuralFeatures' in classifier;\n}\n\nexport function isEEnum(classifier: EClassifier): classifier is EEnum {\n return 'getELiterals' in classifier;\n}\n\nexport function isEDataType(classifier: EClassifier): classifier is EDataType {\n return !isEClass(classifier) && !isEEnum(classifier);\n}\n\nexport function isEReference(feature: EStructuralFeature): boolean {\n return 'isContainment' in feature;\n}\n\n/** \"name: Type, name2: Type2\" for an operation's parameter list. */\nexport function paramList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => `${p.getName()}: ${tsFeatureType(p)}`)\n .join(', ');\n}\n\n/** Like paramList, but every parameter is optional (\"name?: type\") - for the merged implementation signature of an auto-resolved overload set (see metaclassAccessorCollision). */\nexport function optionalParamList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => `${p.getName()}?: ${tsFeatureType(p)}`)\n .join(', ');\n}\n\n/** \"name, name2\" - just the argument names, e.g. for a super-call passthrough. */\nexport function argList(operation: EOperation): string {\n return operation\n .getEParameters()\n .toArray()\n .map((p) => p.getName())\n .join(', ');\n}\n\n/**\n * Groups a class's own operations by name, preserving first-seen order -\n * needed because real Ecore.ecore has genuine overloaded operations\n * (EEnum.getEEnumLiteral, by name and by value) and a TS class can only\n * have ONE method body per name, unlike an interface, which supports\n * overloads natively (so only the impl side needs this grouping, not the\n * types/ interface side - see the loop in eclass.njk). Scoped to\n * same-arity overloads only, matching what real Ecore.ecore actually\n * has - a genuine arity mismatch within one name is not handled (see\n * NOTES.md).\n */\nexport function groupOperationsByName(operations: Iterable<EOperation>): EOperation[][] {\n const groups = new Map<string, EOperation[]>();\n for (const op of operations) {\n const list = groups.get(op.getName()!);\n if (list) list.push(op);\n else groups.set(op.getName()!, [op]);\n }\n return [...groups.values()];\n}\n\n/** \"name\" if every name in `names` is identical, otherwise \"nameOrValueOrEtc\" - used to synthesize a merged parameter name for an overload group. */\nfunction mergeNames(names: string[]): string {\n const unique = [...new Set(names)];\n return (\n unique[0] +\n unique\n .slice(1)\n .map((n) => `Or${ucfirst(n)}`)\n .join('')\n );\n}\n\ninterface MergedParam {\n name: string;\n type: string;\n /** Present in only some of the overloads - so optional in the implementation signature. */\n optional: boolean;\n}\n\n/**\n * The implementation signature's parameters for a group of same-named\n * operations, one per position up to the LONGEST overload: each position's\n * type is the union of every overload's type there (among the overloads\n * that have that position), and its name is synthesized via mergeNames()\n * when they used different names (getEEnumLiteral(name)/getEEnumLiteral(value)\n * merges to \"nameOrValue\"). A position not every overload has is optional -\n * positions are prefixes, so the required ones always come first.\n */\nfunction mergedParams(group: EOperation[]): MergedParam[] {\n const arity = Math.max(...group.map((op) => op.getEParameters().size()));\n const params: MergedParam[] = [];\n for (let i = 0; i < arity; i++) {\n const having = group.filter((op) => op.getEParameters().size() > i);\n params.push({\n name: mergeNames(having.map((op) => op.getEParameters().get(i)!.getName()!)),\n type: [...new Set(having.map((op) => tsFeatureType(op.getEParameters().get(i)!)))].join(' | '),\n optional: having.length < group.length,\n });\n }\n return params;\n}\n\n/**\n * The merged implementation signature's parameter list for a group of\n * same-named operations (see mergedParams; different arities included).\n * For a group of exactly one operation, this is identical to paramList().\n */\nexport function mergedParamList(group: EOperation[]): string {\n const first = group[0]!;\n if (group.length === 1) return paramList(first);\n return mergedParams(group)\n .map((p) => `${p.name}${p.optional ? '?' : ''}: ${p.type}`)\n .join(', ');\n}\n\nexport interface OverloadBranch {\n operation: EOperation;\n /** The TypeScript condition that selects this overload. */\n condition: string;\n /** The overload's body (layered, see operationBody), or undefined -> the branch throws its own \"no body\" error. */\n body: string | undefined;\n /** `const <own name> = <merged name> as <own type>;` for each of the overload's own parameter names its body actually uses. */\n aliases: string[];\n /** e.g. \"EClass.getEStructuralFeature(featureID)\", for error messages. */\n label: string;\n}\n\nexport interface OverloadDispatch {\n /** Set when the group is NOT dispatched: the whole implementation is one throwing stub with this message. */\n stubMessage?: string;\n branches: OverloadBranch[];\n}\n\n/**\n * Runtime-testable TypeScript primitive: `typeof x === 'string'` and so\n * on. This is knowledge about TypeScript itself, not about any Ecore\n * datatype - what the parameter's resolved TS TEXT is, is still decided by\n * the model. Anything else (a generated interface, a many-valued\n * parameter, a compound type) has no runtime test.\n */\nfunction primitiveTest(name: string, tsText: string): string | undefined {\n return ['string', 'number', 'boolean', 'bigint'].includes(tsText) ? `typeof ${name} === '${tsText}'` : undefined;\n}\n\n/**\n * `source` with string literals and comments blanked out, so that finding\n * an identifier in it means USING it: 'by-name:' is not a use of `name`.\n * The expressions inside a template literal's `${...}` are code and are kept.\n */\nfunction codeOnly(source: string): string {\n let out = '';\n let i = 0;\n const n = source.length;\n while (i < n) {\n const c = source[i]!;\n const next = source[i + 1];\n if (c === '/' && next === '/') {\n while (i < n && source[i] !== '\\n') i++;\n } else if (c === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2);\n i = end === -1 ? n : end + 2;\n } else if (c === \"'\" || c === '\"') {\n i++;\n while (i < n && source[i] !== c) i += source[i] === '\\\\' ? 2 : 1;\n i++;\n out += ' ';\n } else if (c === '`') {\n i++;\n while (i < n && source[i] !== '`') {\n if (source[i] === '\\\\') i += 2;\n else if (source[i] === '$' && source[i + 1] === '{') {\n let depth = 1;\n i += 2;\n while (i < n && depth > 0) {\n if (source[i] === '{') depth++;\n else if (source[i] === '}') depth--;\n if (depth > 0) out += source[i];\n i++;\n }\n out += ' ';\n } else i++;\n }\n i++;\n out += ' ';\n } else {\n out += c;\n i++;\n }\n }\n return out;\n}\n\nconst escapeForSingleQuotes = (text: string) => text.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n\n/**\n * How the implementation of an overload group selects the overload to\n * run. Per overload, in order:\n *\n * 1. an explicit `dispatch` detail on the overload's annotation with\n * source https://typemf.dev/generator, used as written (a condition\n * over the MERGED parameter names) - for cases the derivation cannot\n * handle;\n * 2. otherwise a condition derived from the parameters, combined with &&,\n * for each position: a position the overload does not have must be\n * `=== undefined`; where the overloads having the position differ in\n * type, the overload's own type must be a runtime-testable primitive\n * (`typeof x === 'string'`); where the type is the same everywhere but\n * the position is optional, `!== undefined`.\n *\n * The group is NOT dispatched - the implementation stays a single\n * throwing stub whose message says why - when no overload has a body,\n * when a needed test cannot be derived and no explicit condition was\n * given, or when two overloads end up with the same condition (they could\n * never be told apart, so the second would be unreachable).\n */\nexport function overloadDispatch(group: EOperation[], className: string): OverloadDispatch {\n const name = group[0]!.getName();\n const stub = (why: string): OverloadDispatch => ({\n branches: [],\n stubMessage: escapeForSingleQuotes(`${className}.${name}() is overloaded and ${why} - nothing to generate.`),\n });\n\n if (!group.some((op) => operationBody(op) !== undefined))\n return stub('none of its overloads has a `body` annotation');\n\n const merged = mergedParams(group);\n const branches: OverloadBranch[] = [];\n\n for (const op of group) {\n const params = [...op.getEParameters()];\n const label = `${className}.${name}(${params.map((p) => p.getName()).join(', ')})`;\n\n const dispatchDetails = op.getEAnnotation(TYPEMF_GENERATOR_ANNOTATION_SOURCE)?.getDetails();\n let condition = dispatchDetails && detailValue(dispatchDetails, 'dispatch');\n if (condition === undefined || condition === '') {\n const parts: string[] = [];\n for (let i = 0; i < merged.length; i++) {\n const m = merged[i]!;\n const own = params[i];\n if (own === undefined) {\n parts.push(`${m.name} === undefined`);\n continue;\n }\n const havingTypes = new Set(\n group.filter((o) => o.getEParameters().size() > i).map((o) => tsFeatureType(o.getEParameters().get(i)!))\n );\n if (havingTypes.size > 1) {\n const test = 'isMany' in own && own.isMany() ? undefined : primitiveTest(m.name, tsScalarType(own));\n if (test === undefined) {\n return stub(\n `cannot be dispatched: the parameter \\`${own.getName()}\\` of ${label} has type ${tsFeatureType(own)}, ` +\n 'which has no runtime test - add a `dispatch` detail to the overload'\n );\n }\n parts.push(test);\n } else if (m.optional) {\n parts.push(`${m.name} !== undefined`);\n }\n }\n condition = parts.join(' && ');\n }\n\n const body = operationBody(op);\n const code = body === undefined ? '' : codeOnly(body);\n const aliases =\n body === undefined\n ? []\n : params.flatMap((p, i) => {\n const merged_i = merged[i]!;\n const own = p.getName()!;\n return own !== merged_i.name && new RegExp(`(?<![\\\\w$])${own.replace(/[$]/g, '\\\\$')}(?![\\\\w$])`).test(code)\n ? [`const ${own} = ${merged_i.name} as ${tsFeatureType(p)};`]\n : [];\n });\n branches.push({ operation: op, condition, body, aliases, label });\n }\n\n const seen = new Map<string, string>();\n for (const b of branches) {\n const earlier = seen.get(b.condition);\n if (earlier !== undefined || b.condition === '') {\n return stub(\n `cannot be dispatched: ${earlier ?? b.label} and ${b.label} have the same dispatch condition ` +\n `(${b.condition === '' ? 'none' : b.condition}), so they cannot be told apart at runtime - add a \\`dispatch\\` detail`\n );\n }\n seen.set(b.condition, b.label);\n }\n return { branches };\n}\n\n/**\n * An operation's return type, with \" | undefined\" appended only if its\n * OWN declared multiplicity says the result may genuinely be absent\n * (not required - lowerBound < 1) - unlike tsOptionalScalarType() (used\n * for structural features' getters), which appends it unconditionally\n * for every non-primitive type. Operations need this per-operation check\n * instead of a blanket rule: most operations (isSuperTypeOf(): boolean,\n * getClassifierID(): number, ...) are genuinely never-null by their own\n * declared multiplicity, and blanket-appending | undefined to every one\n * of them would be wrong - unlike structural features, where treating\n * every single-valued reference as \"may be unset\" is the reasonable\n * default.\n *\n * This is the fix for a real, confirmed gap: real Ecore.ecore's own\n * EModelElement.getEAnnotation(source) has no declared lowerBound (real\n * EMF's default there is 0 - not required), meaning the operation is\n * genuinely allowed to return nothing when no annotation with that\n * source is attached - but the generator previously always emitted the\n * bare, non-optional return type for every operation regardless.\n */\nexport function tsOperationReturnType(op: EOperation): string {\n const scalar = tsScalarType(op);\n if (isPrimitiveValueType(op.getEType())) return scalar;\n if (op.isRequired()) return scalar;\n if (scalar === 'unknown') return scalar; // `unknown | undefined` is just `unknown`\n return `${scalar} | undefined`;\n}\n\n/** The merged implementation signature's return type for a group - the union of every overload's OWN (possibly optional) return type via tsOperationReturnType(), deduplicated (so an all-identical group collapses to just that one type, not a redundant self-union). */\nexport function mergedReturnType(group: EOperation[]): string {\n return [...new Set(group.map((op) => tsOperationReturnType(op)))].join(' | ');\n}\n\n/**\n * Uppercases only the first character, leaving the rest untouched -\n * NOT the same as Nunjucks' built-in `capitalize` filter, which mirrors\n * Jinja2's and lowercases everything after the first letter (breaking any\n * camelCase name: \"pageCount\" -> \"Pagecount\"). Used to build bean-style\n * accessor names (\"pageCount\" -> \"getPageCount\") without corrupting them.\n */\nexport function ucfirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** The generated Package singleton class name for a package, e.g. \"library\" -> \"LibraryPackage\". */\nexport function packageClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Package`;\n}\n\nexport function factoryClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Factory`;\n}\n\nexport function switchClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}Switch`;\n}\n\nexport function typeGuardsClassName(pkg: EPackage): string {\n return `${ucfirst(pkg.getName()!)}TypeGuards`;\n}\n\n/** The EClass's single supertype for TS `extends` purposes, or undefined - see NOTES.md on multiple inheritance. */\nexport function superType(eClass: EClass): EClass | undefined {\n const supers = eClass.getESuperTypes();\n return supers.size() > 0 ? supers.get(0) : undefined;\n}\n\n/** eClass itself, then each ancestor in turn (via superType()), nearest first. */\nexport function superTypeChain(eClass: EClass): EClass[] {\n const chain: EClass[] = [eClass];\n let current = superType(eClass);\n while (current) {\n chain.push(current);\n current = superType(current);\n }\n return chain;\n}\n\n/**\n * Whether this class descends from (or is) \"EClassifier\" - needed\n * specifically for self-hosting Ecore.ecore: classifierID is internal\n * dispatch bookkeeping, not a real modeled Ecore feature, so it's never\n * emitted by the ordinary feature-driven getter/setter generation - but\n * bootstrap code constructing the metamodel's own classifier shells\n * (which ARE real EClassifier-derived instances, e.g. EClassImpl,\n * EDataTypeImpl) genuinely needs to set it. Confirmed as a real,\n * necessary gap by actually running self-hosted bootstrap code, not\n * assumed - see NOTES.md.\n */\nexport function isClassifierDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EClassifier');\n}\n\n/** The featureID analog of isClassifierDerived() - same reasoning, same real gap found the same way (see NOTES.md). */\nexport function isStructuralFeatureDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EStructuralFeature');\n}\n\n/** The operationID analog of isClassifierDerived()/isStructuralFeatureDerived() - added for point 4. */\nexport function isOperationDerived(eClass: EClass): boolean {\n return superTypeChain(eClass).some((c) => c.getName() === 'EOperation');\n}\n\n/**\n * Whether a real EOperation's name collides with a hand-added bookkeeping\n * method (classifierID/featureID - see isClassifierDerived/\n * isStructuralFeatureDerived's own doc comments). Real Ecore.ecore\n * genuinely declares both \"EClassifier.getClassifierID(): EInt\" and\n * \"EStructuralFeature.getFeatureID(): EInt\" as real, zero-arg operations\n * - colliding, by name, with exactly the bookkeeping getters added for\n * the self-hosting bootstrap fix. Confirmed directly against the real\n * file before excluding these operations from the generic,\n * throwing-stub-generating operation loop, not assumed - see NOTES.md.\n */\nexport function isBookkeepingOperation(op: EOperation, eClass: EClass): boolean {\n if (op.getName() === 'getClassifierID' && op.getEParameters().isEmpty() && isClassifierDerived(eClass)) return true;\n if (op.getName() === 'getFeatureID' && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))\n return true;\n if (op.getName() === 'getOperationID' && op.getEParameters().isEmpty() && isOperationDerived(eClass)) return true;\n if (op.getName() === 'getContainerClass' && op.getEParameters().isEmpty() && isStructuralFeatureDerived(eClass))\n return true;\n return false;\n}\n\n/**\n * Whether classifier `classifierName`'s zero-arg metaclass accessor\n * (get{ClassifierName}(), generated directly on the package class for\n * every classifier the package declares) collides with a real EOperation\n * inherited by the package class from one of ITS OWN ancestors. Only\n * relevant when self-hosting - \"EPackage\" (the package class's own\n * superclass) is itself one of the metamodel's declared classifiers only\n * in that case; an ordinary metamodel never has this situation at all,\n * so this always returns undefined for one.\n *\n * General by design, not hardcoded to specific names: real Ecore.ecore\n * happens to have exactly two instances of this shape\n * (EModelElement.getEAnnotation(source), EPackage.getEClassifier(name)),\n * found by a systematic scan across every classifier's own+inherited\n * generated members, not by inspection - confirmed nothing else in the\n * real file collides this way (or any other way) - see NOTES.md. This\n * function exists so the SAME resolution automatically covers any future\n * metamodel with a classifier sharing a name with one of the package\n * class's own inherited operations, without needing another hardcoded\n * exclusion added by hand each time one is found.\n */\nexport function metaclassAccessorCollision(classifierName: string, pkg: EPackage): EOperation | undefined {\n const ePackageClassifier = [...pkg.getEClassifiers()].find((c) => c.getName() === 'EPackage' && isEClass(c));\n if (!ePackageClassifier) return undefined;\n const accessorName = 'get' + classifierName;\n for (const ancestor of superTypeChain(ePackageClassifier as EClass)) {\n for (const op of ancestor.getEOperations()) {\n if (op.getName() === accessorName) return op;\n }\n }\n return undefined;\n}\n\n/**\n * Distinct, non-primitive classifier names referenced by any metaclass-\n * accessor collision's own signature (return type or parameter types) in\n * `pkg` - needed for {Pkg}Package.ts's own import line, general rather\n * than hardcoding \"EAnnotation\" (real Ecore.ecore's one actual instance\n * today): a future metamodel's own colliding operation could return or\n * accept any classifier at all.\n */\nexport function metaclassAccessorCollisionTypeNames(pkg: EPackage): string[] {\n const names = new Set<string>();\n const maybeAdd = (type: EClassifier | undefined) => {\n if (type && (isEClass(type) || isEEnum(type))) names.add(type.getName()!);\n };\n for (const classifier of pkg.getEClassifiers()) {\n const collision = metaclassAccessorCollision(classifier.getName()!, pkg);\n if (!collision) continue;\n maybeAdd(collision.getEType());\n for (const param of collision.getEParameters()) maybeAdd(param.getEType());\n }\n return [...names];\n}\n\n/**\n * A general validation pass, meant to run during generation (not just as\n * a one-off diagnostic): for every classifier in `pkg`, checks every name\n * that would be generated as one of its members - own or inherited bean\n * accessors, real operations, bookkeeping methods (classifierID/\n * featureID), and (for the package class specifically) metaclass\n * accessors - for a collision with something else generated under the\n * same name, EXCLUDING the two patterns the generator already resolves\n * correctly on its own (isBookkeepingOperation's exclusion, and\n * metaclassAccessorCollision's automatic overload-set generation).\n * Anything left over is a genuine, unhandled collision that would\n * silently produce wrong runtime behaviour (the later declaration wins,\n * no compile error) - generation should refuse to proceed rather than\n * emit it silently.\n *\n * Deliberately reuses the same real helpers the templates themselves\n * use (isBookkeepingOperation, groupOperationsByName, beanGetterName,\n * metaclassAccessorCollision) rather than a parallel reimplementation,\n * so this can never silently drift out of sync with what actually gets\n * generated.\n */\nexport interface MemberCollision {\n classifierName: string;\n memberName: string;\n sources: string[];\n}\n\n/**\n * Every classifier, feature, operation, parameter, and enum literal in `pkg` genuinely needs a name -\n * code generation cannot produce a meaningful `class {name} {}`/`get{name}()`/etc. for one that has\n * none (real Ecore.ecore's own `name` attribute is optional, matching real EMF, so this is a real,\n * reachable state, not a hypothetical one). Checked once, up front, via the same validate() hook every\n * other model-level problem goes through - so every OTHER function in this file can safely assert a\n * name is present (`!`) rather than re-checking it at every one of the many call sites that need one,\n * confident generate() would have already refused to run otherwise.\n */\nexport function findUnnamedElements(pkg: EPackage): string[] {\n const problems: string[] = [];\n const check = (element: { getName(): string | undefined }, kind: string, where: string): void => {\n if (element.getName() === undefined) problems.push(`${where}: a ${kind} with no name`);\n };\n for (const classifier of pkg.getEClassifiers()) {\n check(classifier, 'classifier', pkg.getName() ?? '(this package)');\n if (isEClass(classifier)) {\n for (const feature of classifier.getEStructuralFeatures())\n check(feature, 'feature', classifier.getName() ?? '(unnamed classifier)');\n for (const op of classifier.getEOperations()) {\n check(op, 'operation', classifier.getName() ?? '(unnamed classifier)');\n for (const param of op.getEParameters())\n check(\n param,\n 'parameter',\n `${classifier.getName() ?? '(unnamed classifier)'}.${op.getName() ?? '(unnamed operation)'}`\n );\n }\n } else if (isEEnum(classifier)) {\n for (const literal of classifier.getELiterals())\n check(literal, 'enum literal', classifier.getName() ?? '(unnamed classifier)');\n }\n }\n return problems;\n}\n\nexport function findUnresolvedCollisions(pkg: EPackage): MemberCollision[] {\n const packageClassifierName = 'EPackage';\n const isSelfHosting = [...pkg.getEClassifiers()].some((c) => c.getName() === packageClassifierName && isEClass(c));\n const classifiers = [...pkg.getEClassifiers()].filter(isEClass);\n const results: MemberCollision[] = [];\n\n function scan(chainRoot: EClass, label: string, extra: Array<[string, string]>): void {\n const chain = superTypeChain(chainRoot);\n const byName = new Map<string, string[]>();\n const add = (name: string, source: string) => {\n if (!byName.has(name)) byName.set(name, []);\n byName.get(name)!.push(source);\n };\n\n for (const [name, source] of extra) add(name, source);\n\n for (const anc of chain) {\n const ancName = anc.getName()!;\n for (const f of anc.getEStructuralFeatures()) {\n add(beanGetterName(f), `${ancName}.${f.getName()} getter`);\n if (!f.isMany()) {\n add('set' + f.getName()![0]!.toUpperCase() + f.getName()!.slice(1), `${ancName}.${f.getName()} setter`);\n }\n }\n for (const group of groupOperationsByName(anc.getEOperations())) {\n const op = group[0]!;\n if (isBookkeepingOperation(op, anc)) continue; // already correctly excluded from generation\n add(op.getName()!, `${ancName}.${op.getName()} operation`);\n }\n if (isClassifierDerived(anc) && ancName === 'EClassifier') {\n add('getClassifierID', `${ancName} bookkeeping`);\n add('setClassifierID', `${ancName} bookkeeping`);\n }\n if (isStructuralFeatureDerived(anc) && ancName === 'EStructuralFeature') {\n add('getFeatureID', `${ancName} bookkeeping`);\n add('setFeatureID', `${ancName} bookkeeping`);\n }\n }\n\n for (const [name, sources] of byName) {\n if (sources.length > 1) {\n results.push({ classifierName: label, memberName: name, sources });\n }\n }\n }\n\n for (const c of classifiers) {\n scan(c, c.getName()!, []);\n }\n\n if (isSelfHosting) {\n // EcorePackage (the synthetic, generated package class) is never\n // itself one of pkg.getEClassifiers() - it extends the real \"EPackage\"\n // classifier, plus has its own metaclass accessors (one per\n // classifier the package declares), auto-resolved by\n // metaclassAccessorCollision where a real inherited operation exists.\n const ePackageClassifier = classifiers.find((c) => c.getName() === packageClassifierName)!;\n const ownAccessors: Array<[string, string]> = [];\n for (const classifier of pkg.getEClassifiers()) {\n if (metaclassAccessorCollision(classifier.getName()!, pkg)) continue; // already auto-resolved\n ownAccessors.push(['get' + classifier.getName(), `EcorePackage.get${classifier.getName()} metaclass accessor`]);\n }\n scan(ePackageClassifier, 'EcorePackage', ownAccessors);\n }\n\n return results;\n}\n\n/**\n * Distinct EClass/EEnum type names referenced by `features` (an EClass or\n * EEnum's own attribute/reference types) that need their own import\n * statement - EDataType primitives (string/number/boolean/Date) never do.\n * A TS helper rather than a Nunjucks loop with manual dedup, since\n * template-level array mutation is awkward without extra Nunjucks\n * extensions - matches the \"templates handle structure, TS computes\"\n * principle.\n */\nexport function referencedApiTypes(features: Iterable<EStructuralFeature>, ...excludeTypeNames: string[]): string[] {\n const exclude = new Set(excludeTypeNames);\n const names = new Set<string>();\n for (const feature of features) {\n const type = feature.getEType();\n if (type && (isEReference(feature) || isEEnum(type)) && !exclude.has(type.getName()!)) names.add(type.getName()!);\n // Classes/enums bound inside type arguments need importing too.\n for (const argument of genericArgumentClassifiers(feature.getEGenericType())) {\n if ((isEClass(argument) || isEEnum(argument)) && !exclude.has(argument.getName()!))\n names.add(argument.getName()!);\n }\n }\n return [...names];\n}\n\n/**\n * The operation-scoped analog of referencedApiTypes, for the identical\n * \"needs its own import statement\" reason - but operations weren't\n * scanned by anything at all before this existed, a genuine gap: an\n * operation's return type or any parameter's type can be any classifier,\n * including a non-primitive EDataType (real Ecore.ecore's own\n * EClassifier.getContainerClass(): EJavaClass, for one) - unlike\n * features, where only EClass/EEnum ever need an import (a plain\n * EDataType-typed feature is always one of the handful of TS-primitive-\n * mapped names). Confirmed as a real, previously-missing import by\n * actually generating real Ecore.ecore and type-checking the merged\n * output, not assumed - see NOTES.md.\n */\nexport function referencedOperationTypes(operations: Iterable<EOperation>, ...excludeTypeNames: string[]): string[] {\n const exclude = new Set(excludeTypeNames);\n const names = new Set<string>();\n const maybeAdd = (type: EClassifier | undefined) => {\n if (type && (isEClass(type) || isEEnum(type)) && !exclude.has(type.getName()!)) {\n names.add(type.getName()!);\n }\n };\n for (const op of operations) {\n maybeAdd(op.getEType());\n for (const argument of genericArgumentClassifiers(op.getEGenericType())) maybeAdd(argument);\n for (const param of op.getEParameters()) {\n maybeAdd(param.getEType());\n for (const argument of genericArgumentClassifiers(param.getEGenericType())) maybeAdd(argument);\n }\n }\n return [...names];\n}\n\n/**\n * Nunjucks 3.2.4 silently does not support Jinja2's inline `{% for x in y\n * if cond %}` for-loop filter syntax (it parses without error but produces\n * wrong output - verified empirically, not assumed) - these pre-filtered\n * helpers replace every case a template would otherwise want that syntax\n * for, consistent with keeping templates dumb.\n */\n/**\n * Safely emits a metamodel-supplied string as a TypeScript string literal,\n * via JSON.stringify() - handles quotes, apostrophes, newlines, backslashes,\n * anything. Every place a template interpolates a name/label/annotation\n * value from the metamodel into generated source needs this, not naive\n * single-quote wrapping - annotation `details` values in particular are\n * often free-form prose (GenModel documentation, validation constraint\n * text) and are genuinely likely to contain apostrophes or multi-line\n * text, which naive interpolation would turn into broken generated code.\n */\nexport function jsString(value: string | undefined): string {\n if (value === undefined) {\n throw new Error(\n 'jsString() received undefined - this means required metamodel data (a name, nsURI, nsPrefix, or ' +\n 'annotation value) is missing on the source EPackage. JSON.stringify(undefined) is not a string, so ' +\n 'this would otherwise silently emit an empty/malformed argument into generated code rather than ' +\n 'failing clearly at generation time.'\n );\n }\n return JSON.stringify(value);\n}\n\n/**\n * Nunjucks' {% for %} reliably iterates plain objects and arrays, but not\n * necessarily a real ES6 Map instance the same way (its object-iteration\n * path likely uses Object.keys(), which is empty for a Map's own\n * enumerable properties - the entries live internally, not as own\n * properties). Converting to a plain array here avoids relying on\n * behavior that was never actually verified.\n */\nexport function detailsEntries(annotation: EAnnotation): { key: string; value: string }[] {\n return [...annotation.getDetails()].map((entry) => ({ key: entry.getKey() ?? '', value: entry.getValue() ?? '' }));\n}\n\nexport function eClassesOf(pkg: EPackage): EClass[] {\n return pkg\n .getEClassifiers()\n .toArray()\n .filter((c): c is EClass => isEClass(c) && c.getName() !== 'EObject');\n}\n\nexport function concreteEClassesOf(pkg: EPackage): EClass[] {\n return eClassesOf(pkg).filter((c) => !c.isAbstract());\n}\n\n/**\n * Finds an EClass by exact name within the package, or undefined if none\n * matches - used specifically for the EFactory/{Pkg}Factory unification\n * special case (see efactory.njk): when a metamodel models a classifier\n * literally named \"EFactory\" (as real Ecore.ecore does), the package-level\n * generated Factory extends ITS generated impl instead of the generic\n * @typemf/core EFactoryImpl base, matching real EMF's own\n * EcoreFactoryImpl-extends-EFactoryImpl design. Ordinary metamodels (no\n * \"EFactory\" classifier) are unaffected.\n */\nexport function findEClassByName(pkg: EPackage, name: string): EClass | undefined {\n return eClassesOf(pkg).find((c) => c.getName() === name);\n}\n\nexport function singleValuedFeatures(features: Iterable<EStructuralFeature>): EStructuralFeature[] {\n return [...features].filter((f) => !f.isMany());\n}\n","import { TemplateSet } from './template-set.js';\nimport { typescriptTemplateSet } from './typescript-template-set.js';\n\nconst builtinTemplateSets: Record<string, TemplateSet> = {\n typescript: typescriptTemplateSet,\n};\n\n/**\n * Resolves a config file's \"templateSet\" name string to a real\n * TemplateSet. Only built-in sets are known here for now - a third-party\n * set (e.g. a Java one) would need its own registration mechanism, not yet\n * built; see NOTES.md.\n */\nexport function resolveTemplateSet(name: string): TemplateSet {\n const set = builtinTemplateSets[name];\n if (!set) {\n const known = Object.keys(builtinTemplateSets).join(', ');\n throw new Error(`Unknown template set '${name}'. Known built-in sets: ${known}.`);\n }\n return set;\n}\n"],"mappings":"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","names":["EcorePackageImpl","EAttributeImpl","EClassImpl","EDataTypeImpl","EPackageImpl","EReferenceImpl","EDataTypeImpl","EClassImpl","EAttributeImpl","EReferenceImpl","EPackageImpl","EcorePackageImpl","dirname","join","detailValue","isEClass","byName","isEClass","join","dirname"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typemf/generator",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -30,9 +30,9 @@
30
30
  "provenance": true
31
31
  },
32
32
  "dependencies": {
33
- "@typemf/core": "0.5.1",
34
- "@typemf/node": "0.5.1",
35
- "@typemf/xmi": "0.5.1",
33
+ "@typemf/core": "0.6.0",
34
+ "@typemf/node": "0.6.0",
35
+ "@typemf/xmi": "0.6.0",
36
36
  "nunjucks": "^3.2.4",
37
37
  "prettier": "^3.9.8"
38
38
  },