diff --git a/examples/gobject-param-spec/main.ts b/examples/gobject-param-spec/main.ts index b964eb05..777e0720 100644 --- a/examples/gobject-param-spec/main.ts +++ b/examples/gobject-param-spec/main.ts @@ -1,5 +1,4 @@ import GObject from 'gi://GObject'; -import GLib from 'gi://GLib'; // Example class demonstrating different ParamSpec usages class ExampleObject extends GObject.Object { diff --git a/packages/lib/src/injections/gobject.ts b/packages/lib/src/injections/gobject.ts index 7fa62c29..b8321093 100644 --- a/packages/lib/src/injections/gobject.ts +++ b/packages/lib/src/injections/gobject.ts @@ -30,24 +30,38 @@ import { IntrospectedField } from "../gir/property.js"; import { IntrospectedAlias } from "../gir/alias.js"; import { IntrospectedInterface } from "../gir/class.js"; -function typeParam(name: string, type: TypeExpression) { +function typeParam(name: string, type: TypeExpression, options: any = {}) { return new IntrospectedFunctionParameter({ name, direction: GirDirection.In, - type: type + type: type, + ...options }); } -function anyParam(name: string) { - return typeParam(name, AnyType); +function anyParam(name: string, options: any = {}) { + return typeParam(name, AnyType, options); } -function stringParam(name: string) { - return typeParam(name, StringType); +function stringParam(name: string, options: any = {}) { + return typeParam(name, StringType, options); } -function nullableStringParam(name: string) { - return typeParam(name, new NullableType(StringType)); +/** + * Creates a parameter with a nullable string type. + * Used for optional documentation fields like 'nick' and 'blurb' in GObject properties. + * These fields are commonly used to provide human-readable descriptions of properties. + * + * @param name The parameter name + * @param options Additional options including documentation + * @returns An IntrospectedFunctionParameter with nullable string type + * @see https://gjs.guide/guides/gobject/basics.html#properties + */ +function nullableStringParam(name: string, options: any = {}) { + return typeParam(name, new NullableType(StringType), { + doc: "A nullable string parameter, commonly used for optional documentation fields in GObject properties", + ...options + }); } export default { @@ -99,8 +113,24 @@ export default { GType.noEmit(); const ParamSpec = namespace.assertClass("ParamSpec"); + ParamSpec.doc = `A GObject parameter specification that defines property characteristics. +See https://gjs.guide/guides/gobject/basics.html#properties for more details.`; const ParamFlags = namespace.getEnum("ParamFlags"); + /** + * Generates ParamSpec function definitions with proper typing for nullable documentation fields. + * Follows GJS style guidelines for property definitions with optional documentation. + * + * @param name The name of the ParamSpec type (e.g., "string", "int", "boolean") + * @param returnType The return type of the ParamSpec + * @param minMax Whether the ParamSpec has min/max values + * @param type Optional type parameter name + * @param defaultValue Whether the ParamSpec has a default value + * @param defaultValueType The type of the default value + * @param addGeneric Whether to add generic type parameters + * @returns An IntrospectedStaticClassFunction for the ParamSpec + * @see https://gjs.guide/guides/gjs/style-guide.html#properties + */ function generateParamSpec( name: string, returnType: TypeExpression = ParamSpec.getType(), @@ -110,27 +140,50 @@ export default { defaultValueType: TypeExpression = AnyType, addGeneric = false ) { + const params = [ + stringParam("name", { + doc: "The name of the property" + }), + nullableStringParam("nick", { + doc: "A human readable name for the property" + }), + nullableStringParam("blurb", { + doc: "A longer description of the property" + }), + typeParam("flags", new BinaryType(ParamFlags?.getType() ?? AnyType, NumberType), { + doc: "The flags for this property (e.g. READABLE, WRITABLE)" + }) + ]; + + if (minMax) { + params.push(typeParam("minimum", NumberType, { + doc: "The minimum value for this property" + }), typeParam("maximum", NumberType, { + doc: "The maximum value for this property" + })); + } + + if (type) { + if (!addGeneric) { + params.push(anyParam(`${type}Type`)); + } else { + params.push(new IntrospectedFunctionParameter({ + name: `${type}Type`, + direction: GirDirection.In, + type: new NativeType("GType | { $gtype: GType }") + })); + } + } + + if (defaultValue) { + params.push(typeParam("defaultValue", defaultValueType, { + doc: "The default value for this property" + })); + } + const fn = new IntrospectedStaticClassFunction({ name, - parameters: [ - stringParam("name"), - nullableStringParam("nick"), - nullableStringParam("blurb"), - typeParam("flags", new BinaryType(ParamFlags?.getType() ?? AnyType, NumberType)), - ...(minMax ? [typeParam("minimum", NumberType), typeParam("maximum", NumberType)] : []), - ...(type - ? !addGeneric - ? [anyParam(`${type}Type`)] - : [ - new IntrospectedFunctionParameter({ - name: `${type}Type`, - direction: GirDirection.In, - type: new NativeType("GType | { $gtype: GType }") - }) - ] - : []), - ...(defaultValue ? [typeParam("defaultValue", defaultValueType)] : []) - ], + parameters: params, parent: ParamSpec, return_type: returnType });