UNPKG

@ts-for-gir/lib

Version:

Typescript .d.ts generator from GIR for gjs

77 lines (61 loc) 2.65 kB
import { BooleanType, ClosureType, makeUnion, PromiseType, TupleType, TypeIdentifier, VoidType } from "../gir.ts"; import type { GirModule } from "../gir-module.ts"; import type { IntrospectedAlias } from "./alias.ts"; import type { IntrospectedConstant } from "./const.ts"; import type { IntrospectedEnum } from "./enum.ts"; import { IntrospectedFunction } from "./function.ts"; import type { IntrospectedBaseClass } from "./introspected-classes.ts"; // TODO: Move to types/ export type GirNSMember = | IntrospectedBaseClass | IntrospectedFunction | IntrospectedConstant | IntrospectedEnum | IntrospectedAlias; export function promisifyNamespaceFunctions(namespace: GirModule) { return namespace.members.forEach((node) => { if (!(node instanceof IntrospectedFunction)) return; if (node.parameters.length < 1) return; const last_param = node.parameters[node.parameters.length - 1]; if (!last_param) return; const last_param_unwrapped = last_param.type.unwrap(); if (!(last_param_unwrapped instanceof ClosureType)) return; const internal = last_param_unwrapped.type; if (internal instanceof TypeIdentifier && internal.is("Gio", "AsyncReadyCallback")) { const async_res = [ ...Array.from(namespace.members.values()).filter( (m): m is IntrospectedFunction => m instanceof IntrospectedFunction, ), ].find((m) => m.name === `${node.name.replace(/_async$/, "")}_finish` || m.name === `${node.name}_finish`); if (async_res) { const async_parameters = node.parameters.slice(0, -1).map((p) => p.copy()); const sync_parameters = node.parameters.map((p) => p.copy({ isOptional: false })); const output_parameters = async_res.output_parameters; let async_return = new PromiseType(async_res.return()); if (output_parameters.length > 0) { const raw_return = async_res.return(); if (raw_return.equals(VoidType) || raw_return.equals(BooleanType)) { const [output_type, ...output_types] = output_parameters.map((op) => op.type); async_return = new PromiseType(new TupleType(output_type, ...output_types)); } else { const [...output_types] = output_parameters.map((op) => op.type); async_return = new PromiseType(new TupleType(raw_return, ...output_types)); } } namespace.members.set(node.name, [ node.copy({ parameters: async_parameters, return_type: async_return, }), node.copy({ parameters: sync_parameters, }), node.copy({ return_type: makeUnion(async_return, node.return()), }), ]); } } }); } export { GirModule as IntrospectedNamespace } from "../gir-module.ts";