@gtkx/gir 0.10.5 → 0.11.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/dist/index.d.ts +27 -5
- package/dist/index.js +26 -5
- package/dist/internal/normalizer.d.ts +22 -0
- package/dist/internal/normalizer.js +398 -0
- package/dist/internal/parser.d.ts +42 -0
- package/dist/{parser.js → internal/parser.js} +67 -55
- package/dist/internal/raw-types.d.ts +223 -0
- package/dist/internal/raw-types.js +9 -0
- package/dist/intrinsics.d.ts +39 -0
- package/dist/intrinsics.js +122 -0
- package/dist/repository.d.ts +151 -0
- package/dist/repository.js +322 -0
- package/dist/types.d.ts +517 -483
- package/dist/types.js +743 -1085
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +10 -0
- package/package.json +4 -2
- package/dist/class-names.d.ts +0 -2
- package/dist/class-names.js +0 -12
- package/dist/doc-sanitizer.d.ts +0 -13
- package/dist/doc-sanitizer.js +0 -334
- package/dist/naming.d.ts +0 -6
- package/dist/naming.js +0 -69
- package/dist/parser.d.ts +0 -76
package/dist/types.js
CHANGED
|
@@ -1,1123 +1,781 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GIR
|
|
2
|
+
* Normalized GIR types with helper methods.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @packageDocumentation
|
|
4
|
+
* All type references use fully qualified names (Namespace.TypeName)
|
|
5
|
+
* except for intrinsic types which remain unqualified.
|
|
8
6
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import { toCamelCase, toPascalCase } from "./naming.js";
|
|
11
|
-
export { toCamelCase, toPascalCase };
|
|
7
|
+
import { isIntrinsicType, isNumericType, isStringType, isVoidType } from "./intrinsics.js";
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @param classes - Array of parsed GIR classes
|
|
16
|
-
* @returns Map keyed by class name for O(1) lookup
|
|
9
|
+
* Creates a QualifiedName from namespace and type name.
|
|
17
10
|
*/
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
for (const cls of classes) {
|
|
21
|
-
classMap.set(cls.name, cls);
|
|
22
|
-
}
|
|
23
|
-
return classMap;
|
|
11
|
+
export const qualifiedName = (namespace, name) => {
|
|
12
|
+
return `${namespace}.${name}`;
|
|
24
13
|
};
|
|
25
14
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param typeMapper - The type mapper to register enums with
|
|
29
|
-
* @param namespace - The parsed GIR namespace containing enums
|
|
15
|
+
* Parses a QualifiedName into its parts.
|
|
30
16
|
*/
|
|
31
|
-
export const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
17
|
+
export const parseQualifiedName = (qn) => {
|
|
18
|
+
const dot = qn.indexOf(".");
|
|
19
|
+
return {
|
|
20
|
+
namespace: qn.slice(0, dot),
|
|
21
|
+
name: qn.slice(dot + 1),
|
|
22
|
+
};
|
|
38
23
|
};
|
|
39
24
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Enables cross-namespace type resolution by maintaining a map of
|
|
43
|
-
* all known types from all loaded namespaces.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```tsx
|
|
47
|
-
* const registry = TypeRegistry.fromNamespaces([gtkNamespace, gioNamespace]);
|
|
48
|
-
* const buttonType = registry.resolve("Gtk.Button");
|
|
49
|
-
* ```
|
|
25
|
+
* Normalized namespace containing all resolved types.
|
|
50
26
|
*/
|
|
51
|
-
export class
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
* Registers a callback type.
|
|
142
|
-
*
|
|
143
|
-
* @param namespace - The GIR namespace
|
|
144
|
-
* @param name - The callback name
|
|
145
|
-
*/
|
|
146
|
-
registerCallback(namespace, name) {
|
|
147
|
-
const transformedName = toPascalCase(name);
|
|
148
|
-
this.types.set(`${namespace}.${name}`, {
|
|
149
|
-
kind: "callback",
|
|
150
|
-
name,
|
|
151
|
-
namespace,
|
|
152
|
-
transformedName,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Resolves a fully qualified type name.
|
|
157
|
-
*
|
|
158
|
-
* @param qualifiedName - Type name in "Namespace.TypeName" format
|
|
159
|
-
* @returns The registered type, or undefined if not found
|
|
160
|
-
*/
|
|
161
|
-
resolve(qualifiedName) {
|
|
162
|
-
return this.types.get(qualifiedName);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Resolves a type name within a namespace context.
|
|
166
|
-
*
|
|
167
|
-
* First checks the current namespace, then falls back to
|
|
168
|
-
* searching all registered types.
|
|
169
|
-
*
|
|
170
|
-
* @param name - Type name (may be unqualified)
|
|
171
|
-
* @param currentNamespace - The namespace to search first
|
|
172
|
-
* @returns The registered type, or undefined if not found
|
|
173
|
-
*/
|
|
174
|
-
resolveInNamespace(name, currentNamespace) {
|
|
175
|
-
if (name.includes(".")) {
|
|
176
|
-
return this.resolve(name);
|
|
177
|
-
}
|
|
178
|
-
const inCurrent = this.resolve(`${currentNamespace}.${name}`);
|
|
179
|
-
if (inCurrent) {
|
|
180
|
-
return inCurrent;
|
|
27
|
+
export class GirNamespace {
|
|
28
|
+
name;
|
|
29
|
+
version;
|
|
30
|
+
sharedLibrary;
|
|
31
|
+
cPrefix;
|
|
32
|
+
classes;
|
|
33
|
+
interfaces;
|
|
34
|
+
records;
|
|
35
|
+
enumerations;
|
|
36
|
+
bitfields;
|
|
37
|
+
callbacks;
|
|
38
|
+
functions;
|
|
39
|
+
constants;
|
|
40
|
+
doc;
|
|
41
|
+
constructor(data) {
|
|
42
|
+
this.name = data.name;
|
|
43
|
+
this.version = data.version;
|
|
44
|
+
this.sharedLibrary = data.sharedLibrary;
|
|
45
|
+
this.cPrefix = data.cPrefix;
|
|
46
|
+
this.classes = data.classes;
|
|
47
|
+
this.interfaces = data.interfaces;
|
|
48
|
+
this.records = data.records;
|
|
49
|
+
this.enumerations = data.enumerations;
|
|
50
|
+
this.bitfields = data.bitfields;
|
|
51
|
+
this.callbacks = data.callbacks;
|
|
52
|
+
this.functions = data.functions;
|
|
53
|
+
this.constants = data.constants;
|
|
54
|
+
this.doc = data.doc;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Normalized class with helper methods.
|
|
59
|
+
*/
|
|
60
|
+
export class GirClass {
|
|
61
|
+
name;
|
|
62
|
+
qualifiedName;
|
|
63
|
+
cType;
|
|
64
|
+
parent;
|
|
65
|
+
abstract;
|
|
66
|
+
glibTypeName;
|
|
67
|
+
glibGetType;
|
|
68
|
+
cSymbolPrefix;
|
|
69
|
+
implements;
|
|
70
|
+
methods;
|
|
71
|
+
constructors;
|
|
72
|
+
staticFunctions;
|
|
73
|
+
properties;
|
|
74
|
+
signals;
|
|
75
|
+
doc;
|
|
76
|
+
/** @internal */
|
|
77
|
+
_repo;
|
|
78
|
+
constructor(data) {
|
|
79
|
+
this.name = data.name;
|
|
80
|
+
this.qualifiedName = data.qualifiedName;
|
|
81
|
+
this.cType = data.cType;
|
|
82
|
+
this.parent = data.parent;
|
|
83
|
+
this.abstract = data.abstract;
|
|
84
|
+
this.glibTypeName = data.glibTypeName;
|
|
85
|
+
this.glibGetType = data.glibGetType;
|
|
86
|
+
this.cSymbolPrefix = data.cSymbolPrefix;
|
|
87
|
+
this.implements = data.implements;
|
|
88
|
+
this.methods = data.methods;
|
|
89
|
+
this.constructors = data.constructors;
|
|
90
|
+
this.staticFunctions = data.staticFunctions;
|
|
91
|
+
this.properties = data.properties;
|
|
92
|
+
this.signals = data.signals;
|
|
93
|
+
this.doc = data.doc;
|
|
94
|
+
}
|
|
95
|
+
/** @internal */
|
|
96
|
+
_setRepository(repo) {
|
|
97
|
+
this._repo = repo;
|
|
98
|
+
}
|
|
99
|
+
/** Checks if this class is a subclass of another (direct or transitive). */
|
|
100
|
+
isSubclassOf(qualifiedName) {
|
|
101
|
+
if (this.qualifiedName === qualifiedName)
|
|
102
|
+
return true;
|
|
103
|
+
if (!this.parent || !this._repo)
|
|
104
|
+
return false;
|
|
105
|
+
if (this.parent === qualifiedName)
|
|
106
|
+
return true;
|
|
107
|
+
const parentClass = this._repo.resolveClass(this.parent);
|
|
108
|
+
return parentClass?.isSubclassOf(qualifiedName) ?? false;
|
|
109
|
+
}
|
|
110
|
+
/** Gets the full inheritance chain from this class to the root. */
|
|
111
|
+
getInheritanceChain() {
|
|
112
|
+
const chain = [this.qualifiedName];
|
|
113
|
+
let current = this;
|
|
114
|
+
while (current?.parent && this._repo) {
|
|
115
|
+
chain.push(current.parent);
|
|
116
|
+
current = this._repo.resolveClass(current.parent);
|
|
181
117
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
118
|
+
return chain;
|
|
119
|
+
}
|
|
120
|
+
/** Gets the parent class object, or null if this is a root class. */
|
|
121
|
+
getParent() {
|
|
122
|
+
return this.parent && this._repo ? this._repo.resolveClass(this.parent) : null;
|
|
123
|
+
}
|
|
124
|
+
/** Checks if this class directly or transitively implements an interface. */
|
|
125
|
+
implementsInterface(qualifiedName) {
|
|
126
|
+
if (this.implements.includes(qualifiedName))
|
|
127
|
+
return true;
|
|
128
|
+
const parent = this.getParent();
|
|
129
|
+
return parent?.implementsInterface(qualifiedName) ?? false;
|
|
130
|
+
}
|
|
131
|
+
/** Gets all implemented interfaces including inherited ones. */
|
|
132
|
+
getAllImplementedInterfaces() {
|
|
133
|
+
const interfaces = new Set(this.implements);
|
|
134
|
+
let current = this.getParent();
|
|
135
|
+
while (current) {
|
|
136
|
+
for (const iface of current.implements) {
|
|
137
|
+
interfaces.add(iface);
|
|
185
138
|
}
|
|
139
|
+
current = current.getParent();
|
|
140
|
+
}
|
|
141
|
+
return [...interfaces];
|
|
142
|
+
}
|
|
143
|
+
/** Finds a method defined on this class by name. */
|
|
144
|
+
getMethod(name) {
|
|
145
|
+
return this.methods.find((m) => m.name === name) ?? null;
|
|
146
|
+
}
|
|
147
|
+
/** Finds a property defined on this class by name. */
|
|
148
|
+
getProperty(name) {
|
|
149
|
+
return this.properties.find((p) => p.name === name) ?? null;
|
|
150
|
+
}
|
|
151
|
+
/** Finds a signal defined on this class by name. */
|
|
152
|
+
getSignal(name) {
|
|
153
|
+
return this.signals.find((s) => s.name === name) ?? null;
|
|
154
|
+
}
|
|
155
|
+
/** Finds a constructor by name. */
|
|
156
|
+
getConstructor(name) {
|
|
157
|
+
return this.constructors.find((c) => c.name === name) ?? null;
|
|
158
|
+
}
|
|
159
|
+
/** Gets all methods including inherited ones. */
|
|
160
|
+
getAllMethods() {
|
|
161
|
+
const methods = [...this.methods];
|
|
162
|
+
let current = this.getParent();
|
|
163
|
+
while (current) {
|
|
164
|
+
methods.push(...current.methods);
|
|
165
|
+
current = current.getParent();
|
|
186
166
|
}
|
|
167
|
+
return methods;
|
|
168
|
+
}
|
|
169
|
+
/** Gets all properties including inherited ones. */
|
|
170
|
+
getAllProperties() {
|
|
171
|
+
const properties = [...this.properties];
|
|
172
|
+
let current = this.getParent();
|
|
173
|
+
while (current) {
|
|
174
|
+
properties.push(...current.properties);
|
|
175
|
+
current = current.getParent();
|
|
176
|
+
}
|
|
177
|
+
return properties;
|
|
178
|
+
}
|
|
179
|
+
/** Gets all signals including inherited ones. */
|
|
180
|
+
getAllSignals() {
|
|
181
|
+
const signals = [...this.signals];
|
|
182
|
+
let current = this.getParent();
|
|
183
|
+
while (current) {
|
|
184
|
+
signals.push(...current.signals);
|
|
185
|
+
current = current.getParent();
|
|
186
|
+
}
|
|
187
|
+
return signals;
|
|
188
|
+
}
|
|
189
|
+
/** Finds a method by name, searching up the inheritance chain. */
|
|
190
|
+
findMethod(name) {
|
|
191
|
+
const own = this.getMethod(name);
|
|
192
|
+
if (own)
|
|
193
|
+
return own;
|
|
194
|
+
return this.getParent()?.findMethod(name) ?? null;
|
|
195
|
+
}
|
|
196
|
+
/** Finds a property by name, searching up the inheritance chain. */
|
|
197
|
+
findProperty(name) {
|
|
198
|
+
const own = this.getProperty(name);
|
|
199
|
+
if (own)
|
|
200
|
+
return own;
|
|
201
|
+
return this.getParent()?.findProperty(name) ?? null;
|
|
202
|
+
}
|
|
203
|
+
/** Finds a signal by name, searching up the inheritance chain. */
|
|
204
|
+
findSignal(name) {
|
|
205
|
+
const own = this.getSignal(name);
|
|
206
|
+
if (own)
|
|
207
|
+
return own;
|
|
208
|
+
return this.getParent()?.findSignal(name) ?? null;
|
|
209
|
+
}
|
|
210
|
+
/** True if this is an abstract class. */
|
|
211
|
+
isAbstract() {
|
|
212
|
+
return this.abstract;
|
|
213
|
+
}
|
|
214
|
+
/** True if this has a GType (most GObject classes do). */
|
|
215
|
+
hasGType() {
|
|
216
|
+
return this.glibTypeName !== undefined;
|
|
217
|
+
}
|
|
218
|
+
/** Gets direct subclasses of this class. */
|
|
219
|
+
getDirectSubclasses() {
|
|
220
|
+
if (!this._repo)
|
|
221
|
+
return [];
|
|
222
|
+
return this._repo.findClasses((cls) => cls.parent === this.qualifiedName);
|
|
187
223
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Normalized interface with helper methods.
|
|
227
|
+
*/
|
|
228
|
+
export class GirInterface {
|
|
229
|
+
name;
|
|
230
|
+
qualifiedName;
|
|
231
|
+
cType;
|
|
232
|
+
glibTypeName;
|
|
233
|
+
prerequisites;
|
|
234
|
+
methods;
|
|
235
|
+
properties;
|
|
236
|
+
signals;
|
|
237
|
+
doc;
|
|
238
|
+
/** @internal */
|
|
239
|
+
_repo;
|
|
240
|
+
constructor(data) {
|
|
241
|
+
this.name = data.name;
|
|
242
|
+
this.qualifiedName = data.qualifiedName;
|
|
243
|
+
this.cType = data.cType;
|
|
244
|
+
this.glibTypeName = data.glibTypeName;
|
|
245
|
+
this.prerequisites = data.prerequisites;
|
|
246
|
+
this.methods = data.methods;
|
|
247
|
+
this.properties = data.properties;
|
|
248
|
+
this.signals = data.signals;
|
|
249
|
+
this.doc = data.doc;
|
|
250
|
+
}
|
|
251
|
+
/** @internal */
|
|
252
|
+
_setRepository(repo) {
|
|
253
|
+
this._repo = repo;
|
|
254
|
+
}
|
|
255
|
+
/** Checks if this interface has a prerequisite (direct or transitive). */
|
|
256
|
+
hasPrerequisite(qualifiedName) {
|
|
257
|
+
if (this.prerequisites.includes(qualifiedName))
|
|
258
|
+
return true;
|
|
259
|
+
if (!this._repo)
|
|
260
|
+
return false;
|
|
261
|
+
for (const prereq of this.prerequisites) {
|
|
262
|
+
const prereqIface = this._repo.resolveInterface(prereq);
|
|
263
|
+
if (prereqIface?.hasPrerequisite(qualifiedName))
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
/** Gets all prerequisites including transitive ones. */
|
|
269
|
+
getAllPrerequisites() {
|
|
270
|
+
const all = new Set(this.prerequisites);
|
|
271
|
+
if (this._repo) {
|
|
272
|
+
for (const prereq of this.prerequisites) {
|
|
273
|
+
const prereqIface = this._repo.resolveInterface(prereq);
|
|
274
|
+
if (prereqIface) {
|
|
275
|
+
for (const p of prereqIface.getAllPrerequisites()) {
|
|
276
|
+
all.add(p);
|
|
277
|
+
}
|
|
226
278
|
}
|
|
227
279
|
}
|
|
228
|
-
for (const callback of ns.callbacks) {
|
|
229
|
-
registry.registerCallback(ns.name, callback.name);
|
|
230
|
-
}
|
|
231
280
|
}
|
|
232
|
-
return
|
|
281
|
+
return [...all];
|
|
282
|
+
}
|
|
283
|
+
/** Finds a method by name. */
|
|
284
|
+
getMethod(name) {
|
|
285
|
+
return this.methods.find((m) => m.name === name) ?? null;
|
|
286
|
+
}
|
|
287
|
+
/** Finds a property by name. */
|
|
288
|
+
getProperty(name) {
|
|
289
|
+
return this.properties.find((p) => p.name === name) ?? null;
|
|
290
|
+
}
|
|
291
|
+
/** Finds a signal by name. */
|
|
292
|
+
getSignal(name) {
|
|
293
|
+
return this.signals.find((s) => s.name === name) ?? null;
|
|
233
294
|
}
|
|
234
295
|
}
|
|
235
|
-
const STRING_TYPES = new Set(["utf8", "filename"]);
|
|
236
|
-
const PRIMITIVE_TYPES = new Set([
|
|
237
|
-
"gint",
|
|
238
|
-
"guint",
|
|
239
|
-
"gint8",
|
|
240
|
-
"guint8",
|
|
241
|
-
"gint16",
|
|
242
|
-
"guint16",
|
|
243
|
-
"gint32",
|
|
244
|
-
"guint32",
|
|
245
|
-
"gint64",
|
|
246
|
-
"guint64",
|
|
247
|
-
"gfloat",
|
|
248
|
-
"gdouble",
|
|
249
|
-
"gboolean",
|
|
250
|
-
"gchar",
|
|
251
|
-
"guchar",
|
|
252
|
-
"gsize",
|
|
253
|
-
"gssize",
|
|
254
|
-
"glong",
|
|
255
|
-
"gulong",
|
|
256
|
-
]);
|
|
257
296
|
/**
|
|
258
|
-
*
|
|
259
|
-
* Used to determine if a plain struct can be safely generated.
|
|
260
|
-
* Records with only private fields are considered opaque and should not be plain structs.
|
|
297
|
+
* Normalized record (boxed type or plain struct) with helper methods.
|
|
261
298
|
*/
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
299
|
+
export class GirRecord {
|
|
300
|
+
name;
|
|
301
|
+
qualifiedName;
|
|
302
|
+
cType;
|
|
303
|
+
opaque;
|
|
304
|
+
disguised;
|
|
305
|
+
glibTypeName;
|
|
306
|
+
glibGetType;
|
|
307
|
+
isGtypeStructFor;
|
|
308
|
+
fields;
|
|
309
|
+
methods;
|
|
310
|
+
constructors;
|
|
311
|
+
staticFunctions;
|
|
312
|
+
doc;
|
|
313
|
+
constructor(data) {
|
|
314
|
+
this.name = data.name;
|
|
315
|
+
this.qualifiedName = data.qualifiedName;
|
|
316
|
+
this.cType = data.cType;
|
|
317
|
+
this.opaque = data.opaque;
|
|
318
|
+
this.disguised = data.disguised;
|
|
319
|
+
this.glibTypeName = data.glibTypeName;
|
|
320
|
+
this.glibGetType = data.glibGetType;
|
|
321
|
+
this.isGtypeStructFor = data.isGtypeStructFor;
|
|
322
|
+
this.fields = data.fields;
|
|
323
|
+
this.methods = data.methods;
|
|
324
|
+
this.constructors = data.constructors;
|
|
325
|
+
this.staticFunctions = data.staticFunctions;
|
|
326
|
+
this.doc = data.doc;
|
|
327
|
+
}
|
|
328
|
+
/** True if this is a GLib boxed type (has glibTypeName). */
|
|
329
|
+
isBoxed() {
|
|
330
|
+
return this.glibTypeName !== undefined;
|
|
331
|
+
}
|
|
332
|
+
/** True if this is a GType struct (vtable for a class/interface). */
|
|
333
|
+
isGtypeStruct() {
|
|
334
|
+
return this.isGtypeStructFor !== undefined;
|
|
335
|
+
}
|
|
336
|
+
/** True if this is a plain C struct (no GType, has public fields). */
|
|
337
|
+
isPlainStruct() {
|
|
338
|
+
return !this.glibTypeName && !this.opaque && this.getPublicFields().length > 0;
|
|
339
|
+
}
|
|
340
|
+
/** Gets public (non-private) fields only. */
|
|
341
|
+
getPublicFields() {
|
|
342
|
+
return this.fields.filter((f) => !f.private);
|
|
343
|
+
}
|
|
344
|
+
/** Finds a method by name. */
|
|
345
|
+
getMethod(name) {
|
|
346
|
+
return this.methods.find((m) => m.name === name) ?? null;
|
|
347
|
+
}
|
|
348
|
+
/** Finds a field by name. */
|
|
349
|
+
getField(name) {
|
|
350
|
+
return this.fields.find((f) => f.name === name) ?? null;
|
|
351
|
+
}
|
|
352
|
+
/** Finds a constructor by name. */
|
|
353
|
+
getConstructor(name) {
|
|
354
|
+
return this.constructors.find((c) => c.name === name) ?? null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
268
357
|
/**
|
|
269
|
-
*
|
|
358
|
+
* Normalized enumeration with helper methods.
|
|
270
359
|
*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
360
|
+
export class GirEnumeration {
|
|
361
|
+
name;
|
|
362
|
+
qualifiedName;
|
|
363
|
+
cType;
|
|
364
|
+
members;
|
|
365
|
+
doc;
|
|
366
|
+
constructor(data) {
|
|
367
|
+
this.name = data.name;
|
|
368
|
+
this.qualifiedName = data.qualifiedName;
|
|
369
|
+
this.cType = data.cType;
|
|
370
|
+
this.members = data.members;
|
|
371
|
+
this.doc = data.doc;
|
|
372
|
+
}
|
|
373
|
+
/** Finds a member by name. */
|
|
374
|
+
getMember(name) {
|
|
375
|
+
return this.members.find((m) => m.name === name) ?? null;
|
|
376
|
+
}
|
|
377
|
+
/** Finds a member by value. */
|
|
378
|
+
getMemberByValue(value) {
|
|
379
|
+
return this.members.find((m) => m.value === value) ?? null;
|
|
380
|
+
}
|
|
381
|
+
/** Gets all member names. */
|
|
382
|
+
getMemberNames() {
|
|
383
|
+
return this.members.map((m) => m.name);
|
|
278
384
|
}
|
|
279
|
-
|
|
280
|
-
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Normalized enumeration member.
|
|
388
|
+
*/
|
|
389
|
+
export class GirEnumerationMember {
|
|
390
|
+
name;
|
|
391
|
+
value;
|
|
392
|
+
cIdentifier;
|
|
393
|
+
doc;
|
|
394
|
+
constructor(data) {
|
|
395
|
+
this.name = data.name;
|
|
396
|
+
this.value = data.value;
|
|
397
|
+
this.cIdentifier = data.cIdentifier;
|
|
398
|
+
this.doc = data.doc;
|
|
281
399
|
}
|
|
282
|
-
|
|
283
|
-
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Normalized callback type.
|
|
403
|
+
*/
|
|
404
|
+
export class GirCallback {
|
|
405
|
+
name;
|
|
406
|
+
qualifiedName;
|
|
407
|
+
cType;
|
|
408
|
+
returnType;
|
|
409
|
+
parameters;
|
|
410
|
+
doc;
|
|
411
|
+
constructor(data) {
|
|
412
|
+
this.name = data.name;
|
|
413
|
+
this.qualifiedName = data.qualifiedName;
|
|
414
|
+
this.cType = data.cType;
|
|
415
|
+
this.returnType = data.returnType;
|
|
416
|
+
this.parameters = data.parameters;
|
|
417
|
+
this.doc = data.doc;
|
|
284
418
|
}
|
|
285
|
-
|
|
286
|
-
};
|
|
419
|
+
}
|
|
287
420
|
/**
|
|
288
|
-
*
|
|
421
|
+
* Normalized constant.
|
|
289
422
|
*/
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
const finalSize = Math.ceil(currentOffset / maxAlignment) * maxAlignment;
|
|
308
|
-
return { size: finalSize, fields: result };
|
|
309
|
-
};
|
|
310
|
-
const POINTER_TYPE = { ts: "number", ffi: { type: "int", size: 64, unsigned: true } };
|
|
311
|
-
const C_TYPE_MAP = new Map([
|
|
312
|
-
["void", { ts: "void", ffi: { type: "undefined" } }],
|
|
313
|
-
["gboolean", { ts: "boolean", ffi: { type: "boolean" } }],
|
|
314
|
-
["gchar", { ts: "number", ffi: { type: "int", size: 8, unsigned: false } }],
|
|
315
|
-
["guchar", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
316
|
-
["gint", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
317
|
-
["guint", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
318
|
-
["gshort", { ts: "number", ffi: { type: "int", size: 16, unsigned: false } }],
|
|
319
|
-
["gushort", { ts: "number", ffi: { type: "int", size: 16, unsigned: true } }],
|
|
320
|
-
["glong", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
321
|
-
["gulong", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
322
|
-
["gint8", { ts: "number", ffi: { type: "int", size: 8, unsigned: false } }],
|
|
323
|
-
["guint8", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
324
|
-
["gint16", { ts: "number", ffi: { type: "int", size: 16, unsigned: false } }],
|
|
325
|
-
["guint16", { ts: "number", ffi: { type: "int", size: 16, unsigned: true } }],
|
|
326
|
-
["gint32", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
327
|
-
["guint32", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
328
|
-
["gint64", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
329
|
-
["guint64", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
330
|
-
["gfloat", { ts: "number", ffi: { type: "float", size: 32 } }],
|
|
331
|
-
["gdouble", { ts: "number", ffi: { type: "float", size: 64 } }],
|
|
332
|
-
["gsize", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
333
|
-
["gssize", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
334
|
-
["goffset", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
335
|
-
["int", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
336
|
-
["unsigned int", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
337
|
-
["long", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
338
|
-
["unsigned long", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
339
|
-
["double", { ts: "number", ffi: { type: "float", size: 64 } }],
|
|
340
|
-
["float", { ts: "number", ffi: { type: "float", size: 32 } }],
|
|
341
|
-
["size_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
342
|
-
["ssize_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
343
|
-
["GType", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
344
|
-
["GQuark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
345
|
-
]);
|
|
346
|
-
const mapCType = (cType) => {
|
|
347
|
-
if (!cType) {
|
|
348
|
-
return POINTER_TYPE;
|
|
349
|
-
}
|
|
350
|
-
if (cType.endsWith("*")) {
|
|
351
|
-
return POINTER_TYPE;
|
|
352
|
-
}
|
|
353
|
-
const mapped = C_TYPE_MAP.get(cType);
|
|
354
|
-
if (mapped) {
|
|
355
|
-
return mapped;
|
|
356
|
-
}
|
|
357
|
-
if (cType.startsWith("const ")) {
|
|
358
|
-
return mapCType(cType.slice(6));
|
|
359
|
-
}
|
|
360
|
-
return POINTER_TYPE;
|
|
361
|
-
};
|
|
362
|
-
const BASIC_TYPE_MAP = new Map([
|
|
363
|
-
["gboolean", { ts: "boolean", ffi: { type: "boolean" } }],
|
|
364
|
-
["gchar", { ts: "number", ffi: { type: "int", size: 8, unsigned: false } }],
|
|
365
|
-
["guchar", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
366
|
-
["gint", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
367
|
-
["guint", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
368
|
-
["gshort", { ts: "number", ffi: { type: "int", size: 16, unsigned: false } }],
|
|
369
|
-
["gushort", { ts: "number", ffi: { type: "int", size: 16, unsigned: true } }],
|
|
370
|
-
["glong", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
371
|
-
["gulong", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
372
|
-
["GType", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
373
|
-
["gint8", { ts: "number", ffi: { type: "int", size: 8, unsigned: false } }],
|
|
374
|
-
["guint8", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
375
|
-
["gint16", { ts: "number", ffi: { type: "int", size: 16, unsigned: false } }],
|
|
376
|
-
["guint16", { ts: "number", ffi: { type: "int", size: 16, unsigned: true } }],
|
|
377
|
-
["gint32", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
378
|
-
["guint32", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
379
|
-
["gint64", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
380
|
-
["guint64", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
381
|
-
["gfloat", { ts: "number", ffi: { type: "float", size: 32 } }],
|
|
382
|
-
["gdouble", { ts: "number", ffi: { type: "float", size: 64 } }],
|
|
383
|
-
["gpointer", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
384
|
-
["gconstpointer", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
385
|
-
["gsize", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
386
|
-
["gssize", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
387
|
-
["goffset", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
388
|
-
["guintptr", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
389
|
-
["gintptr", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
390
|
-
["pid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
391
|
-
["uid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
392
|
-
["gid_t", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
393
|
-
["time_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
394
|
-
["Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
395
|
-
["GLib.Quark", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
396
|
-
["TimeSpan", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
397
|
-
["GLib.TimeSpan", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
398
|
-
["DateDay", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
399
|
-
["GLib.DateDay", { ts: "number", ffi: { type: "int", size: 8, unsigned: true } }],
|
|
400
|
-
["DateYear", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
401
|
-
["GLib.DateYear", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
402
|
-
["DateMonth", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
403
|
-
["GLib.DateMonth", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
404
|
-
["Pid", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
405
|
-
["GLib.Pid", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
406
|
-
["void", { ts: "void", ffi: { type: "undefined" } }],
|
|
407
|
-
["none", { ts: "void", ffi: { type: "undefined" } }],
|
|
408
|
-
["int", { ts: "number", ffi: { type: "int", size: 32, unsigned: false } }],
|
|
409
|
-
["uint", { ts: "number", ffi: { type: "int", size: 32, unsigned: true } }],
|
|
410
|
-
["long", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
411
|
-
["ulong", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
412
|
-
["size_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
413
|
-
["ssize_t", { ts: "number", ffi: { type: "int", size: 64, unsigned: false } }],
|
|
414
|
-
["double", { ts: "number", ffi: { type: "float", size: 64 } }],
|
|
415
|
-
["float", { ts: "number", ffi: { type: "float", size: 32 } }],
|
|
416
|
-
["GLib.DestroyNotify", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
417
|
-
["DestroyNotify", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
418
|
-
["GLib.FreeFunc", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
419
|
-
["FreeFunc", { ts: "number", ffi: { type: "int", size: 64, unsigned: true } }],
|
|
420
|
-
]);
|
|
423
|
+
export class GirConstant {
|
|
424
|
+
name;
|
|
425
|
+
qualifiedName;
|
|
426
|
+
cType;
|
|
427
|
+
value;
|
|
428
|
+
type;
|
|
429
|
+
doc;
|
|
430
|
+
constructor(data) {
|
|
431
|
+
this.name = data.name;
|
|
432
|
+
this.qualifiedName = data.qualifiedName;
|
|
433
|
+
this.cType = data.cType;
|
|
434
|
+
this.value = data.value;
|
|
435
|
+
this.type = data.type;
|
|
436
|
+
this.doc = data.doc;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
421
439
|
/**
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* Handles conversion of GIR type information into:
|
|
425
|
-
* - TypeScript type strings for generated declarations
|
|
426
|
-
* - FFI type descriptors for runtime marshalling
|
|
427
|
-
*
|
|
428
|
-
* Supports callbacks for tracking type usage dependencies.
|
|
429
|
-
*
|
|
430
|
-
* @example
|
|
431
|
-
* ```tsx
|
|
432
|
-
* const mapper = new TypeMapper();
|
|
433
|
-
* mapper.registerEnum("Orientation", "Orientation");
|
|
434
|
-
* mapper.setTypeRegistry(registry, "Gtk");
|
|
435
|
-
*
|
|
436
|
-
* const result = mapper.mapType({ name: "utf8" });
|
|
437
|
-
* // { ts: "string", ffi: { type: "string", borrowed: false } }
|
|
438
|
-
* ```
|
|
440
|
+
* Normalized method with helper methods.
|
|
439
441
|
*/
|
|
440
|
-
export class
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
442
|
+
export class GirMethod {
|
|
443
|
+
name;
|
|
444
|
+
cIdentifier;
|
|
445
|
+
returnType;
|
|
446
|
+
parameters;
|
|
447
|
+
throws;
|
|
448
|
+
doc;
|
|
449
|
+
returnDoc;
|
|
450
|
+
/** For async methods, the name of the corresponding finish function */
|
|
451
|
+
finishFunc;
|
|
452
|
+
constructor(data) {
|
|
453
|
+
this.name = data.name;
|
|
454
|
+
this.cIdentifier = data.cIdentifier;
|
|
455
|
+
this.returnType = data.returnType;
|
|
456
|
+
this.parameters = data.parameters;
|
|
457
|
+
this.throws = data.throws;
|
|
458
|
+
this.doc = data.doc;
|
|
459
|
+
this.returnDoc = data.returnDoc;
|
|
460
|
+
this.finishFunc = data.finishFunc;
|
|
461
|
+
}
|
|
462
|
+
/** True if this follows the async/finish pattern. */
|
|
463
|
+
isAsync() {
|
|
464
|
+
return this.name.endsWith("_async") || this.parameters.some((p) => p.scope === "async");
|
|
465
|
+
}
|
|
466
|
+
/** True if this is a _finish method for an async operation. */
|
|
467
|
+
isAsyncFinish() {
|
|
468
|
+
return this.name.endsWith("_finish");
|
|
469
|
+
}
|
|
470
|
+
/** Gets the corresponding _finish method name if this is async. */
|
|
471
|
+
getFinishMethodName() {
|
|
472
|
+
if (this.name.endsWith("_async")) {
|
|
473
|
+
return this.name.replace(/_async$/, "_finish");
|
|
466
474
|
}
|
|
475
|
+
return null;
|
|
467
476
|
}
|
|
468
|
-
/**
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
* @param originalName - The GIR flags name
|
|
472
|
-
* @param transformedName - Optional transformed TypeScript name
|
|
473
|
-
*/
|
|
474
|
-
registerFlags(originalName, transformedName) {
|
|
475
|
-
this.flagsNames.add(originalName);
|
|
476
|
-
if (transformedName) {
|
|
477
|
-
this.flagsTransforms.set(originalName, transformedName);
|
|
478
|
-
}
|
|
477
|
+
/** Gets required (non-optional, non-nullable) parameters. */
|
|
478
|
+
getRequiredParameters() {
|
|
479
|
+
return this.parameters.filter((p) => !p.optional && !p.nullable && p.direction === "in");
|
|
479
480
|
}
|
|
480
|
-
/**
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
* @param originalName - The GIR record name
|
|
484
|
-
* @param transformedName - Optional transformed TypeScript name
|
|
485
|
-
* @param glibTypeName - Optional GLib type name for boxed type marshalling
|
|
486
|
-
*/
|
|
487
|
-
registerRecord(originalName, transformedName, glibTypeName) {
|
|
488
|
-
this.recordNames.add(originalName);
|
|
489
|
-
if (transformedName) {
|
|
490
|
-
this.recordTransforms.set(originalName, transformedName);
|
|
491
|
-
}
|
|
492
|
-
if (glibTypeName) {
|
|
493
|
-
this.recordGlibTypes.set(originalName, glibTypeName);
|
|
494
|
-
}
|
|
481
|
+
/** Gets optional parameters. */
|
|
482
|
+
getOptionalParameters() {
|
|
483
|
+
return this.parameters.filter((p) => p.optional || p.nullable);
|
|
495
484
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
getEnumUsageCallback() {
|
|
500
|
-
return this.onEnumUsed ?? null;
|
|
501
|
-
}
|
|
502
|
-
setRecordUsageCallback(callback) {
|
|
503
|
-
this.onRecordUsed = callback ?? undefined;
|
|
504
|
-
}
|
|
505
|
-
getRecordUsageCallback() {
|
|
506
|
-
return this.onRecordUsed ?? null;
|
|
507
|
-
}
|
|
508
|
-
setExternalTypeUsageCallback(callback) {
|
|
509
|
-
this.onExternalTypeUsed = callback ?? undefined;
|
|
510
|
-
}
|
|
511
|
-
getExternalTypeUsageCallback() {
|
|
512
|
-
return this.onExternalTypeUsed ?? null;
|
|
513
|
-
}
|
|
514
|
-
setSameNamespaceClassUsageCallback(callback) {
|
|
515
|
-
this.onSameNamespaceClassUsed = callback ?? undefined;
|
|
516
|
-
}
|
|
517
|
-
getSameNamespaceClassUsageCallback() {
|
|
518
|
-
return this.onSameNamespaceClassUsed ?? null;
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Sets the type registry for cross-namespace type resolution.
|
|
522
|
-
*
|
|
523
|
-
* @param registry - The type registry to use
|
|
524
|
-
* @param currentNamespace - The current namespace being processed
|
|
525
|
-
*/
|
|
526
|
-
setTypeRegistry(registry, currentNamespace) {
|
|
527
|
-
this.typeRegistry = registry;
|
|
528
|
-
this.currentNamespace = currentNamespace;
|
|
529
|
-
}
|
|
530
|
-
setForceExternalNamespace(namespace) {
|
|
531
|
-
this.forceExternalNamespace = namespace ?? undefined;
|
|
532
|
-
}
|
|
533
|
-
registerSkippedClass(name) {
|
|
534
|
-
this.skippedClasses.add(name);
|
|
535
|
-
}
|
|
536
|
-
clearSkippedClasses() {
|
|
537
|
-
this.skippedClasses.clear();
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Maps a GIR type to TypeScript and FFI representations.
|
|
541
|
-
*
|
|
542
|
-
* @param girType - The GIR type to map
|
|
543
|
-
* @param isReturn - Whether this is a return type (affects ownership)
|
|
544
|
-
* @param parentTransferOwnership - Transfer ownership from parent (used for array elements)
|
|
545
|
-
* @returns The mapped type with TypeScript and FFI descriptors
|
|
546
|
-
*/
|
|
547
|
-
mapType(girType, isReturn = false, parentTransferOwnership) {
|
|
548
|
-
if (girType.isArray || girType.name === "array") {
|
|
549
|
-
const listType = girType.cType?.includes("GSList")
|
|
550
|
-
? "gslist"
|
|
551
|
-
: girType.cType?.includes("GList")
|
|
552
|
-
? "glist"
|
|
553
|
-
: undefined;
|
|
554
|
-
if (girType.elementType) {
|
|
555
|
-
const elementTransferOwnership = girType.transferOwnership ?? parentTransferOwnership;
|
|
556
|
-
const elementType = this.mapType(girType.elementType, isReturn, elementTransferOwnership);
|
|
557
|
-
return {
|
|
558
|
-
ts: `${elementType.ts}[]`,
|
|
559
|
-
ffi: listType
|
|
560
|
-
? { type: "array", itemType: elementType.ffi, listType, borrowed: isReturn }
|
|
561
|
-
: { type: "array", itemType: elementType.ffi },
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
return {
|
|
565
|
-
ts: `unknown[]`,
|
|
566
|
-
ffi: listType
|
|
567
|
-
? { type: "array", itemType: { type: "undefined" }, listType, borrowed: isReturn }
|
|
568
|
-
: { type: "array", itemType: { type: "undefined" } },
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
if (STRING_TYPES.has(girType.name)) {
|
|
572
|
-
const effectiveTransferOwnership = girType.transferOwnership ?? parentTransferOwnership;
|
|
573
|
-
const borrowed = effectiveTransferOwnership === "none";
|
|
574
|
-
return {
|
|
575
|
-
ts: "string",
|
|
576
|
-
ffi: { type: "string", borrowed },
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
const basicType = BASIC_TYPE_MAP.get(girType.name);
|
|
580
|
-
if (basicType) {
|
|
581
|
-
return basicType;
|
|
582
|
-
}
|
|
583
|
-
if (this.typeRegistry && this.currentNamespace && !girType.name.includes(".")) {
|
|
584
|
-
const registered = this.typeRegistry.resolveInNamespace(girType.name, this.currentNamespace);
|
|
585
|
-
if (registered) {
|
|
586
|
-
const isExternal = registered.namespace !== this.currentNamespace ||
|
|
587
|
-
registered.namespace === this.forceExternalNamespace;
|
|
588
|
-
const qualifiedName = isExternal
|
|
589
|
-
? `${registered.namespace}.${registered.transformedName}`
|
|
590
|
-
: registered.transformedName;
|
|
591
|
-
const externalType = isExternal
|
|
592
|
-
? {
|
|
593
|
-
namespace: registered.namespace,
|
|
594
|
-
name: registered.name,
|
|
595
|
-
transformedName: registered.transformedName,
|
|
596
|
-
kind: registered.kind,
|
|
597
|
-
}
|
|
598
|
-
: undefined;
|
|
599
|
-
if (isExternal) {
|
|
600
|
-
this.onExternalTypeUsed?.(externalType);
|
|
601
|
-
}
|
|
602
|
-
else if (registered.kind === "class" || registered.kind === "interface") {
|
|
603
|
-
if (this.skippedClasses.has(registered.name)) {
|
|
604
|
-
return {
|
|
605
|
-
ts: "unknown",
|
|
606
|
-
ffi: { type: "gobject", borrowed: isReturn },
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
this.onSameNamespaceClassUsed?.(registered.transformedName, registered.name);
|
|
610
|
-
}
|
|
611
|
-
else if (registered.kind === "enum" || registered.kind === "flags") {
|
|
612
|
-
this.onEnumUsed?.(registered.transformedName);
|
|
613
|
-
}
|
|
614
|
-
else if (registered.kind === "record") {
|
|
615
|
-
this.onRecordUsed?.(registered.transformedName);
|
|
616
|
-
}
|
|
617
|
-
if (registered.kind === "enum") {
|
|
618
|
-
return {
|
|
619
|
-
ts: qualifiedName,
|
|
620
|
-
ffi: { type: "int", size: 32, unsigned: false },
|
|
621
|
-
externalType,
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
if (registered.kind === "flags") {
|
|
625
|
-
return {
|
|
626
|
-
ts: qualifiedName,
|
|
627
|
-
ffi: { type: "int", size: 32, unsigned: true },
|
|
628
|
-
externalType,
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
if (registered.kind === "record") {
|
|
632
|
-
if (registered.name === "Variant" && registered.namespace === "GLib") {
|
|
633
|
-
return {
|
|
634
|
-
ts: qualifiedName,
|
|
635
|
-
ffi: { type: "gvariant", borrowed: isReturn },
|
|
636
|
-
externalType,
|
|
637
|
-
kind: registered.kind,
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
if (registered.isPlainStruct) {
|
|
641
|
-
return {
|
|
642
|
-
ts: qualifiedName,
|
|
643
|
-
ffi: {
|
|
644
|
-
type: "struct",
|
|
645
|
-
borrowed: isReturn,
|
|
646
|
-
innerType: registered.transformedName,
|
|
647
|
-
size: registered.structSize,
|
|
648
|
-
},
|
|
649
|
-
externalType,
|
|
650
|
-
kind: registered.kind,
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
return {
|
|
654
|
-
ts: qualifiedName,
|
|
655
|
-
ffi: {
|
|
656
|
-
type: "boxed",
|
|
657
|
-
borrowed: isReturn,
|
|
658
|
-
innerType: registered.glibTypeName ?? registered.transformedName,
|
|
659
|
-
lib: registered.sharedLibrary,
|
|
660
|
-
getTypeFn: registered.glibGetType,
|
|
661
|
-
},
|
|
662
|
-
externalType,
|
|
663
|
-
kind: registered.kind,
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
if (registered.kind === "callback") {
|
|
667
|
-
return POINTER_TYPE;
|
|
668
|
-
}
|
|
669
|
-
if (registered.name === "ParamSpec" && registered.namespace === "GObject") {
|
|
670
|
-
return {
|
|
671
|
-
ts: qualifiedName,
|
|
672
|
-
ffi: { type: "gparam", borrowed: isReturn },
|
|
673
|
-
externalType,
|
|
674
|
-
kind: registered.kind,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
return {
|
|
678
|
-
ts: qualifiedName,
|
|
679
|
-
ffi: { type: "gobject", borrowed: isReturn },
|
|
680
|
-
externalType,
|
|
681
|
-
kind: registered.kind,
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
if (this.enumNames.has(girType.name)) {
|
|
686
|
-
const transformedName = this.enumTransforms.get(girType.name) ?? girType.name;
|
|
687
|
-
this.onEnumUsed?.(transformedName);
|
|
688
|
-
return {
|
|
689
|
-
ts: transformedName,
|
|
690
|
-
ffi: { type: "int", size: 32, unsigned: false },
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
if (this.flagsNames.has(girType.name)) {
|
|
694
|
-
const transformedName = this.flagsTransforms.get(girType.name) ?? girType.name;
|
|
695
|
-
this.onEnumUsed?.(transformedName);
|
|
696
|
-
return {
|
|
697
|
-
ts: transformedName,
|
|
698
|
-
ffi: { type: "int", size: 32, unsigned: true },
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
if (this.recordNames.has(girType.name)) {
|
|
702
|
-
const transformedName = this.recordTransforms.get(girType.name) ?? girType.name;
|
|
703
|
-
const glibTypeName = this.recordGlibTypes.get(girType.name) ?? transformedName;
|
|
704
|
-
this.onRecordUsed?.(transformedName);
|
|
705
|
-
return {
|
|
706
|
-
ts: transformedName,
|
|
707
|
-
ffi: { type: "boxed", borrowed: isReturn, innerType: glibTypeName },
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
if (girType.name.includes(".")) {
|
|
711
|
-
const [ns, typeName] = girType.name.split(".", 2);
|
|
712
|
-
if (typeName && ns === this.currentNamespace) {
|
|
713
|
-
if (this.enumNames.has(typeName)) {
|
|
714
|
-
const transformedName = this.enumTransforms.get(typeName) ?? typeName;
|
|
715
|
-
this.onEnumUsed?.(transformedName);
|
|
716
|
-
return {
|
|
717
|
-
ts: transformedName,
|
|
718
|
-
ffi: { type: "int", size: 32, unsigned: false },
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
if (this.flagsNames.has(typeName)) {
|
|
722
|
-
const transformedName = this.flagsTransforms.get(typeName) ?? typeName;
|
|
723
|
-
this.onEnumUsed?.(transformedName);
|
|
724
|
-
return {
|
|
725
|
-
ts: transformedName,
|
|
726
|
-
ffi: { type: "int", size: 32, unsigned: true },
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
if (this.recordNames.has(typeName)) {
|
|
730
|
-
const transformedName = this.recordTransforms.get(typeName) ?? typeName;
|
|
731
|
-
const glibTypeName = this.recordGlibTypes.get(typeName) ?? transformedName;
|
|
732
|
-
this.onRecordUsed?.(transformedName);
|
|
733
|
-
return {
|
|
734
|
-
ts: transformedName,
|
|
735
|
-
ffi: { type: "boxed", borrowed: isReturn, innerType: glibTypeName },
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
if (this.typeRegistry && ns && typeName) {
|
|
740
|
-
const registered = this.typeRegistry.resolve(girType.name);
|
|
741
|
-
if (registered) {
|
|
742
|
-
const isExternal = registered.namespace !== this.currentNamespace ||
|
|
743
|
-
registered.namespace === this.forceExternalNamespace;
|
|
744
|
-
const qualifiedName = isExternal
|
|
745
|
-
? `${registered.namespace}.${registered.transformedName}`
|
|
746
|
-
: registered.transformedName;
|
|
747
|
-
const externalType = {
|
|
748
|
-
namespace: registered.namespace,
|
|
749
|
-
name: registered.name,
|
|
750
|
-
transformedName: registered.transformedName,
|
|
751
|
-
kind: registered.kind,
|
|
752
|
-
};
|
|
753
|
-
if (isExternal) {
|
|
754
|
-
this.onExternalTypeUsed?.(externalType);
|
|
755
|
-
}
|
|
756
|
-
if (registered.kind === "enum") {
|
|
757
|
-
return {
|
|
758
|
-
ts: qualifiedName,
|
|
759
|
-
ffi: { type: "int", size: 32, unsigned: false },
|
|
760
|
-
externalType: isExternal ? externalType : undefined,
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
if (registered.kind === "flags") {
|
|
764
|
-
return {
|
|
765
|
-
ts: qualifiedName,
|
|
766
|
-
ffi: { type: "int", size: 32, unsigned: true },
|
|
767
|
-
externalType: isExternal ? externalType : undefined,
|
|
768
|
-
};
|
|
769
|
-
}
|
|
770
|
-
if (registered.kind === "record") {
|
|
771
|
-
if (registered.name === "Variant" && registered.namespace === "GLib") {
|
|
772
|
-
return {
|
|
773
|
-
ts: qualifiedName,
|
|
774
|
-
ffi: { type: "gvariant", borrowed: isReturn },
|
|
775
|
-
externalType: isExternal ? externalType : undefined,
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
if (registered.isPlainStruct) {
|
|
779
|
-
return {
|
|
780
|
-
ts: qualifiedName,
|
|
781
|
-
ffi: {
|
|
782
|
-
type: "struct",
|
|
783
|
-
borrowed: isReturn,
|
|
784
|
-
innerType: registered.transformedName,
|
|
785
|
-
size: registered.structSize,
|
|
786
|
-
},
|
|
787
|
-
externalType: isExternal ? externalType : undefined,
|
|
788
|
-
kind: registered.kind,
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
return {
|
|
792
|
-
ts: qualifiedName,
|
|
793
|
-
ffi: {
|
|
794
|
-
type: "boxed",
|
|
795
|
-
borrowed: isReturn,
|
|
796
|
-
innerType: registered.glibTypeName ?? registered.transformedName,
|
|
797
|
-
lib: registered.sharedLibrary,
|
|
798
|
-
getTypeFn: registered.glibGetType,
|
|
799
|
-
},
|
|
800
|
-
externalType: isExternal ? externalType : undefined,
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
if (registered.kind === "callback") {
|
|
804
|
-
return POINTER_TYPE;
|
|
805
|
-
}
|
|
806
|
-
if (registered.name === "ParamSpec" && registered.namespace === "GObject") {
|
|
807
|
-
return {
|
|
808
|
-
ts: qualifiedName,
|
|
809
|
-
ffi: { type: "gparam", borrowed: isReturn },
|
|
810
|
-
externalType: isExternal ? externalType : undefined,
|
|
811
|
-
kind: registered.kind,
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
return {
|
|
815
|
-
ts: qualifiedName,
|
|
816
|
-
ffi: { type: "gobject", borrowed: isReturn },
|
|
817
|
-
externalType: isExternal ? externalType : undefined,
|
|
818
|
-
kind: registered.kind,
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
return mapCType(girType.cType);
|
|
823
|
-
}
|
|
824
|
-
if (this.typeRegistry && this.currentNamespace) {
|
|
825
|
-
const registered = this.typeRegistry.resolveInNamespace(girType.name, this.currentNamespace);
|
|
826
|
-
if (registered) {
|
|
827
|
-
const isExternal = registered.namespace !== this.currentNamespace ||
|
|
828
|
-
registered.namespace === this.forceExternalNamespace;
|
|
829
|
-
const qualifiedName = isExternal
|
|
830
|
-
? `${registered.namespace}.${registered.transformedName}`
|
|
831
|
-
: registered.transformedName;
|
|
832
|
-
const externalType = isExternal
|
|
833
|
-
? {
|
|
834
|
-
namespace: registered.namespace,
|
|
835
|
-
name: registered.name,
|
|
836
|
-
transformedName: registered.transformedName,
|
|
837
|
-
kind: registered.kind,
|
|
838
|
-
}
|
|
839
|
-
: undefined;
|
|
840
|
-
if (isExternal) {
|
|
841
|
-
this.onExternalTypeUsed?.(externalType);
|
|
842
|
-
}
|
|
843
|
-
else if (registered.kind === "class" || registered.kind === "interface") {
|
|
844
|
-
if (this.skippedClasses.has(registered.name)) {
|
|
845
|
-
return {
|
|
846
|
-
ts: "unknown",
|
|
847
|
-
ffi: { type: "gobject", borrowed: isReturn },
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
this.onSameNamespaceClassUsed?.(registered.transformedName, registered.name);
|
|
851
|
-
}
|
|
852
|
-
if (registered.kind === "enum") {
|
|
853
|
-
return {
|
|
854
|
-
ts: qualifiedName,
|
|
855
|
-
ffi: { type: "int", size: 32, unsigned: false },
|
|
856
|
-
externalType,
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
if (registered.kind === "flags") {
|
|
860
|
-
return {
|
|
861
|
-
ts: qualifiedName,
|
|
862
|
-
ffi: { type: "int", size: 32, unsigned: true },
|
|
863
|
-
externalType,
|
|
864
|
-
};
|
|
865
|
-
}
|
|
866
|
-
if (registered.kind === "record") {
|
|
867
|
-
if (registered.isPlainStruct) {
|
|
868
|
-
return {
|
|
869
|
-
ts: qualifiedName,
|
|
870
|
-
ffi: {
|
|
871
|
-
type: "struct",
|
|
872
|
-
borrowed: isReturn,
|
|
873
|
-
innerType: registered.transformedName,
|
|
874
|
-
size: registered.structSize,
|
|
875
|
-
},
|
|
876
|
-
externalType,
|
|
877
|
-
kind: registered.kind,
|
|
878
|
-
};
|
|
879
|
-
}
|
|
880
|
-
return {
|
|
881
|
-
ts: qualifiedName,
|
|
882
|
-
ffi: {
|
|
883
|
-
type: "boxed",
|
|
884
|
-
borrowed: isReturn,
|
|
885
|
-
innerType: registered.glibTypeName ?? registered.transformedName,
|
|
886
|
-
lib: registered.sharedLibrary,
|
|
887
|
-
getTypeFn: registered.glibGetType,
|
|
888
|
-
},
|
|
889
|
-
externalType,
|
|
890
|
-
kind: registered.kind,
|
|
891
|
-
};
|
|
892
|
-
}
|
|
893
|
-
if (registered.kind === "callback") {
|
|
894
|
-
return POINTER_TYPE;
|
|
895
|
-
}
|
|
896
|
-
if (registered.name === "ParamSpec" && registered.namespace === "GObject") {
|
|
897
|
-
return {
|
|
898
|
-
ts: qualifiedName,
|
|
899
|
-
ffi: { type: "gparam", borrowed: isReturn },
|
|
900
|
-
externalType,
|
|
901
|
-
kind: registered.kind,
|
|
902
|
-
};
|
|
903
|
-
}
|
|
904
|
-
return {
|
|
905
|
-
ts: qualifiedName,
|
|
906
|
-
ffi: { type: "gobject", borrowed: isReturn },
|
|
907
|
-
externalType,
|
|
908
|
-
kind: registered.kind,
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
return mapCType(girType.cType);
|
|
913
|
-
}
|
|
914
|
-
isCallback(typeName) {
|
|
915
|
-
if (this.typeRegistry) {
|
|
916
|
-
const resolved = this.currentNamespace
|
|
917
|
-
? this.typeRegistry.resolveInNamespace(typeName, this.currentNamespace)
|
|
918
|
-
: this.typeRegistry.resolve(typeName);
|
|
919
|
-
return resolved?.kind === "callback";
|
|
920
|
-
}
|
|
921
|
-
return false;
|
|
485
|
+
/** True if any parameter is an out parameter. */
|
|
486
|
+
hasOutParameters() {
|
|
487
|
+
return this.parameters.some((p) => p.direction === "out" || p.direction === "inout");
|
|
922
488
|
}
|
|
923
|
-
/**
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
489
|
+
/** Gets out parameters only. */
|
|
490
|
+
getOutParameters() {
|
|
491
|
+
return this.parameters.filter((p) => p.direction === "out" || p.direction === "inout");
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Normalized constructor.
|
|
496
|
+
*/
|
|
497
|
+
export class GirConstructor {
|
|
498
|
+
name;
|
|
499
|
+
cIdentifier;
|
|
500
|
+
returnType;
|
|
501
|
+
parameters;
|
|
502
|
+
throws;
|
|
503
|
+
doc;
|
|
504
|
+
returnDoc;
|
|
505
|
+
constructor(data) {
|
|
506
|
+
this.name = data.name;
|
|
507
|
+
this.cIdentifier = data.cIdentifier;
|
|
508
|
+
this.returnType = data.returnType;
|
|
509
|
+
this.parameters = data.parameters;
|
|
510
|
+
this.throws = data.throws;
|
|
511
|
+
this.doc = data.doc;
|
|
512
|
+
this.returnDoc = data.returnDoc;
|
|
513
|
+
}
|
|
514
|
+
/** Gets required (non-optional, non-nullable) parameters. */
|
|
515
|
+
getRequiredParameters() {
|
|
516
|
+
return this.parameters.filter((p) => !p.optional && !p.nullable && p.direction === "in");
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Normalized standalone function.
|
|
521
|
+
*/
|
|
522
|
+
export class GirFunction {
|
|
523
|
+
name;
|
|
524
|
+
cIdentifier;
|
|
525
|
+
returnType;
|
|
526
|
+
parameters;
|
|
527
|
+
throws;
|
|
528
|
+
doc;
|
|
529
|
+
returnDoc;
|
|
530
|
+
constructor(data) {
|
|
531
|
+
this.name = data.name;
|
|
532
|
+
this.cIdentifier = data.cIdentifier;
|
|
533
|
+
this.returnType = data.returnType;
|
|
534
|
+
this.parameters = data.parameters;
|
|
535
|
+
this.throws = data.throws;
|
|
536
|
+
this.doc = data.doc;
|
|
537
|
+
this.returnDoc = data.returnDoc;
|
|
538
|
+
}
|
|
539
|
+
/** True if this follows the async/finish pattern. */
|
|
540
|
+
isAsync() {
|
|
541
|
+
return this.name.endsWith("_async") || this.parameters.some((p) => p.scope === "async");
|
|
542
|
+
}
|
|
543
|
+
/** Gets required parameters. */
|
|
544
|
+
getRequiredParameters() {
|
|
545
|
+
return this.parameters.filter((p) => !p.optional && !p.nullable && p.direction === "in");
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Normalized parameter with helper methods.
|
|
550
|
+
*/
|
|
551
|
+
export class GirParameter {
|
|
552
|
+
name;
|
|
553
|
+
type;
|
|
554
|
+
direction;
|
|
555
|
+
callerAllocates;
|
|
556
|
+
nullable;
|
|
557
|
+
optional;
|
|
558
|
+
scope;
|
|
559
|
+
closure;
|
|
560
|
+
destroy;
|
|
561
|
+
transferOwnership;
|
|
562
|
+
doc;
|
|
563
|
+
constructor(data) {
|
|
564
|
+
this.name = data.name;
|
|
565
|
+
this.type = data.type;
|
|
566
|
+
this.direction = data.direction;
|
|
567
|
+
this.callerAllocates = data.callerAllocates;
|
|
568
|
+
this.nullable = data.nullable;
|
|
569
|
+
this.optional = data.optional;
|
|
570
|
+
this.scope = data.scope;
|
|
571
|
+
this.closure = data.closure;
|
|
572
|
+
this.destroy = data.destroy;
|
|
573
|
+
this.transferOwnership = data.transferOwnership;
|
|
574
|
+
this.doc = data.doc;
|
|
575
|
+
}
|
|
576
|
+
/** True if this is an input parameter. */
|
|
577
|
+
isIn() {
|
|
578
|
+
return this.direction === "in";
|
|
579
|
+
}
|
|
580
|
+
/** True if this is an output parameter. */
|
|
581
|
+
isOut() {
|
|
582
|
+
return this.direction === "out" || this.direction === "inout";
|
|
583
|
+
}
|
|
584
|
+
/** True if this is a callback parameter (has scope). */
|
|
585
|
+
isCallback() {
|
|
586
|
+
return this.scope !== undefined;
|
|
587
|
+
}
|
|
588
|
+
/** True if this is the user_data for a callback. */
|
|
589
|
+
isClosureData() {
|
|
590
|
+
return this.closure !== undefined;
|
|
591
|
+
}
|
|
592
|
+
/** True if this is a destroy notify for a callback. */
|
|
593
|
+
isDestroyNotify() {
|
|
594
|
+
return this.destroy !== undefined;
|
|
595
|
+
}
|
|
596
|
+
/** True if caller must allocate memory for this out param. */
|
|
597
|
+
requiresCallerAllocation() {
|
|
598
|
+
return this.callerAllocates && this.isOut();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Normalized property with helper methods.
|
|
603
|
+
*/
|
|
604
|
+
export class GirProperty {
|
|
605
|
+
name;
|
|
606
|
+
type;
|
|
607
|
+
readable;
|
|
608
|
+
writable;
|
|
609
|
+
constructOnly;
|
|
610
|
+
hasDefault;
|
|
611
|
+
getter;
|
|
612
|
+
setter;
|
|
613
|
+
doc;
|
|
614
|
+
constructor(data) {
|
|
615
|
+
this.name = data.name;
|
|
616
|
+
this.type = data.type;
|
|
617
|
+
this.readable = data.readable;
|
|
618
|
+
this.writable = data.writable;
|
|
619
|
+
this.constructOnly = data.constructOnly;
|
|
620
|
+
this.hasDefault = data.hasDefault;
|
|
621
|
+
this.getter = data.getter;
|
|
622
|
+
this.setter = data.setter;
|
|
623
|
+
this.doc = data.doc;
|
|
624
|
+
}
|
|
625
|
+
/** True if readable but not writable. */
|
|
626
|
+
isReadOnly() {
|
|
627
|
+
return this.readable && !this.writable;
|
|
628
|
+
}
|
|
629
|
+
/** True if writable but not readable. */
|
|
630
|
+
isWriteOnly() {
|
|
631
|
+
return this.writable && !this.readable;
|
|
632
|
+
}
|
|
633
|
+
/** True if can only be set during construction. */
|
|
634
|
+
isConstructOnly() {
|
|
635
|
+
return this.constructOnly;
|
|
636
|
+
}
|
|
637
|
+
/** True if has both getter and setter methods. */
|
|
638
|
+
hasAccessors() {
|
|
639
|
+
return this.getter !== undefined && this.setter !== undefined;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Normalized signal with helper methods.
|
|
644
|
+
*/
|
|
645
|
+
export class GirSignal {
|
|
646
|
+
name;
|
|
647
|
+
when;
|
|
648
|
+
returnType;
|
|
649
|
+
parameters;
|
|
650
|
+
doc;
|
|
651
|
+
constructor(data) {
|
|
652
|
+
this.name = data.name;
|
|
653
|
+
this.when = data.when;
|
|
654
|
+
this.returnType = data.returnType;
|
|
655
|
+
this.parameters = data.parameters;
|
|
656
|
+
this.doc = data.doc;
|
|
657
|
+
}
|
|
658
|
+
/** True if the signal returns a value. */
|
|
659
|
+
hasReturnValue() {
|
|
660
|
+
return this.returnType !== null && !this.returnType.isVoid();
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Normalized field.
|
|
665
|
+
*/
|
|
666
|
+
export class GirField {
|
|
667
|
+
name;
|
|
668
|
+
type;
|
|
669
|
+
writable;
|
|
670
|
+
readable;
|
|
671
|
+
private;
|
|
672
|
+
doc;
|
|
673
|
+
constructor(data) {
|
|
674
|
+
this.name = data.name;
|
|
675
|
+
this.type = data.type;
|
|
676
|
+
this.writable = data.writable;
|
|
677
|
+
this.readable = data.readable;
|
|
678
|
+
this.private = data.private;
|
|
679
|
+
this.doc = data.doc;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Normalized type reference with helper methods.
|
|
684
|
+
*/
|
|
685
|
+
export class GirType {
|
|
686
|
+
/** Type name - either a QualifiedName or an intrinsic type string */
|
|
687
|
+
name;
|
|
688
|
+
cType;
|
|
689
|
+
isArray;
|
|
690
|
+
elementType;
|
|
691
|
+
typeParameters;
|
|
692
|
+
containerType;
|
|
693
|
+
transferOwnership;
|
|
694
|
+
nullable;
|
|
695
|
+
constructor(data) {
|
|
696
|
+
this.name = data.name;
|
|
697
|
+
this.cType = data.cType;
|
|
698
|
+
this.isArray = data.isArray;
|
|
699
|
+
this.elementType = data.elementType;
|
|
700
|
+
this.typeParameters = data.typeParameters ?? [];
|
|
701
|
+
this.containerType = data.containerType;
|
|
702
|
+
this.transferOwnership = data.transferOwnership;
|
|
703
|
+
this.nullable = data.nullable;
|
|
704
|
+
}
|
|
705
|
+
/** True if this is an intrinsic/primitive type. */
|
|
706
|
+
isIntrinsic() {
|
|
707
|
+
return typeof this.name === "string" && isIntrinsicType(this.name);
|
|
708
|
+
}
|
|
709
|
+
/** True if this is a string type (utf8 or filename). */
|
|
710
|
+
isString() {
|
|
711
|
+
return typeof this.name === "string" && isStringType(this.name);
|
|
712
|
+
}
|
|
713
|
+
/** True if this is a numeric type. */
|
|
714
|
+
isNumeric() {
|
|
715
|
+
return typeof this.name === "string" && isNumericType(this.name);
|
|
716
|
+
}
|
|
717
|
+
/** True if this is a boolean type. */
|
|
718
|
+
isBoolean() {
|
|
719
|
+
return this.name === "gboolean";
|
|
720
|
+
}
|
|
721
|
+
/** True if this is void. */
|
|
722
|
+
isVoid() {
|
|
723
|
+
return typeof this.name === "string" && isVoidType(this.name);
|
|
724
|
+
}
|
|
725
|
+
/** True if this is GVariant. */
|
|
726
|
+
isVariant() {
|
|
727
|
+
return this.name === "GVariant";
|
|
728
|
+
}
|
|
729
|
+
/** True if this is GParamSpec. */
|
|
730
|
+
isParamSpec() {
|
|
731
|
+
return this.name === "GParamSpec";
|
|
732
|
+
}
|
|
733
|
+
/** True if this is a GHashTable container. */
|
|
734
|
+
isHashTable() {
|
|
735
|
+
return this.containerType === "ghashtable";
|
|
736
|
+
}
|
|
737
|
+
/** True if this is a GPtrArray container. */
|
|
738
|
+
isPtrArray() {
|
|
739
|
+
return this.containerType === "gptrarray";
|
|
740
|
+
}
|
|
741
|
+
/** True if this is a GArray container. */
|
|
742
|
+
isGArray() {
|
|
743
|
+
return this.containerType === "garray";
|
|
744
|
+
}
|
|
745
|
+
/** True if this is a GList or GSList container. */
|
|
746
|
+
isList() {
|
|
747
|
+
return this.containerType === "glist" || this.containerType === "gslist";
|
|
748
|
+
}
|
|
749
|
+
/** True if this is any generic container type. */
|
|
750
|
+
isGenericContainer() {
|
|
751
|
+
return this.containerType !== undefined;
|
|
752
|
+
}
|
|
753
|
+
/** Gets the key type for GHashTable, or null for other types. */
|
|
754
|
+
getKeyType() {
|
|
755
|
+
if (!this.isHashTable() || this.typeParameters.length < 1)
|
|
756
|
+
return null;
|
|
757
|
+
return this.typeParameters[0] ?? null;
|
|
758
|
+
}
|
|
759
|
+
/** Gets the value type for GHashTable, or null for other types. */
|
|
760
|
+
getValueType() {
|
|
761
|
+
if (!this.isHashTable() || this.typeParameters.length < 2)
|
|
762
|
+
return null;
|
|
763
|
+
return this.typeParameters[1] ?? null;
|
|
764
|
+
}
|
|
765
|
+
/** Gets the namespace part of a qualified name, or null for intrinsics. */
|
|
766
|
+
getNamespace() {
|
|
767
|
+
if (this.isIntrinsic())
|
|
768
|
+
return null;
|
|
769
|
+
const qn = this.name;
|
|
770
|
+
const dot = qn.indexOf(".");
|
|
771
|
+
return dot >= 0 ? qn.slice(0, dot) : null;
|
|
772
|
+
}
|
|
773
|
+
/** Gets the simple name part (without namespace). */
|
|
774
|
+
getSimpleName() {
|
|
775
|
+
if (this.isIntrinsic())
|
|
776
|
+
return this.name;
|
|
777
|
+
const qn = this.name;
|
|
778
|
+
const dot = qn.indexOf(".");
|
|
779
|
+
return dot >= 0 ? qn.slice(dot + 1) : qn;
|
|
1122
780
|
}
|
|
1123
781
|
}
|