@gtkx/gir 0.1.12 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/gir",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "GObject Introspection file parser for GTKX",
5
5
  "keywords": [
6
6
  "gtk",
@@ -28,5 +28,8 @@
28
28
  },
29
29
  "files": [
30
30
  "src"
31
- ]
31
+ ],
32
+ "scripts": {
33
+ "test": "vitest run"
34
+ }
32
35
  }
package/src/parser.ts CHANGED
@@ -244,7 +244,15 @@ export class GirParser {
244
244
  if (!returnValue) {
245
245
  return { name: "void" };
246
246
  }
247
- return this.parseType((returnValue.type ?? returnValue.array) as Record<string, unknown> | undefined);
247
+ const type = this.parseType((returnValue.type ?? returnValue.array) as Record<string, unknown> | undefined);
248
+ const transferOwnership = returnValue["@_transfer-ownership"] as string | undefined;
249
+ if (transferOwnership === "none" || transferOwnership === "full" || transferOwnership === "container") {
250
+ type.transferOwnership = transferOwnership;
251
+ }
252
+ if (returnValue["@_nullable"] === "1") {
253
+ type.nullable = true;
254
+ }
255
+ return type;
248
256
  }
249
257
 
250
258
  private parseType(typeNode: Record<string, unknown> | undefined): GirType {
@@ -252,9 +260,21 @@ export class GirParser {
252
260
  return { name: "void" };
253
261
  }
254
262
 
255
- if (typeNode["@_name"]) {
263
+ const typeName = typeNode["@_name"] ? String(typeNode["@_name"]) : undefined;
264
+
265
+ if (typeName === "GLib.List" || typeName === "GLib.SList") {
266
+ const innerType = typeNode.type as Record<string, unknown> | undefined;
267
+ return {
268
+ name: "array",
269
+ cType: typeNode["@_c:type"] ? String(typeNode["@_c:type"]) : undefined,
270
+ isArray: true,
271
+ elementType: innerType ? this.parseType(innerType) : undefined,
272
+ };
273
+ }
274
+
275
+ if (typeName) {
256
276
  return {
257
- name: String(typeNode["@_name"] ?? ""),
277
+ name: typeName,
258
278
  cType: typeNode["@_c:type"] ? String(typeNode["@_c:type"]) : undefined,
259
279
  };
260
280
  }
package/src/types.ts CHANGED
@@ -204,6 +204,10 @@ export interface GirType {
204
204
  isArray?: boolean;
205
205
  /** The element type for array types. */
206
206
  elementType?: GirType;
207
+ /** Transfer ownership semantics for return types. */
208
+ transferOwnership?: "none" | "full" | "container";
209
+ /** Whether this type can be null (for return types). */
210
+ nullable?: boolean;
207
211
  }
208
212
 
209
213
  /**
@@ -290,9 +294,13 @@ export interface FfiTypeDescriptor {
290
294
  innerType?: FfiTypeDescriptor | string;
291
295
  /** Item type for array types. */
292
296
  itemType?: FfiTypeDescriptor;
293
- /** Source type for asyncCallback (the GObject source). */
297
+ /** List type for arrays (glist, gslist) - indicates native GList/GSList iteration. */
298
+ listType?: "glist" | "gslist";
299
+ /** Trampoline type for callbacks (asyncReady, destroy, sourceFunc). Default is "closure". */
300
+ trampoline?: "asyncReady" | "destroy" | "sourceFunc";
301
+ /** Source type for asyncReady callback (the GObject source). */
294
302
  sourceType?: FfiTypeDescriptor;
295
- /** Result type for asyncCallback (the GAsyncResult). */
303
+ /** Result type for asyncReady callback (the GAsyncResult). */
296
304
  resultType?: FfiTypeDescriptor;
297
305
  }
298
306
 
@@ -448,6 +456,8 @@ export class TypeRegistry {
448
456
  }
449
457
  }
450
458
 
