UNPKG

@ts-for-gir/lib

Version:

Typescript .d.ts generator from GIR for gjs

208 lines (179 loc) 6.02 kB
import type { IntrospectedNamespace } from "../gir/namespace.ts"; import { GenericType, GenerifiedTypeIdentifier } from "../gir.ts"; import type { StTemplateConfig } from "../types/generics-config.ts"; function createStTemplate(version: string): StTemplateConfig { return { namespace: "St", version, modifier: (namespace: IntrospectedNamespace, inferGenerics: boolean) => { if (!inferGenerics) { return; } applyStGenerics(namespace, version); }, }; } function applyStGenerics(namespace: IntrospectedNamespace, version: string): void { const clutterImport = namespace.assertInstalledImport("Clutter"); const classes = getStClasses(namespace); const clutterClasses = getClutterClasses(clutterImport, version); setupWidgetGenerics(classes, clutterClasses); setupViewportGenerics(classes, clutterClasses); setupContainerGenerics(classes, clutterClasses, version); setupBoxLayout(classes, clutterClasses); setupBinGenerics(classes, clutterClasses); setupScrollViewMethods(classes); } function getStClasses(namespace: IntrospectedNamespace) { return { Bin: namespace.assertClass("Bin"), Button: namespace.assertClass("Button"), ScrollView: namespace.assertClass("ScrollView"), ScrollBar: namespace.assertClass("ScrollBar"), Widget: namespace.assertClass("Widget"), Viewport: namespace.assertClass("Viewport"), StBoxLayout: namespace.assertClass("BoxLayout"), }; } function getClutterClasses(clutterImport: ReturnType<IntrospectedNamespace["assertInstalledImport"]>, version: string) { return { Actor: clutterImport.assertClass("Actor"), Content: clutterImport.assertClass("Content"), Container: Number(version) < 14 ? clutterImport.assertClass("Container") : null, LayoutManager: clutterImport.assertClass("LayoutManager"), ClutterBoxLayout: clutterImport.assertClass("BoxLayout"), }; } function setupWidgetGenerics( stClasses: ReturnType<typeof getStClasses>, clutterClasses: ReturnType<typeof getClutterClasses>, ): void { const { Widget } = stClasses; const { Actor, Content, LayoutManager } = clutterClasses; Widget.addGeneric({ deriveFrom: Actor.getType(), default: LayoutManager.getType(), constraint: LayoutManager.getType(), }); Widget.addGeneric({ deriveFrom: Actor.getType(), default: Content.getType(), constraint: Content.getType(), }); } function setupViewportGenerics( stClasses: ReturnType<typeof getStClasses>, clutterClasses: ReturnType<typeof getClutterClasses>, ): void { const { Viewport, Widget } = stClasses; const { Content, LayoutManager } = clutterClasses; Viewport.addGeneric({ deriveFrom: Widget.getType(), default: LayoutManager.getType(), constraint: LayoutManager.getType(), }); Viewport.addGeneric({ deriveFrom: Widget.getType(), default: Content.getType(), constraint: Content.getType(), }); } function setupContainerGenerics( stClasses: ReturnType<typeof getStClasses>, clutterClasses: ReturnType<typeof getClutterClasses>, _version: string, ): void { const { StBoxLayout } = stClasses; const { Actor, Container } = clutterClasses; if (!Container) { return; } Container.addGeneric({ default: Actor.getType(), constraint: Actor.getType(), }); StBoxLayout.addGeneric({ deriveFrom: Container.getType(), default: Actor.getType(), constraint: Actor.getType(), }); } function setupBoxLayout( stClasses: ReturnType<typeof getStClasses>, clutterClasses: ReturnType<typeof getClutterClasses>, ): void { const { StBoxLayout } = stClasses; const { ClutterBoxLayout } = clutterClasses; if (StBoxLayout.superType) { StBoxLayout.superType = new GenerifiedTypeIdentifier(StBoxLayout.superType.name, StBoxLayout.superType.namespace, [ ClutterBoxLayout.getType(), ]); } } function setupBinGenerics( stClasses: ReturnType<typeof getStClasses>, clutterClasses: ReturnType<typeof getClutterClasses>, ): void { const { Bin, Button, ScrollView } = stClasses; const { Actor } = clutterClasses; Bin.addGeneric({ default: Actor.getType(), constraint: Actor.getType(), }); Button.addGeneric({ deriveFrom: Bin.getType(), default: Actor.getType(), constraint: Actor.getType(), }); ScrollView.addGeneric({ deriveFrom: Bin.getType(), default: Actor.getType(), constraint: Actor.getType(), }); // Update Bin child property updatePropertyType(Bin, ["child"], new GenericType("A", Actor.getType())); } function setupScrollViewMethods(stClasses: ReturnType<typeof getStClasses>): void { const { ScrollView, ScrollBar } = stClasses; const methodConfigs = [ { name: "get_hscroll_bar", returnType: ScrollBar.getType() }, { name: "get_vscroll_bar", returnType: ScrollBar.getType() }, ]; for (const config of methodConfigs) { const method = ScrollView.members.find((member) => member.name === config.name); if (method) { const fixedMethod = method.copy({ returnType: config.returnType }); const index = ScrollView.members.indexOf(method); ScrollView.members.splice(index, 1, fixedMethod); } } } function updatePropertyType( cls: ReturnType<IntrospectedNamespace["assertClass"]>, propertyNames: string[], newType: GenericType, ): void { cls.props .filter((p) => propertyNames.includes(p.name)) .forEach((prop) => { // TODO: Automatically infer such changes. prop.type = newType; }); } // Version exports export const st1 = createStTemplate("1.0"); export const st12 = createStTemplate("12"); export const st13 = createStTemplate("13"); /** St-14 was introduced with GNOME 46 */ export const st14 = createStTemplate("14"); /** St-15 was introduced with GNOME 47 */ export const st15 = createStTemplate("15"); /** St-16 was introduced with GNOME 48 */ export const st16 = createStTemplate("16"); /** St-17 was introduced with GNOME 49 */ export const st17 = createStTemplate("17"); /** St-18 was introduced with GNOME 50 */ export const st18 = createStTemplate("18"); // Possibly future versions, adjust if necessary export const st19 = createStTemplate("19"); export const st20 = createStTemplate("20");