@gtkx/gir 0.1.5 → 0.1.6
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 +1 -1
- package/src/parser.ts +53 -0
- package/src/types.ts +108 -3
package/package.json
CHANGED
package/src/parser.ts
CHANGED
|
@@ -4,12 +4,14 @@ import type {
|
|
|
4
4
|
GirConstructor,
|
|
5
5
|
GirEnumeration,
|
|
6
6
|
GirEnumerationMember,
|
|
7
|
+
GirField,
|
|
7
8
|
GirFunction,
|
|
8
9
|
GirInterface,
|
|
9
10
|
GirMethod,
|
|
10
11
|
GirNamespace,
|
|
11
12
|
GirParameter,
|
|
12
13
|
GirProperty,
|
|
14
|
+
GirRecord,
|
|
13
15
|
GirSignal,
|
|
14
16
|
GirType,
|
|
15
17
|
} from "./types.js";
|
|
@@ -20,6 +22,7 @@ const ARRAY_ELEMENT_PATHS = new Set<string>([
|
|
|
20
22
|
"namespace.function",
|
|
21
23
|
"namespace.enumeration",
|
|
22
24
|
"namespace.bitfield",
|
|
25
|
+
"namespace.record",
|
|
23
26
|
"namespace.class.method",
|
|
24
27
|
"namespace.class.constructor",
|
|
25
28
|
"namespace.class.function",
|
|
@@ -30,6 +33,10 @@ const ARRAY_ELEMENT_PATHS = new Set<string>([
|
|
|
30
33
|
"namespace.interface.property",
|
|
31
34
|
"namespace.interface.signal",
|
|
32
35
|
"namespace.interface.glib:signal",
|
|
36
|
+
"namespace.record.method",
|
|
37
|
+
"namespace.record.constructor",
|
|
38
|
+
"namespace.record.function",
|
|
39
|
+
"namespace.record.field",
|
|
33
40
|
"namespace.class.method.parameters.parameter",
|
|
34
41
|
"namespace.class.constructor.parameters.parameter",
|
|
35
42
|
"namespace.class.function.parameters.parameter",
|
|
@@ -39,6 +46,9 @@ const ARRAY_ELEMENT_PATHS = new Set<string>([
|
|
|
39
46
|
"namespace.interface.method.parameters.parameter",
|
|
40
47
|
"namespace.class.glib:signal.parameters.parameter",
|
|
41
48
|
"namespace.interface.glib:signal.parameters.parameter",
|
|
49
|
+
"namespace.record.method.parameters.parameter",
|
|
50
|
+
"namespace.record.constructor.parameters.parameter",
|
|
51
|
+
"namespace.record.function.parameters.parameter",
|
|
42
52
|
]);
|
|
43
53
|
|
|
44
54
|
const extractDoc = (node: Record<string, unknown>): string | undefined => {
|
|
@@ -94,6 +104,7 @@ export class GirParser {
|
|
|
94
104
|
functions: this.parseFunctions(namespace.function ?? []),
|
|
95
105
|
enumerations: this.parseEnumerations(namespace.enumeration ?? []),
|
|
96
106
|
bitfields: this.parseEnumerations(namespace.bitfield ?? []),
|
|
107
|
+
records: this.parseRecords(namespace.record ?? []),
|
|
97
108
|
};
|
|
98
109
|
}
|
|
99
110
|
|
|
@@ -290,6 +301,48 @@ export class GirParser {
|
|
|
290
301
|
});
|
|
291
302
|
}
|
|
292
303
|
|
|
304
|
+
private parseRecords(records: Record<string, unknown>[]): GirRecord[] {
|
|
305
|
+
if (!records || !Array.isArray(records)) {
|
|
306
|
+
return [];
|
|
307
|
+
}
|
|
308
|
+
return records.map((record) => ({
|
|
309
|
+
name: String(record["@_name"] ?? ""),
|
|
310
|
+
cType: String(record["@_c:type"] ?? record["@_glib:type-name"] ?? ""),
|
|
311
|
+
opaque: record["@_opaque"] === "1",
|
|
312
|
+
disguised: record["@_disguised"] === "1",
|
|
313
|
+
glibTypeName: record["@_glib:type-name"] ? String(record["@_glib:type-name"]) : undefined,
|
|
314
|
+
glibGetType: record["@_glib:get-type"] ? String(record["@_glib:get-type"]) : undefined,
|
|
315
|
+
fields: this.parseFields(Array.isArray(record.field) ? (record.field as Record<string, unknown>[]) : []),
|
|
316
|
+
methods: this.parseMethods(Array.isArray(record.method) ? (record.method as Record<string, unknown>[]) : []),
|
|
317
|
+
constructors: this.parseConstructors(
|
|
318
|
+
Array.isArray(record.constructor) ? (record.constructor as Record<string, unknown>[]) : [],
|
|
319
|
+
),
|
|
320
|
+
functions: this.parseFunctions(
|
|
321
|
+
Array.isArray(record.function) ? (record.function as Record<string, unknown>[]) : [],
|
|
322
|
+
),
|
|
323
|
+
doc: extractDoc(record),
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private parseFields(fields: Record<string, unknown>[]): GirField[] {
|
|
328
|
+
if (!fields || !Array.isArray(fields)) {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
return fields
|
|
332
|
+
.filter((field) => {
|
|
333
|
+
const hasCallback = field.callback !== undefined;
|
|
334
|
+
return !hasCallback;
|
|
335
|
+
})
|
|
336
|
+
.map((field) => ({
|
|
337
|
+
name: String(field["@_name"] ?? ""),
|
|
338
|
+
type: this.parseType((field.type ?? field.array) as Record<string, unknown> | undefined),
|
|
339
|
+
writable: field["@_writable"] === "1",
|
|
340
|
+
readable: field["@_readable"] !== "0",
|
|
341
|
+
private: field["@_private"] === "1",
|
|
342
|
+
doc: extractDoc(field),
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
|
|
293
346
|
private parseEnumerations(enumerations: Record<string, unknown>[]): GirEnumeration[] {
|
|
294
347
|
if (!enumerations || !Array.isArray(enumerations)) {
|
|
295
348
|
return [];
|
package/src/types.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface GirNamespace {
|
|
|
20
20
|
enumerations: GirEnumeration[];
|
|
21
21
|
/** All bitfield enumerations defined in this namespace. */
|
|
22
22
|
bitfields: GirEnumeration[];
|
|
23
|
+
/** All records (structs) defined in this namespace. */
|
|
24
|
+
records: GirRecord[];
|
|
23
25
|
/** Documentation for the namespace. */
|
|
24
26
|
doc?: string;
|
|
25
27
|
}
|
|
@@ -70,6 +72,52 @@ export interface GirClass {
|
|
|
70
72
|
doc?: string;
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Represents a GIR record (struct) definition.
|
|
77
|
+
*/
|
|
78
|
+
export interface GirRecord {
|
|
79
|
+
/** The record name. */
|
|
80
|
+
name: string;
|
|
81
|
+
/** The C type name. */
|
|
82
|
+
cType: string;
|
|
83
|
+
/** Whether this record is opaque (no field access). */
|
|
84
|
+
opaque?: boolean;
|
|
85
|
+
/** Whether this record is disguised (typically internal). */
|
|
86
|
+
disguised?: boolean;
|
|
87
|
+
/** The GLib type name for boxed types. */
|
|
88
|
+
glibTypeName?: string;
|
|
89
|
+
/** The GLib get-type function. */
|
|
90
|
+
glibGetType?: string;
|
|
91
|
+
/** Fields defined in this record. */
|
|
92
|
+
fields: GirField[];
|
|
93
|
+
/** Methods defined on this record. */
|
|
94
|
+
methods: GirMethod[];
|
|
95
|
+
/** Constructor functions for this record. */
|
|
96
|
+
constructors: GirConstructor[];
|
|
97
|
+
/** Static functions defined on this record. */
|
|
98
|
+
functions: GirFunction[];
|
|
99
|
+
/** Documentation for the record. */
|
|
100
|
+
doc?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Represents a GIR field definition in a record.
|
|
105
|
+
*/
|
|
106
|
+
export interface GirField {
|
|
107
|
+
/** The field name. */
|
|
108
|
+
name: string;
|
|
109
|
+
/** The field type. */
|
|
110
|
+
type: GirType;
|
|
111
|
+
/** Whether this field is writable. */
|
|
112
|
+
writable?: boolean;
|
|
113
|
+
/** Whether this field is readable. */
|
|
114
|
+
readable?: boolean;
|
|
115
|
+
/** Whether this field is private. */
|
|
116
|
+
private?: boolean;
|
|
117
|
+
/** Documentation for the field. */
|
|
118
|
+
doc?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
73
121
|
/**
|
|
74
122
|
* Represents a GIR method definition.
|
|
75
123
|
*/
|
|
@@ -230,8 +278,8 @@ export interface FfiTypeDescriptor {
|
|
|
230
278
|
unsigned?: boolean;
|
|
231
279
|
/** Whether the pointer is borrowed (not owned). */
|
|
232
280
|
borrowed?: boolean;
|
|
233
|
-
/** Inner type for ref types. */
|
|
234
|
-
innerType?: FfiTypeDescriptor;
|
|
281
|
+
/** Inner type for ref types (as descriptor) or boxed types (as GLib type name string). */
|
|
282
|
+
innerType?: FfiTypeDescriptor | string;
|
|
235
283
|
/** Item type for array types. */
|
|
236
284
|
itemType?: FfiTypeDescriptor;
|
|
237
285
|
}
|
|
@@ -307,6 +355,8 @@ const BASIC_TYPE_MAP = new Map<string, TypeMapping>([
|
|
|
307
355
|
["filename", { ts: "string", ffi: { type: "string" } }],
|
|
308
356
|
["gpointer", { ts: "unknown", ffi: { type: "gobject" } }],
|
|
309
357
|
["gconstpointer", { ts: "unknown", ffi: { type: "gobject" } }],
|
|
358
|
+
["Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
359
|
+
["GLib.Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
310
360
|
["void", { ts: "void", ffi: { type: "undefined" } }],
|
|
311
361
|
["none", { ts: "void", ffi: { type: "undefined" } }],
|
|
312
362
|
["int", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
@@ -331,12 +381,16 @@ const LIBRARY_MAP: Record<string, string> = {
|
|
|
331
381
|
|
|
332
382
|
/**
|
|
333
383
|
* Maps GIR types to TypeScript types and FFI type descriptors.
|
|
334
|
-
* Handles basic types, enumerations, arrays, and object references.
|
|
384
|
+
* Handles basic types, enumerations, records, arrays, and object references.
|
|
335
385
|
*/
|
|
336
386
|
export class TypeMapper {
|
|
337
387
|
private enumNames: Set<string> = new Set();
|
|
338
388
|
private enumTransforms: Map<string, string> = new Map();
|
|
389
|
+
private recordNames: Set<string> = new Set();
|
|
390
|
+
private recordTransforms: Map<string, string> = new Map();
|
|
391
|
+
private recordGlibTypes: Map<string, string> = new Map();
|
|
339
392
|
private onEnumUsed?: (enumName: string) => void;
|
|
393
|
+
private onRecordUsed?: (recordName: string) => void;
|
|
340
394
|
|
|
341
395
|
/**
|
|
342
396
|
* Registers an enumeration type for mapping.
|
|
@@ -350,6 +404,22 @@ export class TypeMapper {
|
|
|
350
404
|
}
|
|
351
405
|
}
|
|
352
406
|
|
|
407
|
+
/**
|
|
408
|
+
* Registers a record type for mapping.
|
|
409
|
+
* @param originalName - The original GIR record name
|
|
410
|
+
* @param transformedName - The transformed TypeScript class name
|
|
411
|
+
* @param glibTypeName - The GLib type name for boxed type handling
|
|
412
|
+
*/
|
|
413
|
+
registerRecord(originalName: string, transformedName?: string, glibTypeName?: string): void {
|
|
414
|
+
this.recordNames.add(originalName);
|
|
415
|
+
if (transformedName) {
|
|
416
|
+
this.recordTransforms.set(originalName, transformedName);
|
|
417
|
+
}
|
|
418
|
+
if (glibTypeName) {
|
|
419
|
+
this.recordGlibTypes.set(originalName, glibTypeName);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
353
423
|
/**
|
|
354
424
|
* Sets a callback to track enum usage during type mapping.
|
|
355
425
|
* @param callback - Called when an enum is used, or null to clear
|
|
@@ -366,6 +436,22 @@ export class TypeMapper {
|
|
|
366
436
|
return this.onEnumUsed ?? null;
|
|
367
437
|
}
|
|
368
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Sets a callback to track record usage during type mapping.
|
|
441
|
+
* @param callback - Called when a record is used, or null to clear
|
|
442
|
+
*/
|
|
443
|
+
setRecordUsageCallback(callback: ((recordName: string) => void) | null): void {
|
|
444
|
+
this.onRecordUsed = callback ?? undefined;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Gets the current record usage callback.
|
|
449
|
+
* @returns The callback or null if not set
|
|
450
|
+
*/
|
|
451
|
+
getRecordUsageCallback(): ((recordName: string) => void) | null {
|
|
452
|
+
return this.onRecordUsed ?? null;
|
|
453
|
+
}
|
|
454
|
+
|
|
369
455
|
/**
|
|
370
456
|
* Maps a GIR type to TypeScript and FFI type descriptors.
|
|
371
457
|
* @param girType - The GIR type to map
|
|
@@ -401,6 +487,16 @@ export class TypeMapper {
|
|
|
401
487
|
};
|
|
402
488
|
}
|
|
403
489
|
|
|
490
|
+
if (this.recordNames.has(girType.name)) {
|
|
491
|
+
const transformedName = this.recordTransforms.get(girType.name) ?? girType.name;
|
|
492
|
+
const glibTypeName = this.recordGlibTypes.get(girType.name) ?? transformedName;
|
|
493
|
+
this.onRecordUsed?.(transformedName);
|
|
494
|
+
return {
|
|
495
|
+
ts: transformedName,
|
|
496
|
+
ffi: { type: "boxed", borrowed: isReturn, innerType: glibTypeName },
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
404
500
|
if (girType.name.includes(".")) {
|
|
405
501
|
const [_ns, typeName] = girType.name.split(".", 2);
|
|
406
502
|
if (typeName && this.enumNames.has(typeName)) {
|
|
@@ -411,6 +507,15 @@ export class TypeMapper {
|
|
|
411
507
|
ffi: { type: "int", size: 32, unsigned: false },
|
|
412
508
|
};
|
|
413
509
|
}
|
|
510
|
+
if (typeName && this.recordNames.has(typeName)) {
|
|
511
|
+
const transformedName = this.recordTransforms.get(typeName) ?? typeName;
|
|
512
|
+
const glibTypeName = this.recordGlibTypes.get(typeName) ?? transformedName;
|
|
513
|
+
this.onRecordUsed?.(transformedName);
|
|
514
|
+
return {
|
|
515
|
+
ts: transformedName,
|
|
516
|
+
ffi: { type: "boxed", borrowed: isReturn, innerType: glibTypeName },
|
|
517
|
+
};
|
|
518
|
+
}
|
|
414
519
|
return {
|
|
415
520
|
ts: "unknown",
|
|
416
521
|
ffi: { type: "gobject", borrowed: isReturn },
|