@gtkx/gir 0.20.0 → 0.21.0

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.
Files changed (115) hide show
  1. package/dist/index.d.ts +25 -12
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +21 -10
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/loader.d.ts +30 -0
  6. package/dist/internal/loader.d.ts.map +1 -0
  7. package/dist/internal/loader.js +109 -0
  8. package/dist/internal/loader.js.map +1 -0
  9. package/dist/internal/normalizer.d.ts +98 -15
  10. package/dist/internal/normalizer.d.ts.map +1 -1
  11. package/dist/internal/normalizer.js +381 -412
  12. package/dist/internal/normalizer.js.map +1 -1
  13. package/dist/internal/parser.d.ts +23 -31
  14. package/dist/internal/parser.d.ts.map +1 -1
  15. package/dist/internal/parser.js +228 -244
  16. package/dist/internal/parser.js.map +1 -1
  17. package/dist/internal/raw-types.d.ts +58 -109
  18. package/dist/internal/raw-types.d.ts.map +1 -1
  19. package/dist/internal/raw-types.js +0 -8
  20. package/dist/internal/raw-types.js.map +1 -1
  21. package/dist/intrinsics.d.ts.map +1 -1
  22. package/dist/intrinsics.js +7 -0
  23. package/dist/intrinsics.js.map +1 -1
  24. package/dist/model/alias.d.ts +21 -0
  25. package/dist/model/alias.d.ts.map +1 -0
  26. package/dist/model/alias.js +22 -0
  27. package/dist/model/alias.js.map +1 -0
  28. package/dist/model/callables.d.ts +102 -0
  29. package/dist/model/callables.d.ts.map +1 -0
  30. package/dist/model/callables.js +123 -0
  31. package/dist/model/callables.js.map +1 -0
  32. package/dist/model/callback.d.ts +22 -0
  33. package/dist/model/callback.d.ts.map +1 -0
  34. package/dist/model/callback.js +20 -0
  35. package/dist/model/callback.js.map +1 -0
  36. package/dist/model/class.d.ts +92 -0
  37. package/dist/model/class.d.ts.map +1 -0
  38. package/dist/model/class.js +171 -0
  39. package/dist/model/class.js.map +1 -0
  40. package/dist/model/constant.d.ts +21 -0
  41. package/dist/model/constant.d.ts.map +1 -0
  42. package/dist/model/constant.js +20 -0
  43. package/dist/model/constant.js.map +1 -0
  44. package/dist/model/enumeration.d.ts +41 -0
  45. package/dist/model/enumeration.d.ts.map +1 -0
  46. package/dist/model/enumeration.js +47 -0
  47. package/dist/model/enumeration.js.map +1 -0
  48. package/dist/model/field.d.ts +21 -0
  49. package/dist/model/field.d.ts.map +1 -0
  50. package/dist/model/field.js +20 -0
  51. package/dist/model/field.js.map +1 -0
  52. package/dist/model/interface.d.ts +44 -0
  53. package/dist/model/interface.d.ts.map +1 -0
  54. package/dist/model/interface.js +67 -0
  55. package/dist/model/interface.js.map +1 -0
  56. package/dist/model/namespace.d.ts +44 -0
  57. package/dist/model/namespace.d.ts.map +1 -0
  58. package/dist/model/namespace.js +36 -0
  59. package/dist/model/namespace.js.map +1 -0
  60. package/dist/model/parameter.d.ts +43 -0
  61. package/dist/model/parameter.d.ts.map +1 -0
  62. package/dist/model/parameter.js +54 -0
  63. package/dist/model/parameter.js.map +1 -0
  64. package/dist/model/property.d.ts +62 -0
  65. package/dist/model/property.d.ts.map +1 -0
  66. package/dist/model/property.js +69 -0
  67. package/dist/model/property.js.map +1 -0
  68. package/dist/model/record.d.ts +56 -0
  69. package/dist/model/record.d.ts.map +1 -0
  70. package/dist/model/record.js +70 -0
  71. package/dist/model/record.js.map +1 -0
  72. package/dist/model/repository-like.d.ts +19 -0
  73. package/dist/model/repository-like.d.ts.map +1 -0
  74. package/dist/model/repository-like.js +2 -0
  75. package/dist/model/repository-like.js.map +1 -0
  76. package/dist/model/signal.d.ts +22 -0
  77. package/dist/model/signal.d.ts.map +1 -0
  78. package/dist/model/signal.js +22 -0
  79. package/dist/model/signal.js.map +1 -0
  80. package/dist/model/type.d.ts +71 -0
  81. package/dist/model/type.d.ts.map +1 -0
  82. package/dist/model/type.js +112 -0
  83. package/dist/model/type.js.map +1 -0
  84. package/dist/repository.d.ts +92 -138
  85. package/dist/repository.d.ts.map +1 -1
  86. package/dist/repository.js +155 -219
  87. package/dist/repository.js.map +1 -1
  88. package/package.json +2 -2
  89. package/src/index.ts +25 -39
  90. package/src/internal/loader.ts +127 -0
  91. package/src/internal/normalizer.ts +451 -475
  92. package/src/internal/parser.ts +242 -284
  93. package/src/internal/raw-types.ts +65 -116
  94. package/src/intrinsics.ts +7 -0
  95. package/src/model/alias.ts +31 -0
  96. package/src/model/callables.ts +172 -0
  97. package/src/model/callback.ts +30 -0
  98. package/src/model/class.ts +215 -0
  99. package/src/model/constant.ts +29 -0
  100. package/src/model/enumeration.ts +64 -0
  101. package/src/model/field.ts +29 -0
  102. package/src/model/interface.ts +89 -0
  103. package/src/model/namespace.ts +60 -0
  104. package/src/model/parameter.ts +74 -0
  105. package/src/model/property.ts +97 -0
  106. package/src/model/record.ts +97 -0
  107. package/src/model/repository-like.ts +20 -0
  108. package/src/model/signal.ts +32 -0
  109. package/src/model/type.ts +143 -0
  110. package/src/repository.ts +197 -283
  111. package/dist/types.d.ts +0 -655
  112. package/dist/types.d.ts.map +0 -1
  113. package/dist/types.js +0 -879
  114. package/dist/types.js.map +0 -1
  115. package/src/types.ts +0 -1192
