UNPKG

@ts-for-gir/lib

Version:

Typescript .d.ts generator from GIR for gjs

147 lines 5.68 kB
import { DefaultFormatter } from "../formatters/default.js"; import { JSONFormatter } from "../formatters/json.js"; import { JsonGenerator } from "../generators/json.js"; import { generify } from "../generics/generify.js"; import { inject } from "../injections/inject.js"; import { TwoKeyMap } from "../util.js"; import { ClassVisitor } from "../validators/class.js"; import { InterfaceVisitor } from "../validators/interface.js"; import { DtsModuleGenerator } from "../generators/dts-modules.js"; import { DtsInlineGenerator } from "../generators/dts-inline.js"; import { FunctionParametersVisitor } from "../validators/function-parameters.js"; export class NSRegistry { mapping = new TwoKeyMap(); formatters = new Map(); generators = new Map(); c_mapping = new Map(); transformations = []; subtypes = new TwoKeyMap(); constructor() { this.formatters.set("json", new JSONFormatter()); } registerTransformation(visitor) { this.transformations.push(visitor); // Apply transformations to already built namespaces. this.mapping.forEach(n => { n.accept(visitor); }); } registerFormatter(output, formatter) { this.formatters.set(output, formatter); } getFormatter(output) { return this.formatters.get(output) ?? new DefaultFormatter(); } registerGenerator(output, generator) { this.generators.set(output, generator); } async getGenerator(output) { if (output === "dts") { return DtsModuleGenerator; } if (output === "dts-inline") { return DtsInlineGenerator; } if (output === "json") { return JsonGenerator; } // Handle loading external generators... if (!this.generators.has(output)) { let Generator; try { Generator = (await import(`@gi.ts/generator-${output}`)); if (Generator) { console.log(`Loading generator "@gi.ts/generator-${output}"...`); this.generators.set(output, Generator.default); return; } } catch { try { Generator = (await import(`gi-ts-generator-${output}`)); console.log(`Loading generator "gi-ts-generator-${output}"...`); this.generators.set(output, Generator.default); return; } catch { try { Generator = (await import(`${output}`)); console.log(`Loading generator "${output}"...`); this.generators.set(output, Generator.default); return; } catch { } } } } return this.generators.get(output); } _transformNamespace(namespace) { this.transformations.forEach(t => { namespace.accept(t); }); } namespace(name, version) { const namespace = this.mapping.get(name, version); return namespace ?? null; } namespacesForPrefix(c_prefix) { return (this.c_mapping.get(c_prefix) ?? []).map(c_mapping => this.assertNamespace(c_mapping.name, c_mapping.version)); } transform(options) { const GLib = this.assertNamespace("GLib", "2.0"); const Gio = this.assertNamespace("Gio", "2.0"); const GObject = this.assertNamespace("GObject", "2.0"); // These follow the GLib version. Gio.package_version = [...GLib.package_version]; GObject.package_version = [...GLib.package_version]; const interfaceVisitor = new InterfaceVisitor(); this.registerTransformation(interfaceVisitor); const classVisitor = new ClassVisitor(); this.registerTransformation(classVisitor); const enumParamsVisitor = new FunctionParametersVisitor(); this.registerTransformation(enumParamsVisitor); console.log("Adding generics..."); generify(this, options.inferGenerics); console.log("Injecting types..."); inject(this); } defaultVersionOf(name) { // GJS has a hard dependency on these versions. if (name === "GLib" || name === "Gio" || name === "GObject") { return "2.0"; } const meta = this.mapping.getIfOnly(name); if (meta) { return meta[0]; } return null; } assertDefaultVersionOf(name) { const version = this.defaultVersionOf(name); if (version) { return version; } // This mirrors GJS' and GI's default behavior. // If we can't find a single version of an unspecified dependency, we throw an error. throw new Error(`No single version found for unspecified dependency: ${JSON.stringify(name)}.`); } assertNamespace(name, version) { const namespace = this.mapping.get(name, version) ?? null; if (!namespace) { throw new Error(`Namespace '${name}' not found.`); } return namespace; } register(namespace) { this.mapping.set(namespace.namespace, namespace.version, namespace); namespace.c_prefixes.forEach(c_prefix => { const c_map = this.c_mapping.get(c_prefix) || []; c_map.push({ name: namespace.namespace, version: namespace.version }); this.c_mapping.set(c_prefix, c_map); }); this._transformNamespace(namespace); return namespace; } } //# sourceMappingURL=registry.js.map