459
+ const STRING_TYPES = new Set(["utf8", "filename"]);
460
+
451
461
  const BASIC_TYPE_MAP = new Map<string, TypeMapping>([
452
462
  ["gboolean", { ts: "boolean", ffi: { type: "boolean" } }],
453
463
  ["gchar", { ts: "number", ffi: { type: "int", size: 8, unsigned: false } }],
@@ -469,12 +479,29 @@ const BASIC_TYPE_MAP = new Map<string, TypeMapping>([
469
479
  ["guint64", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
470
480
  ["gfloat", { ts: "number", ffi: { type: "float", size: 32 } }],
471
481
  ["gdouble", { ts: "number", ffi: { type: "float", size: 64 } }],
472
- ["utf8", { ts: "string", ffi: { type: "string" } }],
473
- ["filename", { ts: "string", ffi: { type: "string" } }],
474
- ["gpointer", { ts: "unknown", ffi: { type: "gobject" } }],
475
- ["gconstpointer", { ts: "unknown", ffi: { type: "gobject" } }],
482
+ ["gpointer", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
483
+ ["gconstpointer", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
484
+ ["gsize", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
485
+ ["gssize", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
486
+ ["goffset", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
487
+ ["guintptr", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
488
+ ["gintptr", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
489
+ ["pid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
490
+ ["uid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
491
+ ["gid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
492
+ ["time_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
476
493
  ["Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
477
494
  ["GLib.Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
495
+ ["TimeSpan", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
496
+ ["GLib.TimeSpan", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
497
+ ["DateDay", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
498
+ ["GLib.DateDay", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
499
+ ["DateYear", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
500
+ ["GLib.DateYear", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
501
+ ["DateMonth", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
502
+ ["GLib.DateMonth", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
503
+ ["Pid", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
504
+ ["GLib.Pid", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
478
505
  ["void", { ts: "void", ffi: { type: "undefined" } }],
479
506
  ["none", { ts: "void", ffi: { type: "undefined" } }],
480
507
  ["int", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
@@ -485,6 +512,10 @@ const BASIC_TYPE_MAP = new Map<string, TypeMapping>([
485
512
  ["ssize_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
486
513
  ["double", { ts: "number", ffi: { type: "float", size: 64 } }],
487
514
  ["float", { ts: "number", ffi: { type: "float", size: 32 } }],
515
+ ["GLib.DestroyNotify", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
516
+ ["DestroyNotify", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
517
+ ["GLib.FreeFunc", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
518
+ ["FreeFunc", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
488
519
  ]);
489
520
 
490
521
  const LIBRARY_MAP: Record<string, string> = {
@@ -509,6 +540,7 @@ export interface MappedType {
509
540
  ffi: FfiTypeDescriptor;
510
541
  externalType?: ExternalTypeUsage;
511
542
  kind?: TypeKind;
543
+ nullable?: boolean;
512
544
  }
513
545
 
514
546
  /**
@@ -622,16 +654,33 @@ export class TypeMapper {
622
654
  */
623
655
  mapType(girType: GirType, isReturn = false): MappedType {
624
656
  if (girType.isArray || girType.name === "array") {
657
+ const listType = girType.cType?.includes("GSList")
658
+ ? "gslist"
659
+ : girType.cType?.includes("GList")
660
+ ? "glist"
661
+ : undefined;
625
662
  if (girType.elementType) {
626
663
  const elementType = this.mapType(girType.elementType);
627
664
  return {
628
665
  ts: `${elementType.ts}[]`,
629
- ffi: { type: "array", itemType: elementType.ffi },
666
+ ffi: listType
667
+ ? { type: "array", itemType: elementType.ffi, listType, borrowed: isReturn }
668
+ : { type: "array", itemType: elementType.ffi },
630
669
  };
631
670
  }
632
671
  return {
633
672
  ts: `unknown[]`,
634
- ffi: { type: "array", itemType: { type: "undefined" } },
673
+ ffi: listType
674
+ ? { type: "array", itemType: { type: "undefined" }, listType, borrowed: isReturn }
675
+ : { type: "array", itemType: { type: "undefined" } },
676
+ };
677
+ }
678
+
679
+ if (STRING_TYPES.has(girType.name)) {
680
+ const borrowed = girType.transferOwnership === "none";
681
+ return {
682
+ ts: "string",
683
+ ffi: { type: "string", borrowed },
635
684
  };
636
685
  }
637
686
 
@@ -804,13 +853,34 @@ export class TypeMapper {
804
853
  return {
805
854
  ts: "(source: unknown, result: unknown) => void",
806
855
  ffi: {
807
- type: "asyncCallback",
856
+ type: "callback",
857
+ trampoline: "asyncReady",
808
858
  sourceType: { type: "gobject", borrowed: true },
809
859
  resultType: { type: "gobject", borrowed: true },
810
860
  },
811
861
  };
812
862
  }
813
863
 
864
+ if (param.type.name === "GLib.DestroyNotify") {
865
+ return {
866
+ ts: "() => void",
867
+ ffi: {
868
+ type: "callback",
869
+ trampoline: "destroy",
870
+ },
871
+ };
872
+ }
873
+
874
+ if (param.type.name === "GLib.SourceFunc") {
875
+ return {
876
+ ts: "() => boolean",
877
+ ffi: {
878
+ type: "callback",
879
+ trampoline: "sourceFunc",
880
+ },
881
+ };
882
+ }
883
+
814
884
  if (param.type.name === "GLib.Closure" || param.type.name.endsWith("Func")) {
815
885
  return {
816
886
  ts: "(...args: unknown[]) => unknown",