@gtkx/gir 0.8.0 → 0.9.1
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 +4 -1
- package/src/parser.ts +48 -36
- package/src/types.ts +66 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/gir",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "GObject Introspection file parser for GTKX",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtk",
|
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"src"
|
|
31
31
|
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"fast-xml-parser": "^5.3.3"
|
|
34
|
+
},
|
|
32
35
|
"scripts": {
|
|
33
36
|
"test": "vitest run"
|
|
34
37
|
}
|
package/src/parser.ts
CHANGED
|
@@ -186,18 +186,22 @@ export class GirParser {
|
|
|
186
186
|
}
|
|
187
187
|
return methods
|
|
188
188
|
.filter((method) => method["@_introspectable"] !== "0")
|
|
189
|
-
.map((method) =>
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
189
|
+
.map((method) => {
|
|
190
|
+
const returnValue = method["return-value"] as Record<string, unknown> | undefined;
|
|
191
|
+
return {
|
|
192
|
+
name: String(method["@_name"] ?? ""),
|
|
193
|
+
cIdentifier: String(method["@_c:identifier"] ?? ""),
|
|
194
|
+
returnType: this.parseReturnType(returnValue),
|
|
195
|
+
parameters: this.parseParameters(
|
|
196
|
+
(method.parameters && typeof method.parameters === "object" && method.parameters !== null
|
|
197
|
+
? method.parameters
|
|
198
|
+
: {}) as Record<string, unknown>,
|
|
199
|
+
),
|
|
200
|
+
throws: method["@_throws"] === "1",
|
|
201
|
+
doc: extractDoc(method),
|
|
202
|
+
returnDoc: returnValue ? extractDoc(returnValue) : undefined,
|
|
203
|
+
};
|
|
204
|
+
});
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
private parseConstructors(constructors: Record<string, unknown>[]): GirConstructor[] {
|
|
@@ -206,18 +210,22 @@ export class GirParser {
|
|
|
206
210
|
}
|
|
207
211
|
return constructors
|
|
208
212
|
.filter((ctor) => ctor["@_introspectable"] !== "0")
|
|
209
|
-
.map((ctor) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
.map((ctor) => {
|
|
214
|
+
const returnValue = ctor["return-value"] as Record<string, unknown> | undefined;
|
|
215
|
+
return {
|
|
216
|
+
name: String(ctor["@_name"] ?? ""),
|
|
217
|
+
cIdentifier: String(ctor["@_c:identifier"] ?? ""),
|
|
218
|
+
returnType: this.parseReturnType(returnValue),
|
|
219
|
+
parameters: this.parseParameters(
|
|
220
|
+
(ctor.parameters && typeof ctor.parameters === "object" && ctor.parameters !== null
|
|
221
|
+
? ctor.parameters
|
|
222
|
+
: {}) as Record<string, unknown>,
|
|
223
|
+
),
|
|
224
|
+
throws: ctor["@_throws"] === "1",
|
|
225
|
+
doc: extractDoc(ctor),
|
|
226
|
+
returnDoc: returnValue ? extractDoc(returnValue) : undefined,
|
|
227
|
+
};
|
|
228
|
+
});
|
|
221
229
|
}
|
|
222
230
|
|
|
223
231
|
private parseFunctions(functions: Record<string, unknown>[]): GirFunction[] {
|
|
@@ -226,18 +234,22 @@ export class GirParser {
|
|
|
226
234
|
}
|
|
227
235
|
return functions
|
|
228
236
|
.filter((func) => func["@_introspectable"] !== "0")
|
|
229
|
-
.map((func) =>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
237
|
+
.map((func) => {
|
|
238
|
+
const returnValue = func["return-value"] as Record<string, unknown> | undefined;
|
|
239
|
+
return {
|
|
240
|
+
name: String(func["@_name"] ?? ""),
|
|
241
|
+
cIdentifier: String(func["@_c:identifier"] ?? ""),
|
|
242
|
+
returnType: this.parseReturnType(returnValue),
|
|
243
|
+
parameters: this.parseParameters(
|
|
244
|
+
(func.parameters && typeof func.parameters === "object" && func.parameters !== null
|
|
245
|
+
? func.parameters
|
|
246
|
+
: {}) as Record<string, unknown>,
|
|
247
|
+
),
|
|
248
|
+
throws: func["@_throws"] === "1",
|
|
249
|
+
doc: extractDoc(func),
|
|
250
|
+
returnDoc: returnValue ? extractDoc(returnValue) : undefined,
|
|
251
|
+
};
|
|
252
|
+
});
|
|
241
253
|
}
|
|
242
254
|
|
|
243
255
|
private parseParameters(parametersNode: Record<string, unknown>): GirParameter[] {
|
package/src/types.ts
CHANGED
|
@@ -178,6 +178,8 @@ export type GirMethod = {
|
|
|
178
178
|
throws?: boolean;
|
|
179
179
|
/** Documentation for the method. */
|
|
180
180
|
doc?: string;
|
|
181
|
+
/** Documentation for the return value. */
|
|
182
|
+
returnDoc?: string;
|
|
181
183
|
};
|
|
182
184
|
|
|
183
185
|
/**
|
|
@@ -196,6 +198,8 @@ export type GirConstructor = {
|
|
|
196
198
|
throws?: boolean;
|
|
197
199
|
/** Documentation for the constructor. */
|
|
198
200
|
doc?: string;
|
|
201
|
+
/** Documentation for the return value. */
|
|
202
|
+
returnDoc?: string;
|
|
199
203
|
};
|
|
200
204
|
|
|
201
205
|
/**
|
|
@@ -214,6 +218,8 @@ export type GirFunction = {
|
|
|
214
218
|
throws?: boolean;
|
|
215
219
|
/** Documentation for the function. */
|
|
216
220
|
doc?: string;
|
|
221
|
+
/** Documentation for the return value. */
|
|
222
|
+
returnDoc?: string;
|
|
217
223
|
};
|
|
218
224
|
|
|
219
225
|
/**
|
|
@@ -344,12 +350,16 @@ export type FfiTypeDescriptor = {
|
|
|
344
350
|
borrowed?: boolean;
|
|
345
351
|
/** Inner type for ref types (as descriptor) or boxed types (as GLib type name string). */
|
|
346
352
|
innerType?: FfiTypeDescriptor | string;
|
|
353
|
+
/** Library name for boxed types that need dynamic type lookup. */
|
|
354
|
+
lib?: string;
|
|
355
|
+
/** Explicit get_type function name for boxed types (when naive transformation doesn't work). */
|
|
356
|
+
getTypeFn?: string;
|
|
347
357
|
/** Item type for array types. */
|
|
348
358
|
itemType?: FfiTypeDescriptor;
|
|
349
359
|
/** List type for arrays (glist, gslist) - indicates native GList/GSList iteration. */
|
|
350
360
|
listType?: "glist" | "gslist";
|
|
351
|
-
/** Trampoline type for callbacks
|
|
352
|
-
trampoline?: "asyncReady" | "destroy" | "
|
|
361
|
+
/** Trampoline type for callbacks. Default is "closure". */
|
|
362
|
+
trampoline?: "asyncReady" | "destroy" | "drawFunc" | "scaleFormatValueFunc";
|
|
353
363
|
/** Source type for asyncReady callback (the GObject source). */
|
|
354
364
|
sourceType?: FfiTypeDescriptor;
|
|
355
365
|
/** Result type for asyncReady callback (the GAsyncResult). */
|
|
@@ -441,7 +451,7 @@ export class TypeRegistry {
|
|
|
441
451
|
* @param namespace - The namespace containing the class
|
|
442
452
|
* @param name - The class name
|
|
443
453
|
*/
|
|
444
|
-
|
|
454
|
+
registerNativeClass(namespace: string, name: string): void {
|
|
445
455
|
const transformedName = normalizeTypeName(name, namespace);
|
|
446
456
|
this.types.set(`${namespace}.${name}`, {
|
|
447
457
|
kind: "class",
|
|
@@ -557,7 +567,7 @@ export class TypeRegistry {
|
|
|
557
567
|
const registry = new TypeRegistry();
|
|
558
568
|
for (const ns of namespaces) {
|
|
559
569
|
for (const cls of ns.classes) {
|
|
560
|
-
registry.
|
|
570
|
+
registry.registerNativeClass(ns.name, cls.name);
|
|
561
571
|
}
|
|
562
572
|
for (const iface of ns.interfaces) {
|
|
563
573
|
registry.registerInterface(ns.name, iface.name);
|
|
@@ -727,6 +737,7 @@ export class TypeMapper {
|
|
|
727
737
|
private recordNames: Set<string> = new Set();
|
|
728
738
|
private recordTransforms: Map<string, string> = new Map();
|
|
729
739
|
private recordGlibTypes: Map<string, string> = new Map();
|
|
740
|
+
private skippedClasses: Set<string> = new Set();
|
|
730
741
|
private onEnumUsed?: (enumName: string) => void;
|
|
731
742
|
private onRecordUsed?: (recordName: string) => void;
|
|
732
743
|
private onExternalTypeUsed?: (usage: ExternalTypeUsage) => void;
|
|
@@ -836,6 +847,14 @@ export class TypeMapper {
|
|
|
836
847
|
this.currentNamespace = currentNamespace;
|
|
837
848
|
}
|
|
838
849
|
|
|
850
|
+
registerSkippedClass(name: string): void {
|
|
851
|
+
this.skippedClasses.add(name);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
clearSkippedClasses(): void {
|
|
855
|
+
this.skippedClasses.clear();
|
|
856
|
+
}
|
|
857
|
+
|
|
839
858
|
/**
|
|
840
859
|
* Maps a GIR type to TypeScript and FFI type descriptors.
|
|
841
860
|
* @param girType - The GIR type to map
|
|
@@ -897,6 +916,12 @@ export class TypeMapper {
|
|
|
897
916
|
if (isExternal) {
|
|
898
917
|
this.onExternalTypeUsed?.(externalType as ExternalTypeUsage);
|
|
899
918
|
} else if (registered.kind === "class" || registered.kind === "interface") {
|
|
919
|
+
if (this.skippedClasses.has(registered.name)) {
|
|
920
|
+
return {
|
|
921
|
+
ts: "unknown",
|
|
922
|
+
ffi: { type: "gobject", borrowed: isReturn },
|
|
923
|
+
};
|
|
924
|
+
}
|
|
900
925
|
this.onSameNamespaceClassUsed?.(registered.transformedName, registered.name);
|
|
901
926
|
} else if (registered.kind === "enum") {
|
|
902
927
|
this.onEnumUsed?.(registered.transformedName);
|
|
@@ -1044,6 +1069,12 @@ export class TypeMapper {
|
|
|
1044
1069
|
if (isExternal) {
|
|
1045
1070
|
this.onExternalTypeUsed?.(externalType as ExternalTypeUsage);
|
|
1046
1071
|
} else if (registered.kind === "class" || registered.kind === "interface") {
|
|
1072
|
+
if (this.skippedClasses.has(registered.name)) {
|
|
1073
|
+
return {
|
|
1074
|
+
ts: "unknown",
|
|
1075
|
+
ffi: { type: "gobject", borrowed: isReturn },
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1047
1078
|
this.onSameNamespaceClassUsed?.(registered.transformedName, registered.name);
|
|
1048
1079
|
}
|
|
1049
1080
|
if (registered.kind === "enum") {
|
|
@@ -1159,25 +1190,28 @@ export class TypeMapper {
|
|
|
1159
1190
|
};
|
|
1160
1191
|
}
|
|
1161
1192
|
|
|
1162
|
-
if (param.type.name === "GLib.SourceFunc" || param.type.name === "SourceFunc") {
|
|
1163
|
-
return {
|
|
1164
|
-
ts: "() => boolean",
|
|
1165
|
-
ffi: {
|
|
1166
|
-
type: "callback",
|
|
1167
|
-
trampoline: "sourceFunc",
|
|
1168
|
-
},
|
|
1169
|
-
};
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
1193
|
if (param.type.name === "Gtk.DrawingAreaDrawFunc" || param.type.name === "DrawingAreaDrawFunc") {
|
|
1194
|
+
this.onExternalTypeUsed?.({
|
|
1195
|
+
namespace: "Cairo",
|
|
1196
|
+
name: "Context",
|
|
1197
|
+
transformedName: "Context",
|
|
1198
|
+
kind: "record",
|
|
1199
|
+
});
|
|
1200
|
+
this.onSameNamespaceClassUsed?.("DrawingArea", "DrawingArea");
|
|
1173
1201
|
return {
|
|
1174
|
-
ts: "(self:
|
|
1202
|
+
ts: "(self: DrawingArea, cr: Cairo.Context, width: number, height: number) => void",
|
|
1175
1203
|
ffi: {
|
|
1176
1204
|
type: "callback",
|
|
1177
1205
|
trampoline: "drawFunc",
|
|
1178
1206
|
argTypes: [
|
|
1179
1207
|
{ type: "gobject", borrowed: true },
|
|
1180
|
-
{
|
|
1208
|
+
{
|
|
1209
|
+
type: "boxed",
|
|
1210
|
+
borrowed: true,
|
|
1211
|
+
innerType: "CairoContext",
|
|
1212
|
+
lib: "libcairo-gobject.so.2",
|
|
1213
|
+
getTypeFn: "cairo_gobject_context_get_type",
|
|
1214
|
+
},
|
|
1181
1215
|
{ type: "int", size: 32, unsigned: false },
|
|
1182
1216
|
{ type: "int", size: 32, unsigned: false },
|
|
1183
1217
|
],
|
|
@@ -1185,34 +1219,6 @@ export class TypeMapper {
|
|
|
1185
1219
|
};
|
|
1186
1220
|
}
|
|
1187
1221
|
|
|
1188
|
-
if (param.type.name === "GLib.CompareDataFunc" || param.type.name === "CompareDataFunc") {
|
|
1189
|
-
return {
|
|
1190
|
-
ts: "(a: unknown, b: unknown) => number",
|
|
1191
|
-
ffi: {
|
|
1192
|
-
type: "callback",
|
|
1193
|
-
trampoline: "compareDataFunc",
|
|
1194
|
-
argTypes: [
|
|
1195
|
-
{ type: "gobject", borrowed: true },
|
|
1196
|
-
{ type: "gobject", borrowed: true },
|
|
1197
|
-
],
|
|
1198
|
-
},
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
if (param.type.name === "Gtk.TickCallback" || param.type.name === "TickCallback") {
|
|
1203
|
-
return {
|
|
1204
|
-
ts: "(widget: unknown, frameClock: unknown) => boolean",
|
|
1205
|
-
ffi: {
|
|
1206
|
-
type: "callback",
|
|
1207
|
-
trampoline: "tickFunc",
|
|
1208
|
-
argTypes: [
|
|
1209
|
-
{ type: "gobject", borrowed: true },
|
|
1210
|
-
{ type: "gobject", borrowed: true },
|
|
1211
|
-
],
|
|
1212
|
-
},
|
|
1213
|
-
};
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
1222
|
if (param.type.name === "GLib.Closure" || this.isCallback(param.type.name)) {
|
|
1217
1223
|
return {
|
|
1218
1224
|
ts: "(...args: unknown[]) => unknown",
|
|
@@ -1278,4 +1284,20 @@ export class TypeMapper {
|
|
|
1278
1284
|
isNullable(param: GirParameter): boolean {
|
|
1279
1285
|
return param.nullable === true || param.optional === true;
|
|
1280
1286
|
}
|
|
1287
|
+
|
|
1288
|
+
hasUnsupportedCallback(param: GirParameter): boolean {
|
|
1289
|
+
const supportedCallbacks = [
|
|
1290
|
+
"Gio.AsyncReadyCallback",
|
|
1291
|
+
"GLib.DestroyNotify",
|
|
1292
|
+
"DestroyNotify",
|
|
1293
|
+
"Gtk.DrawingAreaDrawFunc",
|
|
1294
|
+
"DrawingAreaDrawFunc",
|
|
1295
|
+
];
|
|
1296
|
+
|
|
1297
|
+
if (supportedCallbacks.includes(param.type.name)) {
|
|
1298
|
+
return false;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
return param.type.name === "GLib.Closure" || this.isCallback(param.type.name);
|
|
1302
|
+
}
|
|
1281
1303
|
}
|