-
I'm trying out the new emitter framework, and I'm running into an issue: my target language (Haskell) doesn't support anonymous record/union types, so I need to identify these and generate named type declarations and refer to them. I found some code in const program = await getProgram(`
namespace DemoService;
model Widget extends Record<unknown> {
id: string;
weight: int32;
color: "blue" | "red";
};
`);
// Mutates anonymous types to be named.
const anonymousMutatorRecord: unsafe_MutatorRecord<Model | Union> = {
filter(t) {
return MutatorFlow.MutateAndRecur;
},
mutate(t, clone) {
if (!clone.name) {
clone.name = $.type.getPlausibleName(clone);
}
},
};
const anonymousMutator: Mutator = {
name: "Anonymous types",
Model: anonymousMutatorRecord,
Union: anonymousMutatorRecord,
};
const { realm, type } = mutateSubgraphWithNamespace(
program,
[anonymousMutator],
program.getGlobalNamespaceType(),
);
const models = Array.from((type as Namespace).models.values());
// I expect the named union to show up here, but it is empty
const unions = Array.from((type as Namespace).unions.values()); Is there some additional work needed to access the cloned union type so I can emit it separately from the source model? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I managed to do this with Alloy contexts and no mutation. The context has a function to deanonymize a type: export interface NamespaceContext {
/** Create a clone of [type] with a generated name and return a reference to that type. */
deanonymizeType(type: Model | Union): Refkey;
} And the component implements it like: export function NamespaceDeclaration(props: NamespaceDeclarationProps) {
const additionalTypes: [Refkey, Type][] = reactive([]);
const namespaceContext: NamespaceContext = {
deanonymizeType(type) {
const clone = $.type.clone({ ...type, name: generateName(type) });
const refkey = getRefkey(type);
additionalTypes.push([refkey, clone]);
return refkey;
},
};
return (
<For each={additionalTypes}>
{([refkey, type]) => <TypeDeclaration type={type} refkey={refkey} />}
</For>
);
} |
Beta Was this translation helpful? Give feedback.
I managed to do this with Alloy contexts and no mutation. The context has a function to deanonymize a type:
And the component implements it like: