@ts-for-gir/lib
Version:
Typescript .d.ts generator from GIR for gjs
130 lines (100 loc) • 3.6 kB
text/typescript
import type { FormatGenerator } from "../generators/generator.ts";
import { NumberType, TypeIdentifier } from "../gir.ts";
import type { GirBitfieldElement, GirEnumElement } from "../index.ts";
import type { OptionsLoad } from "../types/index.ts";
import { parseDoc, parseMetadata } from "../utils/gir-parsing.ts";
import { sanitizeIdentifierName, sanitizeMemberName } from "../utils/naming.ts";
import type { GirVisitor } from "../visitor.ts";
import { GirEnumMember } from "./enum-member.ts";
import { GirComplexRecord } from "./gir-complex-record.ts";
import { IntrospectedNamespaceMember } from "./introspected-namespace-member.ts";
import type { IntrospectedNamespace } from "./namespace.ts";
import { IntrospectedField } from "./property.ts";
import type { IntrospectedRecord } from "./record.ts";
export class IntrospectedEnum extends IntrospectedNamespaceMember {
members = new Map<string, GirEnumMember>();
isRegistered: boolean = false;
flags: boolean = false;
ns: IntrospectedNamespace;
constructor(name: string, namespace: IntrospectedNamespace, options: { isIntrospectable?: boolean } = {}) {
super(sanitizeIdentifierName(namespace.namespace, name), namespace, options);
this.ns = namespace;
}
copy({ members }: { parent?: undefined; members?: Map<string, GirEnumMember> } = {}): IntrospectedEnum {
const { namespace, name, isRegistered, flags } = this;
const en = new IntrospectedEnum(name, namespace);
for (const [key, member] of (members ?? this.members).entries()) {
en.members.set(key, member.copy());
}
en.isRegistered = isRegistered;
en.flags = flags;
en._copyBaseProperties(this);
return en;
}
accept(visitor: GirVisitor): IntrospectedEnum {
const node = this.copy({
members: new Map(
Array.from(this.members.entries()).map(([name, m]) => {
return [name, m.accept(visitor)];
}),
),
});
return visitor.visitEnum?.(node) ?? node;
}
getType(): TypeIdentifier {
return new TypeIdentifier(this.name, this.ns.namespace);
}
asString<T extends FormatGenerator<unknown>>(generator: T): ReturnType<T["generateEnum"]> {
return generator.generateEnum(this) as ReturnType<T["generateEnum"]>;
}
asClass(): IntrospectedRecord {
const { name, namespace, doc } = this;
const clazz = new GirComplexRecord({ name, namespace, doc });
clazz.fields.push(
...Array.from(this.members.values()).map((m) => {
const field = new IntrospectedField({
name: m.name,
parent: clazz,
type: NumberType,
writable: true,
isStatic: true,
});
field.doc = m.doc;
field.metadata = m.metadata;
return field;
}),
);
clazz.members = [];
return clazz;
}
static fromXML(
element: GirEnumElement | GirBitfieldElement,
ns: IntrospectedNamespace,
options: OptionsLoad,
flags = false,
): IntrospectedEnum {
const em = new IntrospectedEnum(sanitizeMemberName(element.$.name), ns);
if (element.$["glib:type-name"]) {
em.isRegistered = true;
em.resolve_names.push(element.$["glib:type-name"]);
ns.registerResolveName(element.$["glib:type-name"], ns.namespace, em.name);
}
if (element.$["c:type"]) {
em.resolve_names.push(element.$["c:type"]);
ns.registerResolveName(element.$["c:type"], ns.namespace, em.name);
}
if (options.loadDocs) {
em.doc = parseDoc(element);
em.metadata = parseMetadata(element);
}
if (!element.member) {
return em;
}
element.member.forEach((m) => {
const member = GirEnumMember.fromXML(m, em, options);
em.members.set(member.name, member);
});
em.flags = flags;
return em;
}
}