@@ -1,11 +1,3 @@
1
- /**
2
- * GObject Introspection XML (GIR) parser.
3
- *
4
- * Parses GIR files to extract type information for GTK/GLib libraries.
5
- * Outputs raw GIR types that are then normalized by the normalizer.
6
- *
7
- * @internal
8
- */
9
1
  import { XMLParser } from "fast-xml-parser";
10
2
  const ARRAY_ELEMENT_PATHS = new Set([
11
3
  "namespace.class",
@@ -18,7 +10,7 @@ const ARRAY_ELEMENT_PATHS = new Set([
18
10
  "namespace.constant",
19
11
  "namespace.alias",
20
12
  "namespace.class.method",
21
- "namespace.class.constructor",
13
+ "namespace.class._constructor",
22
14
  "namespace.class.function",
23
15
  "namespace.class.property",
24
16
  "namespace.class.signal",
@@ -28,11 +20,11 @@ const ARRAY_ELEMENT_PATHS = new Set([
28
20
  "namespace.interface.signal",
29
21
  "namespace.interface.glib:signal",
30
22
  "namespace.record.method",
31
- "namespace.record.constructor",
23
+ "namespace.record._constructor",
32
24
  "namespace.record.function",
33
25
  "namespace.record.field",
34
26
  "namespace.class.method.parameters.parameter",
35
- "namespace.class.constructor.parameters.parameter",
27
+ "namespace.class._constructor.parameters.parameter",
36
28
  "namespace.class.function.parameters.parameter",
37
29
  "namespace.function.parameters.parameter",
38
30
  "namespace.enumeration.member",
@@ -41,11 +33,14 @@ const ARRAY_ELEMENT_PATHS = new Set([
41
33
  "namespace.class.glib:signal.parameters.parameter",
42
34
  "namespace.interface.glib:signal.parameters.parameter",
43
35
  "namespace.record.method.parameters.parameter",
44
- "namespace.record.constructor.parameters.parameter",
36
+ "namespace.record._constructor.parameters.parameter",
45
37
  "namespace.record.function.parameters.parameter",
46
38
  "namespace.callback.parameters.parameter",
47
39
  ]);
48
- const extractDoc = (node) => {
40
+ const INCLUDE_RE = /<include\s+name="([^"]+)"\s+version="([^"]+)"/g;
41
+ const NS_NAME_RE = /<namespace\s[^>]*name="([^"]+)"/;
42
+ const NS_VERSION_RE = /<namespace\s[^>]*version="([^"]+)"/;
43
+ function extractDoc(node) {
49
44
  const doc = node.doc;
50
45
  if (!doc)
51
46
  return undefined;
@@ -53,49 +48,69 @@ const extractDoc = (node) => {
53
48
  if (typeof text !== "string")
54
49
  return undefined;
55
50
  return text.trim();
56
- };
57
- const ensureArray = (value) => Array.isArray(value) ? value : [];
51
+ }
52
+ function ensureArray(value) {
53
+ return Array.isArray(value) ? value : [];
54
+ }
58
55
  /**
59
56
  * Parser for GObject Introspection XML (GIR) files.
60
57
  *
61
- * Converts GIR XML into raw TypeScript objects.
58
+ * Provides both a lightweight header parse (for dependency graph discovery)
59
+ * and a full parse (for complete namespace extraction).
62
60
  */
63
- export class RawGirParser {
61
+ export class GirParser {
64
62
  parser;
65
- includeNonIntrospectableNamespaces;
66
- currentNamespace = "";
67
- constructor(options = {}) {
68
- this.includeNonIntrospectableNamespaces = options.includeNonIntrospectableNamespaces ?? new Set();
63
+ constructor() {
69
64
  this.parser = new XMLParser({
70
65
  ignoreAttributes: false,
71
66
  attributeNamePrefix: "@_",
72
67
  textNodeName: "#text",
68
+ transformTagName: (tagName) => (tagName === "constructor" ? "_constructor" : tagName),
73
69
  isArray: (_name, jpath, _isLeafNode, _isAttribute) => {
70
+ if (typeof jpath !== "string")
71
+ return false;
74
72
  const path = jpath.split(".").slice(1).join(".");
75
73
  return ARRAY_ELEMENT_PATHS.has(path);
76
74
  },
75
+ processEntities: { maxTotalExpansions: 100000 },
77
76
  });
78
77
  }
79
- shouldIncludeNonIntrospectable() {
80
- return this.includeNonIntrospectableNamespaces.has(this.currentNamespace);
81
- }
82
- isIntrospectable(node) {
83
- if (node["@_introspectable"] === "0") {
84
- return this.shouldIncludeNonIntrospectable();
78
+ /**
79
+ * Lightweight header parse using regex — extracts namespace name, version,
80
+ * and `<include>` dependencies without paying the cost of full XML parsing.
81
+ */
82
+ parseHeader(girXml) {
83
+ const nameMatch = NS_NAME_RE.exec(girXml);
84
+ const versionMatch = NS_VERSION_RE.exec(girXml);
85
+ if (!nameMatch || !versionMatch) {
86
+ throw new Error("Failed to parse GIR header: missing namespace name or version");
85
87
  }
86
- return true;
88
+ const dependencies = [];
89
+ INCLUDE_RE.lastIndex = 0;
90
+ for (let m = INCLUDE_RE.exec(girXml); m !== null; m = INCLUDE_RE.exec(girXml)) {
91
+ const name = m[1];
92
+ const version = m[2];
93
+ if (name && version) {
94
+ dependencies.push({ name, version });
95
+ }
96
+ }
97
+ const namespaceName = nameMatch[1];
98
+ const namespaceVersion = versionMatch[1];
99
+ if (!namespaceName || !namespaceVersion) {
100
+ throw new Error("Failed to parse GIR header: missing namespace name or version");
101
+ }
102
+ return { namespaceName, namespaceVersion, dependencies };
87
103
  }
88
104
  /**
89
- * Parses a GIR XML string into a raw namespace object.
105
+ * Full parse of a GIR XML string into a raw namespace.
90
106
  */
91
- parse(girXml) {
107
+ parseNamespace(girXml) {
92
108
  const parsed = this.parser.parse(girXml);
93
109
  const repository = parsed.repository;
94
110
  if (!repository?.namespace) {
95
111
  throw new Error("Failed to parse GIR file: missing repository or namespace element");
96
112
  }
97
113
  const namespace = repository.namespace;
98
- this.currentNamespace = namespace["@_name"];
99
114
  return {
100
115
  name: namespace["@_name"],
101
116
  version: namespace["@_version"],
@@ -112,22 +127,6 @@ export class RawGirParser {
112
127
  aliases: this.parseAliases(namespace.alias ?? []),
113
128
  };
114
129
  }
115
- parseCallbacks(callbacks) {
116
- if (!callbacks || !Array.isArray(callbacks)) {
117
- return [];
118
- }
119
- return callbacks
120
- .filter((cb) => this.isIntrospectable(cb))
121
- .map((cb) => ({
122
- name: String(cb["@_name"] ?? ""),
123
- cType: String(cb["@_c:type"] ?? ""),
124
- returnType: this.parseReturnType(cb["return-value"]),
125
- parameters: this.parseParameters((cb.parameters && typeof cb.parameters === "object" && cb.parameters !== null
126
- ? cb.parameters
127
- : {})),
128
- doc: extractDoc(cb),
129
- }));
130
- }
131
130
  parseClasses(classes) {
132
131
  return classes.map((cls) => ({
133
132
  name: String(cls["@_name"] ?? ""),
@@ -142,7 +141,7 @@ export class RawGirParser {
142
141
  unrefFunc: cls["@_glib:unref-func"] ? String(cls["@_glib:unref-func"]) : undefined,
143
142
  implements: this.parseImplements(cls.implements),
144
143
  methods: this.parseMethods(ensureArray(cls.method)),
145
- constructors: this.parseConstructors(ensureArray(cls.constructor)),
144
+ constructors: this.parseConstructors(ensureArray(cls._constructor)),
146
145
  functions: this.parseFunctions(ensureArray(cls.function)),
147
146
  properties: this.parseProperties(ensureArray(cls.property)),
148
147
  signals: this.parseSignals(ensureArray(cls["glib:signal"])),
@@ -156,9 +155,8 @@ export class RawGirParser {
156
155
  return arr.map((impl) => String(impl["@_name"] ?? "")).filter(Boolean);
157
156
  }
158
157
  parseInterfaces(interfaces) {
159
- if (!interfaces || !Array.isArray(interfaces)) {
158
+ if (!interfaces || !Array.isArray(interfaces))
160
159
  return [];
161
- }
162
160
  return interfaces.map((iface) => ({
163
161
  name: String(iface["@_name"] ?? ""),
164
162
  cType: String(iface["@_c:type"] ?? iface["@_glib:type-name"] ?? ""),
@@ -177,19 +175,13 @@ export class RawGirParser {
177
175
  return arr.map((prereq) => String(prereq["@_name"] ?? "")).filter(Boolean);
178
176
  }
179
177
  parseMethods(methods) {
180
- if (!methods || !Array.isArray(methods)) {
178
+ if (!methods || !Array.isArray(methods))
181
179
  return [];
182
- }
183
180
  return methods
184
- .filter((method) => this.isIntrospectable(method))
181
+ .filter((m) => m["@_introspectable"] !== "0")
185
182
  .map((method) => {
186
183
  const returnValue = method["return-value"];
187
- const finishFunc = method["@_glib:finish-func"];
188
- const shadows = method["@_shadows"];
189
- const shadowedBy = method["@_shadowed-by"];
190
- const parametersNode = method.parameters && typeof method.parameters === "object" && method.parameters !== null
191
- ? method.parameters
192
- : {};
184
+ const parametersNode = this.extractParametersNode(method);
193
185
  return {
194
186
  name: String(method["@_name"] ?? ""),
195
187
  cIdentifier: String(method["@_c:identifier"] ?? ""),
@@ -199,74 +191,208 @@ export class RawGirParser {
199
191
  throws: method["@_throws"] === "1",
200
192
  doc: extractDoc(method),
201
193
  returnDoc: returnValue ? extractDoc(returnValue) : undefined,
202
- finishFunc: finishFunc || undefined,
203
- shadows: shadows || undefined,
204
- shadowedBy: shadowedBy || undefined,
194
+ finishFunc: method["@_glib:finish-func"] || undefined,
195
+ shadows: method["@_shadows"] || undefined,
196
+ shadowedBy: method["@_shadowed-by"] || undefined,
205
197
  };
206
198
  });
207
199
  }
208
200
  parseConstructors(constructors) {
209
- if (!constructors || !Array.isArray(constructors)) {
201
+ if (!constructors || !Array.isArray(constructors))
210
202
  return [];
211
- }
212
203
  return constructors
213
- .filter((ctor) => this.isIntrospectable(ctor))
204
+ .filter((c) => c["@_introspectable"] !== "0")
214
205
  .map((ctor) => {
215
206
  const returnValue = ctor["return-value"];
216
- const shadows = ctor["@_shadows"];
217
- const shadowedBy = ctor["@_shadowed-by"];
218
207
  return {
219
208
  name: String(ctor["@_name"] ?? ""),
220
209
  cIdentifier: String(ctor["@_c:identifier"] ?? ""),
221
210
  returnType: this.parseReturnType(returnValue),
222
- parameters: this.parseParameters((ctor.parameters && typeof ctor.parameters === "object" && ctor.parameters !== null
223
- ? ctor.parameters
224
- : {})),
211
+ parameters: this.parseParameters(this.extractParametersNode(ctor)),
225
212
  throws: ctor["@_throws"] === "1",
226
213
  doc: extractDoc(ctor),
227
214
  returnDoc: returnValue ? extractDoc(returnValue) : undefined,
228
- shadows: shadows || undefined,
229
- shadowedBy: shadowedBy || undefined,
215
+ shadows: ctor["@_shadows"] || undefined,
216
+ shadowedBy: ctor["@_shadowed-by"] || undefined,
230
217
  };
231
218
  });
232
219
  }
233
220
  parseFunctions(functions) {
234
- if (!functions || !Array.isArray(functions)) {
221
+ if (!functions || !Array.isArray(functions))
235
222
  return [];
236
- }
237
223
  return functions
238
- .filter((func) => this.isIntrospectable(func))
224
+ .filter((f) => f["@_introspectable"] !== "0")
239
225
  .map((func) => {
240
226
  const returnValue = func["return-value"];
241
- const shadows = func["@_shadows"];
242
- const shadowedBy = func["@_shadowed-by"];
243
227
  return {
244
228
  name: String(func["@_name"] ?? ""),
245
229
  cIdentifier: String(func["@_c:identifier"] ?? ""),
246
230
  returnType: this.parseReturnType(returnValue),
247
- parameters: this.parseParameters((func.parameters && typeof func.parameters === "object" && func.parameters !== null
248
- ? func.parameters
249
- : {})),
231
+ parameters: this.parseParameters(this.extractParametersNode(func)),
250
232
  throws: func["@_throws"] === "1",
251
233
  doc: extractDoc(func),
252
234
  returnDoc: returnValue ? extractDoc(returnValue) : undefined,
253
- shadows: shadows || undefined,
254
- shadowedBy: shadowedBy || undefined,
235
+ shadows: func["@_shadows"] || undefined,
236
+ shadowedBy: func["@_shadowed-by"] || undefined,
237
+ };
238
+ });
239
+ }
240
+ parseCallbacks(callbacks) {
241
+ if (!callbacks || !Array.isArray(callbacks))
242
+ return [];
243
+ return callbacks
244
+ .filter((cb) => cb["@_introspectable"] !== "0")
245
+ .map((cb) => ({
246
+ name: String(cb["@_name"] ?? ""),
247
+ cType: String(cb["@_c:type"] ?? ""),
248
+ returnType: this.parseReturnType(cb["return-value"]),
249
+ parameters: this.parseParameters(this.extractParametersNode(cb)),
250
+ doc: extractDoc(cb),
251
+ }));
252
+ }
253
+ parseRecords(records) {
254
+ if (!records || !Array.isArray(records))
255
+ return [];
256
+ return records.map((record) => ({
257
+ name: String(record["@_name"] ?? ""),
258
+ cType: String(record["@_c:type"] ?? record["@_glib:type-name"] ?? ""),
259
+ opaque: record["@_opaque"] === "1",
260
+ disguised: record["@_disguised"] === "1",
261
+ glibTypeName: record["@_glib:type-name"] ? String(record["@_glib:type-name"]) : undefined,
262
+ glibGetType: record["@_glib:get-type"] ? String(record["@_glib:get-type"]) : undefined,
263
+ isGtypeStructFor: record["@_glib:is-gtype-struct-for"]
264
+ ? String(record["@_glib:is-gtype-struct-for"])
265
+ : undefined,
266
+ copyFunction: record["@_copy-function"] ? String(record["@_copy-function"]) : undefined,
267
+ freeFunction: record["@_free-function"] ? String(record["@_free-function"]) : undefined,
268
+ fields: this.parseFields(ensureArray(record.field)),
269
+ methods: this.parseMethods(ensureArray(record.method)),
270
+ constructors: this.parseConstructors(ensureArray(record._constructor)),
271
+ functions: this.parseFunctions(ensureArray(record.function)),
272
+ doc: extractDoc(record),
273
+ }));
274
+ }
275
+ parseEnumerations(enumerations) {
276
+ if (!enumerations || !Array.isArray(enumerations))
277
+ return [];
278
+ return enumerations.map((enumeration) => ({
279
+ name: String(enumeration["@_name"] ?? ""),
280
+ cType: String(enumeration["@_c:type"] ?? ""),
281
+ members: this.parseEnumerationMembers(ensureArray(enumeration.member)),
282
+ glibGetType: typeof enumeration["@_glib:get-type"] === "string" ? enumeration["@_glib:get-type"] : undefined,
283
+ doc: extractDoc(enumeration),
284
+ }));
285
+ }
286
+ parseEnumerationMembers(members) {
287
+ if (!members || !Array.isArray(members))
288
+ return [];
289
+ return members.map((member) => ({
290
+ name: String(member["@_name"] ?? ""),
291
+ value: String(member["@_value"] ?? ""),
292
+ cIdentifier: String(member["@_c:identifier"] ?? ""),
293
+ doc: extractDoc(member),
294
+ }));
295
+ }
296
+ parseConstants(constants) {
297
+ if (!constants || !Array.isArray(constants))
298
+ return [];
299
+ return constants.map((constant) => ({
300
+ name: String(constant["@_name"] ?? ""),
301
+ cType: String(constant["@_c:type"] ?? ""),
302
+ value: String(constant["@_value"] ?? ""),
303
+ type: this.parseType((constant.type ?? constant.array)),
304
+ doc: extractDoc(constant),
305
+ }));
306
+ }
307
+ parseAliases(aliases) {
308
+ if (!aliases || !Array.isArray(aliases))
309
+ return [];
310
+ return aliases.map((alias) => ({
311
+ name: String(alias["@_name"] ?? ""),
312
+ cType: String(alias["@_c:type"] ?? ""),
313
+ targetType: this.parseType(alias.type),
314
+ doc: extractDoc(alias),
315
+ }));
316
+ }
317
+ parseProperties(properties) {
318
+ if (!properties || !Array.isArray(properties))
319
+ return [];
320
+ return properties.map((prop) => {
321
+ let getter = prop["@_getter"] ? String(prop["@_getter"]) : undefined;
322
+ let setter = prop["@_setter"] ? String(prop["@_setter"]) : undefined;
323
+ const attributes = prop.attribute;
324
+ if (attributes) {
325
+ const attrList = Array.isArray(attributes) ? attributes : [attributes];
326
+ for (const attr of attrList) {
327
+ if (attr["@_name"] === "org.gtk.Property.get" && attr["@_value"]) {
328
+ getter = String(attr["@_value"]);
329
+ }
330
+ else if (attr["@_name"] === "org.gtk.Property.set" && attr["@_value"]) {
331
+ setter = String(attr["@_value"]);
332
+ }
333
+ }
334
+ }
335
+ return {
336
+ name: String(prop["@_name"] ?? ""),
337
+ type: this.parseType((prop.type ?? prop.array)),
338
+ readable: prop["@_readable"] !== "0",
339
+ writable: prop["@_writable"] === "1",
340
+ constructOnly: prop["@_construct-only"] === "1",
341
+ defaultValueRaw: prop["@_default-value"] !== undefined ? String(prop["@_default-value"]) : undefined,
342
+ getter,
343
+ setter,
344
+ doc: extractDoc(prop),
345
+ };
346
+ });
347
+ }
348
+ parseSignals(signals) {
349
+ if (!signals || !Array.isArray(signals))
350
+ return [];
351
+ return signals.map((signal) => {
352
+ const whenValue = String(signal["@_when"] ?? "last");
353
+ const validWhen = whenValue === "first" || whenValue === "last" || whenValue === "cleanup";
354
+ return {
355
+ name: String(signal["@_name"] ?? ""),
356
+ when: validWhen ? whenValue : "last",
357
+ returnType: signal["return-value"]
358
+ ? this.parseReturnType(signal["return-value"])
359
+ : undefined,
360
+ parameters: signal.parameters && typeof signal.parameters === "object" && signal.parameters !== null
361
+ ? this.parseParameters(signal.parameters)
362
+ : [],
363
+ doc: extractDoc(signal),
255
364
  };
256
365
  });
257
366
  }
367
+ parseFields(fields) {
368
+ if (!fields || !Array.isArray(fields))
369
+ return [];
370
+ return fields
371
+ .filter((field) => field.callback === undefined)
372
+ .map((field) => ({
373
+ name: String(field["@_name"] ?? ""),
374
+ type: this.parseType((field.type ?? field.array)),
375
+ writable: field["@_writable"] === "1",
376
+ readable: field["@_readable"] !== "0",
377
+ private: field["@_private"] === "1",
378
+ doc: extractDoc(field),
379
+ }));
380
+ }
381
+ extractParametersNode(node) {
382
+ return node.parameters && typeof node.parameters === "object" && node.parameters !== null
383
+ ? node.parameters
384
+ : {};
385
+ }
258
386
  parseParameters(parametersNode) {
259
- if (!parametersNode?.parameter) {
387
+ if (!parametersNode?.parameter)
260
388
  return [];
261
- }
262
389
  const params = Array.isArray(parametersNode.parameter) ? parametersNode.parameter : [parametersNode.parameter];
263
390
  return params.map((param) => this.parseSingleParameter(param));
264
391
  }
265
392
  parseInstanceParameter(parametersNode) {
266
393
  const instanceParam = parametersNode?.["instance-parameter"];
267
- if (!instanceParam) {
394
+ if (!instanceParam)
268
395
  return undefined;
269
- }
270
396
  return this.parseSingleParameter(instanceParam);
271
397
  }
272
398
  parseSingleParameter(param) {
@@ -292,9 +418,8 @@ export class RawGirParser {
292
418
  };
293
419
  }
294
420
  parseReturnType(returnValue) {
295
- if (!returnValue) {
421
+ if (!returnValue)
296
422
  return { name: "void" };
297
- }
298
423
  const type = this.parseType((returnValue.type ?? returnValue.array));
299
424
  const transferOwnership = returnValue["@_transfer-ownership"];
300
425
  if (transferOwnership === "none" || transferOwnership === "full" || transferOwnership === "container") {
@@ -306,33 +431,27 @@ export class RawGirParser {
306
431
  return type;
307
432
  }
308
433
  parseType(typeNode) {
309
- if (!typeNode) {
434
+ if (!typeNode)
310
435
  return { name: "void" };
311
- }
312
436
  const typeName = typeNode["@_name"] ? String(typeNode["@_name"]) : undefined;
313
437
  const cType = typeNode["@_c:type"] ? String(typeNode["@_c:type"]) : undefined;
314
438
  const containerResult = this.parseGLibContainerType(typeName, typeNode, cType);
315
- if (containerResult) {
439
+ if (containerResult)
316
440
  return containerResult;
317
- }
318
- if (typeName) {
441
+ if (typeName)
319
442
  return { name: typeName, cType };
320
- }
321
443
  const isArrayNode = typeNode.type ||
322
444
  typeNode["@_zero-terminated"] !== undefined ||
323
445
  typeNode["@_fixed-size"] !== undefined ||
324
446
  typeNode["@_length"] !== undefined;
325
447
  if (isArrayNode) {
326
- const lengthAttr = typeNode["@_length"];
327
- const zeroTerminatedAttr = typeNode["@_zero-terminated"];
328
- const fixedSizeAttr = typeNode["@_fixed-size"];
329
448
  return {
330
449
  name: "array",
331
450
  isArray: true,
332
451
  elementType: typeNode.type ? this.parseType(typeNode.type) : undefined,
333
- sizeParamIndex: lengthAttr !== undefined ? Number(lengthAttr) : undefined,
334
- zeroTerminated: zeroTerminatedAttr !== undefined ? zeroTerminatedAttr !== "0" : undefined,
335
- fixedSize: fixedSizeAttr !== undefined ? Number(fixedSizeAttr) : undefined,
452
+ sizeParamIndex: typeNode["@_length"] !== undefined ? Number(typeNode["@_length"]) : undefined,
453
+ zeroTerminated: typeNode["@_zero-terminated"] !== undefined ? typeNode["@_zero-terminated"] !== "0" : undefined,
454
+ fixedSize: typeNode["@_fixed-size"] !== undefined ? Number(typeNode["@_fixed-size"]) : undefined,
336
455
  };
337
456
  }
338
457
  return { name: "void" };
@@ -382,6 +501,15 @@ export class RawGirParser {
382
501
  elementType: typeParams[0],
383
502
  };
384
503
  }
504
+ if (typeName === "GLib.ByteArray") {
505
+ return {
506
+ name: typeName,
507
+ cType,
508
+ isArray: true,
509
+ containerType: "gbytearray",
510
+ elementType: { name: "guint8", cType: "guint8" },
511
+ };
512
+ }
385
513
  if (typeName === "GLib.List" || typeName === "GLib.SList") {
386
514
  const innerType = (typeNode.type ?? typeNode.array);
387
515
  const elementType = innerType ? this.parseType(innerType) : undefined;
@@ -396,149 +524,5 @@ export class RawGirParser {
396
524
  }
397
525
  return null;
398
526
  }
399
- parseProperties(properties) {
400
- if (!properties || !Array.isArray(properties)) {
401
- return [];
402
- }
403
- return properties.map((prop) => {
404
- let getter = prop["@_getter"] ? String(prop["@_getter"]) : undefined;
405
- let setter = prop["@_setter"] ? String(prop["@_setter"]) : undefined;
406
- const attributes = prop.attribute;
407
- if (attributes) {
408
- const attrList = Array.isArray(attributes) ? attributes : [attributes];
409
- for (const attr of attrList) {
410
- const attrName = attr["@_name"];
411
- const attrValue = attr["@_value"];
412
- if (attrName === "org.gtk.Property.get" && attrValue) {
413
- getter = String(attrValue);
414
- }
415
- else if (attrName === "org.gtk.Property.set" && attrValue) {
416
- setter = String(attrValue);
417
- }
418
- }
419
- }
420
- return {
421
- name: String(prop["@_name"] ?? ""),
422
- type: this.parseType((prop.type ?? prop.array)),
423
- readable: prop["@_readable"] !== "0",
424
- writable: prop["@_writable"] === "1",
425
- constructOnly: prop["@_construct-only"] === "1",
426
- defaultValueRaw: prop["@_default-value"] !== undefined ? String(prop["@_default-value"]) : undefined,
427
- getter,
428
- setter,
429
- doc: extractDoc(prop),
430
- };
431
- });
432
- }
433
- parseSignals(signals) {
434
- if (!signals || !Array.isArray(signals)) {
435
- return [];
436
- }
437
- return signals.map((signal) => {
438
- const whenValue = String(signal["@_when"] ?? "last");
439
- const validWhen = whenValue === "first" || whenValue === "last" || whenValue === "cleanup";
440
- return {
441
- name: String(signal["@_name"] ?? ""),
442
- when: validWhen ? whenValue : "last",
443
- returnType: signal["return-value"]
444
- ? this.parseReturnType(signal["return-value"])
445
- : undefined,
446
- parameters: signal.parameters && typeof signal.parameters === "object" && signal.parameters !== null
447
- ? this.parseParameters(signal.parameters)
448
- : [],
449
- doc: extractDoc(signal),
450
- };
451
- });
452
- }
453
- parseRecords(records) {
454
- if (!records || !Array.isArray(records)) {
455
- return [];
456
- }
457
- return records.map((record) => ({
458
- name: String(record["@_name"] ?? ""),
459
- cType: String(record["@_c:type"] ?? record["@_glib:type-name"] ?? ""),
460
- opaque: record["@_opaque"] === "1",
461
- disguised: record["@_disguised"] === "1",
462
- glibTypeName: record["@_glib:type-name"] ? String(record["@_glib:type-name"]) : undefined,
463
- glibGetType: record["@_glib:get-type"] ? String(record["@_glib:get-type"]) : undefined,
464
- isGtypeStructFor: record["@_glib:is-gtype-struct-for"]
465
- ? String(record["@_glib:is-gtype-struct-for"])
466
- : undefined,
467
- copyFunction: record["@_copy-function"] ? String(record["@_copy-function"]) : undefined,
468
- freeFunction: record["@_free-function"] ? String(record["@_free-function"]) : undefined,
469
- fields: this.parseFields(ensureArray(record.field)),
470
- methods: this.parseMethods(ensureArray(record.method)),
471
- constructors: this.parseConstructors(ensureArray(record.constructor)),
472
- functions: this.parseFunctions(ensureArray(record.function)),
473
- doc: extractDoc(record),
474
- }));
475
- }
476
- parseFields(fields) {
477
- if (!fields || !Array.isArray(fields)) {
478
- return [];
479
- }
480
- return fields
481
- .filter((field) => {
482
- const hasCallback = field.callback !== undefined;
483
- return !hasCallback;
484
- })
485
- .map((field) => ({
486
- name: String(field["@_name"] ?? ""),
487
- type: this.parseType((field.type ?? field.array)),
488
- writable: field["@_writable"] === "1",
489
- readable: field["@_readable"] !== "0",
490
- private: field["@_private"] === "1",
491
- doc: extractDoc(field),
492
- }));
493
- }
494
- parseEnumerations(enumerations) {
495
- if (!enumerations || !Array.isArray(enumerations)) {
496
- return [];
497
- }
498
- return enumerations.map((enumeration) => {
499
- const glibGetType = enumeration["@_glib:get-type"];
500
- return {
501
- name: String(enumeration["@_name"] ?? ""),
502
- cType: String(enumeration["@_c:type"] ?? ""),
503
- members: this.parseEnumerationMembers(ensureArray(enumeration.member)),
504
- glibGetType: typeof glibGetType === "string" ? glibGetType : undefined,
505
- doc: extractDoc(enumeration),
506
- };
507
- });
508
- }
509
- parseEnumerationMembers(members) {
510
- if (!members || !Array.isArray(members)) {
511
- return [];
512
- }
513
- return members.map((member) => ({
514
- name: String(member["@_name"] ?? ""),
515
- value: String(member["@_value"] ?? ""),
516
- cIdentifier: String(member["@_c:identifier"] ?? ""),
517
- doc: extractDoc(member),
518
- }));
519
- }
520
- parseConstants(constants) {
521
- if (!constants || !Array.isArray(constants)) {
522
- return [];
523
- }
524
- return constants.map((constant) => ({
525
- name: String(constant["@_name"] ?? ""),
526
- cType: String(constant["@_c:type"] ?? ""),
527
- value: String(constant["@_value"] ?? ""),
528
- type: this.parseType((constant.type ?? constant.array)),
529
- doc: extractDoc(constant),
530
- }));
531
- }
532
- parseAliases(aliases) {
533
- if (!aliases || !Array.isArray(aliases)) {
534
- return [];
535
- }
536
- return aliases.map((alias) => ({
537
- name: String(alias["@_name"] ?? ""),
538
- cType: String(alias["@_c:type"] ?? ""),
539
- targetType: this.parseType(alias.type),
540
- doc: extractDoc(alias),
541
- }));
542
- }
543
527
  }
544
528
  //# sourceMappingURL=parser.js.map