@ts-for-gir/lib
Version:
Typescript .d.ts generator from GIR for gjs
77 lines (61 loc) • 2.65 kB
text/typescript
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";