@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.
- package/dist/index.d.ts +25 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -10
- package/dist/index.js.map +1 -1
- package/dist/internal/loader.d.ts +30 -0
- package/dist/internal/loader.d.ts.map +1 -0
- package/dist/internal/loader.js +109 -0
- package/dist/internal/loader.js.map +1 -0
- package/dist/internal/normalizer.d.ts +98 -15
- package/dist/internal/normalizer.d.ts.map +1 -1
- package/dist/internal/normalizer.js +381 -412
- package/dist/internal/normalizer.js.map +1 -1
- package/dist/internal/parser.d.ts +23 -31
- package/dist/internal/parser.d.ts.map +1 -1
- package/dist/internal/parser.js +228 -244
- package/dist/internal/parser.js.map +1 -1
- package/dist/internal/raw-types.d.ts +58 -109
- package/dist/internal/raw-types.d.ts.map +1 -1
- package/dist/internal/raw-types.js +0 -8
- package/dist/internal/raw-types.js.map +1 -1
- package/dist/intrinsics.d.ts.map +1 -1
- package/dist/intrinsics.js +7 -0
- package/dist/intrinsics.js.map +1 -1
- package/dist/model/alias.d.ts +21 -0
- package/dist/model/alias.d.ts.map +1 -0
- package/dist/model/alias.js +22 -0
- package/dist/model/alias.js.map +1 -0
- package/dist/model/callables.d.ts +102 -0
- package/dist/model/callables.d.ts.map +1 -0
- package/dist/model/callables.js +123 -0
- package/dist/model/callables.js.map +1 -0
- package/dist/model/callback.d.ts +22 -0
- package/dist/model/callback.d.ts.map +1 -0
- package/dist/model/callback.js +20 -0
- package/dist/model/callback.js.map +1 -0
- package/dist/model/class.d.ts +92 -0
- package/dist/model/class.d.ts.map +1 -0
- package/dist/model/class.js +171 -0
- package/dist/model/class.js.map +1 -0
- package/dist/model/constant.d.ts +21 -0
- package/dist/model/constant.d.ts.map +1 -0
- package/dist/model/constant.js +20 -0
- package/dist/model/constant.js.map +1 -0
- package/dist/model/enumeration.d.ts +41 -0
- package/dist/model/enumeration.d.ts.map +1 -0
- package/dist/model/enumeration.js +47 -0
- package/dist/model/enumeration.js.map +1 -0
- package/dist/model/field.d.ts +21 -0
- package/dist/model/field.d.ts.map +1 -0
- package/dist/model/field.js +20 -0
- package/dist/model/field.js.map +1 -0
- package/dist/model/interface.d.ts +44 -0
- package/dist/model/interface.d.ts.map +1 -0
- package/dist/model/interface.js +67 -0
- package/dist/model/interface.js.map +1 -0
- package/dist/model/namespace.d.ts +44 -0
- package/dist/model/namespace.d.ts.map +1 -0
- package/dist/model/namespace.js +36 -0
- package/dist/model/namespace.js.map +1 -0
- package/dist/model/parameter.d.ts +43 -0
- package/dist/model/parameter.d.ts.map +1 -0
- package/dist/model/parameter.js +54 -0
- package/dist/model/parameter.js.map +1 -0
- package/dist/model/property.d.ts +62 -0
- package/dist/model/property.d.ts.map +1 -0
- package/dist/model/property.js +69 -0
- package/dist/model/property.js.map +1 -0
- package/dist/model/record.d.ts +56 -0
- package/dist/model/record.d.ts.map +1 -0
- package/dist/model/record.js +70 -0
- package/dist/model/record.js.map +1 -0
- package/dist/model/repository-like.d.ts +19 -0
- package/dist/model/repository-like.d.ts.map +1 -0
- package/dist/model/repository-like.js +2 -0
- package/dist/model/repository-like.js.map +1 -0
- package/dist/model/signal.d.ts +22 -0
- package/dist/model/signal.d.ts.map +1 -0
- package/dist/model/signal.js +22 -0
- package/dist/model/signal.js.map +1 -0
- package/dist/model/type.d.ts +71 -0
- package/dist/model/type.d.ts.map +1 -0
- package/dist/model/type.js +112 -0
- package/dist/model/type.js.map +1 -0
- package/dist/repository.d.ts +92 -138
- package/dist/repository.d.ts.map +1 -1
- package/dist/repository.js +155 -219
- package/dist/repository.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +25 -39
- package/src/internal/loader.ts +127 -0
- package/src/internal/normalizer.ts +451 -475
- package/src/internal/parser.ts +242 -284
- package/src/internal/raw-types.ts +65 -116
- package/src/intrinsics.ts +7 -0
- package/src/model/alias.ts +31 -0
- package/src/model/callables.ts +172 -0
- package/src/model/callback.ts +30 -0
- package/src/model/class.ts +215 -0
- package/src/model/constant.ts +29 -0
- package/src/model/enumeration.ts +64 -0
- package/src/model/field.ts +29 -0
- package/src/model/interface.ts +89 -0
- package/src/model/namespace.ts +60 -0
- package/src/model/parameter.ts +74 -0
- package/src/model/property.ts +97 -0
- package/src/model/record.ts +97 -0
- package/src/model/repository-like.ts +20 -0
- package/src/model/signal.ts +32 -0
- package/src/model/type.ts +143 -0
- package/src/repository.ts +197 -283
- package/dist/types.d.ts +0 -655
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -879
- package/dist/types.js.map +0 -1
- package/src/types.ts +0 -1192
package/src/repository.ts
CHANGED
|
@@ -1,259 +1,234 @@
|
|
|
1
|
+
import { GirLoader } from "./internal/loader.js";
|
|
2
|
+
import type { GirNamespaceIntermediate } from "./internal/normalizer.js";
|
|
3
|
+
import { GirNormalizer } from "./internal/normalizer.js";
|
|
4
|
+
import { GirParser } from "./internal/parser.js";
|
|
5
|
+
import type { RawNamespace } from "./internal/raw-types.js";
|
|
6
|
+
import { isIntrinsicType } from "./intrinsics.js";
|
|
7
|
+
import type { GirAlias } from "./model/alias.js";
|
|
8
|
+
import type { GirFunction } from "./model/callables.js";
|
|
9
|
+
import type { GirCallback } from "./model/callback.js";
|
|
10
|
+
import { GirClass } from "./model/class.js";
|
|
11
|
+
import type { GirConstant } from "./model/constant.js";
|
|
12
|
+
import type { GirEnumeration } from "./model/enumeration.js";
|
|
13
|
+
import { GirInterface } from "./model/interface.js";
|
|
14
|
+
import { GirNamespace } from "./model/namespace.js";
|
|
15
|
+
import type { GirRecord } from "./model/record.js";
|
|
16
|
+
import type { RepositoryLike, TypeKind } from "./model/repository-like.js";
|
|
17
|
+
import type { GirType } from "./model/type.js";
|
|
18
|
+
|
|
1
19
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Loads, normalizes, and provides query access to GIR namespaces.
|
|
5
|
-
* All type references are normalized to fully qualified names.
|
|
20
|
+
* Options for loading a GIR repository.
|
|
6
21
|
*/
|
|
22
|
+
export type RepositoryOptions = {
|
|
23
|
+
girPath: string[];
|
|
24
|
+
};
|
|
7
25
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { isIntrinsicType } from "./intrinsics.js";
|
|
14
|
-
import {
|
|
15
|
-
type GirAlias,
|
|
16
|
-
type GirCallback,
|
|
17
|
-
type GirClass,
|
|
18
|
-
type GirConstant,
|
|
19
|
-
type GirEnumeration,
|
|
20
|
-
type GirFunction,
|
|
21
|
-
type GirInterface,
|
|
22
|
-
type GirNamespace,
|
|
23
|
-
type GirRecord,
|
|
24
|
-
type GirType,
|
|
25
|
-
parseQualifiedName,
|
|
26
|
-
type QualifiedName,
|
|
27
|
-
type TypeKind,
|
|
28
|
-
} from "./types.js";
|
|
26
|
+
/**
|
|
27
|
+
* A dependency graph entry mapping namespace keys to their file paths
|
|
28
|
+
* and direct dependencies.
|
|
29
|
+
*/
|
|
30
|
+
export type DependencyGraph = Map<string, { filePath: string; dependencies: string[] }>;
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
|
-
* Central
|
|
33
|
+
* Central registry for GIR data.
|
|
32
34
|
*
|
|
33
|
-
* Loads,
|
|
34
|
-
* All type references
|
|
35
|
+
* Loads, resolves, and provides query access to GIR namespaces.
|
|
36
|
+
* All type references use fully qualified names (`Namespace.TypeName`).
|
|
35
37
|
*
|
|
36
38
|
* @example
|
|
37
39
|
* ```typescript
|
|
38
|
-
* const repo =
|
|
39
|
-
*
|
|
40
|
-
*
|
|
40
|
+
* const repo = await GirRepository.load(["Gtk-4.0", "Adw-1"], {
|
|
41
|
+
* girPath: ["/usr/share/gir-1.0"]
|
|
42
|
+
* });
|
|
41
43
|
*
|
|
42
|
-
* const
|
|
43
|
-
*
|
|
44
|
-
*
|
|
44
|
+
* const button = repo.resolveClass("Gtk.Button");
|
|
45
|
+
* button.isSubclassOf("Gtk.Widget"); // true
|
|
46
|
+
* button.getInheritanceChain();
|
|
45
47
|
* // ["Gtk.Button", "Gtk.Widget", "GObject.InitiallyUnowned", "GObject.Object"]
|
|
46
48
|
* ```
|
|
47
49
|
*/
|
|
48
|
-
export
|
|
49
|
-
|
|
50
|
-
export class GirRepository {
|
|
51
|
-
private rawNamespaces = new Map<string, RawNamespace>();
|
|
52
|
-
private normalizedNamespaces = new Map<string, GirNamespace>();
|
|
53
|
-
private parser: RawGirParser;
|
|
54
|
-
private resolved = false;
|
|
50
|
+
export class GirRepository implements RepositoryLike {
|
|
51
|
+
private readonly namespaces: Map<string, GirNamespace>;
|
|
55
52
|
|
|
56
|
-
constructor(
|
|
57
|
-
this.
|
|
53
|
+
private constructor(namespaces: Map<string, GirNamespace>) {
|
|
54
|
+
this.namespaces = namespaces;
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
/**
|
|
61
|
-
*
|
|
58
|
+
* Discovers all transitive dependencies for the given roots without
|
|
59
|
+
* performing a full parse. Returns namespace keys and their file paths.
|
|
60
|
+
*
|
|
61
|
+
* @param roots - Namespace keys to start from (e.g., `["Gtk-4.0", "Adw-1"]`)
|
|
62
|
+
* @param options - Search paths for GIR files
|
|
62
63
|
*/
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
if (existing && this.compareVersions(existing.version, raw.version) >= 0) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
this.rawNamespaces.set(raw.name, raw);
|
|
70
|
-
this.resolved = false;
|
|
64
|
+
static async discoverDependencies(roots: string[], options: RepositoryOptions): Promise<DependencyGraph> {
|
|
65
|
+
const loader = new GirLoader(options.girPath);
|
|
66
|
+
return loader.discoverDependencies(roots);
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
/**
|
|
74
|
-
* Loads
|
|
70
|
+
* Loads GIR files for the given namespace roots and all their transitive
|
|
71
|
+
* dependencies, returning a fully resolved repository.
|
|
72
|
+
*
|
|
73
|
+
* @param roots - Namespace keys to load (e.g., `["Gtk-4.0", "Adw-1"]`)
|
|
74
|
+
* @param options - Search paths for GIR files
|
|
75
75
|
*/
|
|
76
|
-
async
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
}
|
|
76
|
+
static async load(roots: string[], options: RepositoryOptions): Promise<GirRepository> {
|
|
77
|
+
const loader = new GirLoader(options.girPath);
|
|
78
|
+
const loaded = await loader.loadAll(roots);
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const files = await readdir(dirPath);
|
|
86
|
-
const girFiles = files.filter((f) => f.endsWith(".gir"));
|
|
80
|
+
const rawNamespaces = new Map<string, RawNamespace>();
|
|
81
|
+
for (const [name, { raw }] of loaded) {
|
|
82
|
+
rawNamespaces.set(name, raw);
|
|
83
|
+
}
|
|
87
84
|
|
|
88
|
-
|
|
85
|
+
return GirRepository.buildFromRaw(rawNamespaces);
|
|
89
86
|
}
|
|
90
87
|
|
|
91
88
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
89
|
+
* Creates a repository from inline GIR XML strings.
|
|
90
|
+
* Useful for testing and scenarios where GIR data is already in memory.
|
|
94
91
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const ctx: NormalizerContext = {
|
|
99
|
-
rawNamespaces: this.rawNamespaces,
|
|
100
|
-
};
|
|
92
|
+
static fromXml(xmlStrings: string[]): GirRepository {
|
|
93
|
+
const parser = new GirParser();
|
|
94
|
+
const rawNamespaces = new Map<string, RawNamespace>();
|
|
101
95
|
|
|
102
|
-
for (const
|
|
103
|
-
const
|
|
104
|
-
|
|
96
|
+
for (const xml of xmlStrings) {
|
|
97
|
+
const raw = parser.parseNamespace(xml);
|
|
98
|
+
rawNamespaces.set(raw.name, raw);
|
|
105
99
|
}
|
|
106
100
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
return GirRepository.buildFromRaw(rawNamespaces);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private static buildFromRaw(rawNamespaces: Map<string, RawNamespace>): GirRepository {
|
|
105
|
+
const normalizer = new GirNormalizer();
|
|
106
|
+
const intermediates = normalizer.normalize(rawNamespaces);
|
|
107
|
+
return GirRepository.buildFromIntermediates(intermediates);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private static buildFromIntermediates(intermediates: Map<string, GirNamespaceIntermediate>): GirRepository {
|
|
111
|
+
const namespaceMap = new Map<string, GirNamespace>();
|
|
112
|
+
const repo = new GirRepository(namespaceMap);
|
|
113
|
+
|
|
114
|
+
for (const [nsName, data] of intermediates) {
|
|
115
|
+
const classes = new Map<string, GirClass>();
|
|
116
|
+
for (const [name, classData] of data.classes) {
|
|
117
|
+
classes.set(name, new GirClass(classData, repo));
|
|
110
118
|
}
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
|
|
120
|
+
const interfaces = new Map<string, GirInterface>();
|
|
121
|
+
for (const [name, ifaceData] of data.interfaces) {
|
|
122
|
+
interfaces.set(name, new GirInterface(ifaceData, repo));
|
|
113
123
|
}
|
|
124
|
+
|
|
125
|
+
namespaceMap.set(
|
|
126
|
+
nsName,
|
|
127
|
+
new GirNamespace({
|
|
128
|
+
name: data.name,
|
|
129
|
+
version: data.version,
|
|
130
|
+
sharedLibrary: data.sharedLibrary,
|
|
131
|
+
cPrefix: data.cPrefix,
|
|
132
|
+
classes,
|
|
133
|
+
interfaces,
|
|
134
|
+
records: data.records,
|
|
135
|
+
enumerations: data.enumerations,
|
|
136
|
+
bitfields: data.bitfields,
|
|
137
|
+
callbacks: data.callbacks,
|
|
138
|
+
functions: data.functions,
|
|
139
|
+
constants: data.constants,
|
|
140
|
+
aliases: data.aliases,
|
|
141
|
+
doc: data.doc,
|
|
142
|
+
}),
|
|
143
|
+
);
|
|
114
144
|
}
|
|
115
145
|
|
|
116
|
-
|
|
146
|
+
return repo;
|
|
117
147
|
}
|
|
118
148
|
|
|
119
|
-
/**
|
|
120
|
-
* Gets all loaded namespace names.
|
|
121
|
-
*/
|
|
149
|
+
/** Gets all loaded namespace names. */
|
|
122
150
|
getNamespaceNames(): string[] {
|
|
123
|
-
this.
|
|
124
|
-
return [...this.normalizedNamespaces.keys()];
|
|
151
|
+
return [...this.namespaces.keys()];
|
|
125
152
|
}
|
|
126
153
|
|
|
127
|
-
/**
|
|
128
|
-
* Gets a normalized namespace by name.
|
|
129
|
-
*/
|
|
154
|
+
/** Gets a namespace by name, or null if not loaded. */
|
|
130
155
|
getNamespace(name: string): GirNamespace | null {
|
|
131
|
-
this.
|
|
132
|
-
return this.normalizedNamespaces.get(name) ?? null;
|
|
156
|
+
return this.namespaces.get(name) ?? null;
|
|
133
157
|
}
|
|
134
158
|
|
|
135
|
-
/**
|
|
136
|
-
* Gets all normalized namespaces.
|
|
137
|
-
*/
|
|
159
|
+
/** Gets all loaded namespaces. */
|
|
138
160
|
getAllNamespaces(): Map<string, GirNamespace> {
|
|
139
|
-
this.
|
|
140
|
-
return this.normalizedNamespaces;
|
|
161
|
+
return this.namespaces;
|
|
141
162
|
}
|
|
142
163
|
|
|
143
|
-
/**
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
resolveClass(qualifiedName: QualifiedName): GirClass | null {
|
|
148
|
-
this.ensureResolved();
|
|
149
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
150
|
-
return this.normalizedNamespaces.get(namespace)?.classes.get(name) ?? null;
|
|
164
|
+
/** Resolves a class by qualified name (e.g., `"Gtk.Button"`). */
|
|
165
|
+
resolveClass(qualifiedName: string): GirClass | null {
|
|
166
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
167
|
+
return this.namespaces.get(namespace)?.classes.get(name) ?? null;
|
|
151
168
|
}
|
|
152
169
|
|
|
153
|
-
/**
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
resolveInterface(qualifiedName: QualifiedName): GirInterface | null {
|
|
158
|
-
this.ensureResolved();
|
|
159
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
160
|
-
return this.normalizedNamespaces.get(namespace)?.interfaces.get(name) ?? null;
|
|
170
|
+
/** Resolves an interface by qualified name (e.g., `"Gio.ListModel"`). */
|
|
171
|
+
resolveInterface(qualifiedName: string): GirInterface | null {
|
|
172
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
173
|
+
return this.namespaces.get(namespace)?.interfaces.get(name) ?? null;
|
|
161
174
|
}
|
|
162
175
|
|
|
163
|
-
/**
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
resolveRecord(qualifiedName: QualifiedName): GirRecord | null {
|
|
168
|
-
this.ensureResolved();
|
|
169
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
170
|
-
return this.normalizedNamespaces.get(namespace)?.records.get(name) ?? null;
|
|
176
|
+
/** Resolves a record by qualified name (e.g., `"Gdk.Rectangle"`). */
|
|
177
|
+
resolveRecord(qualifiedName: string): GirRecord | null {
|
|
178
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
179
|
+
return this.namespaces.get(namespace)?.records.get(name) ?? null;
|
|
171
180
|
}
|
|
172
181
|
|
|
173
|
-
/**
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
resolveEnum(qualifiedName: QualifiedName): GirEnumeration | null {
|
|
178
|
-
this.ensureResolved();
|
|
179
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
180
|
-
return this.normalizedNamespaces.get(namespace)?.enumerations.get(name) ?? null;
|
|
182
|
+
/** Resolves an enumeration by qualified name (e.g., `"Gtk.Orientation"`). */
|
|
183
|
+
resolveEnum(qualifiedName: string): GirEnumeration | null {
|
|
184
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
185
|
+
return this.namespaces.get(namespace)?.enumerations.get(name) ?? null;
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
/**
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
resolveFlags(qualifiedName: QualifiedName): GirEnumeration | null {
|
|
188
|
-
this.ensureResolved();
|
|
189
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
190
|
-
return this.normalizedNamespaces.get(namespace)?.bitfields.get(name) ?? null;
|
|
188
|
+
/** Resolves a bitfield by qualified name (e.g., `"Gdk.ModifierType"`). */
|
|
189
|
+
resolveFlags(qualifiedName: string): GirEnumeration | null {
|
|
190
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
191
|
+
return this.namespaces.get(namespace)?.bitfields.get(name) ?? null;
|
|
191
192
|
}
|
|
192
193
|
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
resolveCallback(qualifiedName: QualifiedName): GirCallback | null {
|
|
198
|
-
this.ensureResolved();
|
|
199
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
200
|
-
return this.normalizedNamespaces.get(namespace)?.callbacks.get(name) ?? null;
|
|
194
|
+
/** Resolves a callback by qualified name (e.g., `"Gio.AsyncReadyCallback"`). */
|
|
195
|
+
resolveCallback(qualifiedName: string): GirCallback | null {
|
|
196
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
197
|
+
return this.namespaces.get(namespace)?.callbacks.get(name) ?? null;
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
/**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
resolveConstant(qualifiedName: QualifiedName): GirConstant | null {
|
|
208
|
-
this.ensureResolved();
|
|
209
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
210
|
-
return this.normalizedNamespaces.get(namespace)?.constants.get(name) ?? null;
|
|
200
|
+
/** Resolves a constant by qualified name (e.g., `"Gtk.MAJOR_VERSION"`). */
|
|
201
|
+
resolveConstant(qualifiedName: string): GirConstant | null {
|
|
202
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
203
|
+
return this.namespaces.get(namespace)?.constants.get(name) ?? null;
|
|
211
204
|
}
|
|
212
205
|
|
|
213
|
-
/**
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
resolveFunction(qualifiedName: QualifiedName): GirFunction | null {
|
|
218
|
-
this.ensureResolved();
|
|
219
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
220
|
-
return this.normalizedNamespaces.get(namespace)?.functions.get(name) ?? null;
|
|
206
|
+
/** Resolves a standalone function by qualified name (e.g., `"Gtk.init"`). */
|
|
207
|
+
resolveFunction(qualifiedName: string): GirFunction | null {
|
|
208
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
209
|
+
return this.namespaces.get(namespace)?.functions.get(name) ?? null;
|
|
221
210
|
}
|
|
222
211
|
|
|
223
|
-
/**
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
resolveAlias(qualifiedName: QualifiedName): GirAlias | null {
|
|
228
|
-
this.ensureResolved();
|
|
229
|
-
const { namespace, name } = parseQualifiedName(qualifiedName);
|
|
230
|
-
return this.normalizedNamespaces.get(namespace)?.aliases.get(name) ?? null;
|
|
212
|
+
/** Resolves an alias by qualified name (e.g., `"Pango.LayoutRun"`). */
|
|
213
|
+
resolveAlias(qualifiedName: string): GirAlias | null {
|
|
214
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
215
|
+
return this.namespaces.get(namespace)?.aliases.get(name) ?? null;
|
|
231
216
|
}
|
|
232
217
|
|
|
233
|
-
/**
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
* If not an alias, returns null.
|
|
237
|
-
* @example repo.resolveTypeAlias("Pango.LayoutRun" as QualifiedName) // returns GirType pointing to Pango.GlyphItem
|
|
238
|
-
*/
|
|
239
|
-
resolveTypeAlias(qualifiedName: QualifiedName): GirType | null {
|
|
240
|
-
const alias = this.resolveAlias(qualifiedName);
|
|
241
|
-
return alias?.targetType ?? null;
|
|
218
|
+
/** Resolves a type alias to its target type, or null if not an alias. */
|
|
219
|
+
resolveTypeAlias(qualifiedName: string): GirType | null {
|
|
220
|
+
return this.resolveAlias(qualifiedName)?.targetType ?? null;
|
|
242
221
|
}
|
|
243
222
|
|
|
244
223
|
/**
|
|
245
224
|
* Gets the kind of a type (class, interface, record, enum, flags, callback).
|
|
246
225
|
* Returns null for intrinsic types or unknown types.
|
|
247
226
|
*/
|
|
248
|
-
getTypeKind(qualifiedName:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (isIntrinsicType(qualifiedName)) {
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
227
|
+
getTypeKind(qualifiedName: string): TypeKind | null {
|
|
228
|
+
if (isIntrinsicType(qualifiedName)) return null;
|
|
254
229
|
|
|
255
|
-
const { namespace, name } =
|
|
256
|
-
const ns = this.
|
|
230
|
+
const { namespace, name } = splitQualifiedName(qualifiedName);
|
|
231
|
+
const ns = this.namespaces.get(namespace);
|
|
257
232
|
if (!ns) return null;
|
|
258
233
|
|
|
259
234
|
if (ns.classes.has(name)) return "class";
|
|
@@ -266,156 +241,95 @@ export class GirRepository {
|
|
|
266
241
|
return null;
|
|
267
242
|
}
|
|
268
243
|
|
|
269
|
-
/**
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
*
|
|
273
|
-
* @example
|
|
274
|
-
* getInheritanceChain("Gtk.Button" as QualifiedName)
|
|
275
|
-
* // ["Gtk.Button", "Gtk.Widget", "GObject.InitiallyUnowned", "GObject.Object"]
|
|
276
|
-
*/
|
|
277
|
-
getInheritanceChain(qualifiedName: QualifiedName): QualifiedName[] {
|
|
278
|
-
const cls = this.resolveClass(qualifiedName);
|
|
279
|
-
return cls?.getInheritanceChain() ?? [];
|
|
244
|
+
/** Gets the full inheritance chain for a class (most derived to base). */
|
|
245
|
+
getInheritanceChain(qualifiedName: string): string[] {
|
|
246
|
+
return this.resolveClass(qualifiedName)?.getInheritanceChain() ?? [];
|
|
280
247
|
}
|
|
281
248
|
|
|
282
|
-
/**
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
getImplementedInterfaces(qualifiedName: QualifiedName): QualifiedName[] {
|
|
286
|
-
const cls = this.resolveClass(qualifiedName);
|
|
287
|
-
return cls?.getAllImplementedInterfaces() ?? [];
|
|
249
|
+
/** Gets all interfaces implemented by a class (including inherited). */
|
|
250
|
+
getImplementedInterfaces(qualifiedName: string): string[] {
|
|
251
|
+
return this.resolveClass(qualifiedName)?.getAllImplementedInterfaces() ?? [];
|
|
288
252
|
}
|
|
289
253
|
|
|
290
|
-
/**
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
this.ensureResolved();
|
|
295
|
-
const derived: QualifiedName[] = [];
|
|
296
|
-
|
|
297
|
-
for (const ns of this.normalizedNamespaces.values()) {
|
|
254
|
+
/** Gets all classes that derive from a given class. */
|
|
255
|
+
getDerivedClasses(qualifiedName: string): string[] {
|
|
256
|
+
const derived: string[] = [];
|
|
257
|
+
for (const ns of this.namespaces.values()) {
|
|
298
258
|
for (const cls of ns.classes.values()) {
|
|
299
259
|
if (cls.qualifiedName !== qualifiedName && cls.isSubclassOf(qualifiedName)) {
|
|
300
260
|
derived.push(cls.qualifiedName);
|
|
301
261
|
}
|
|
302
262
|
}
|
|
303
263
|
}
|
|
304
|
-
|
|
305
264
|
return derived;
|
|
306
265
|
}
|
|
307
266
|
|
|
308
|
-
/**
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this.ensureResolved();
|
|
313
|
-
const implementors: QualifiedName[] = [];
|
|
314
|
-
|
|
315
|
-
for (const ns of this.normalizedNamespaces.values()) {
|
|
267
|
+
/** Gets all classes that implement a given interface. */
|
|
268
|
+
getImplementors(interfaceName: string): string[] {
|
|
269
|
+
const implementors: string[] = [];
|
|
270
|
+
for (const ns of this.namespaces.values()) {
|
|
316
271
|
for (const cls of ns.classes.values()) {
|
|
317
272
|
if (cls.implementsInterface(interfaceName)) {
|
|
318
273
|
implementors.push(cls.qualifiedName);
|
|
319
274
|
}
|
|
320
275
|
}
|
|
321
276
|
}
|
|
322
|
-
|
|
323
277
|
return implementors;
|
|
324
278
|
}
|
|
325
279
|
|
|
326
|
-
/**
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
isGObject(qualifiedName: QualifiedName): boolean {
|
|
330
|
-
const cls = this.resolveClass(qualifiedName);
|
|
331
|
-
return cls?.hasGType() ?? false;
|
|
280
|
+
/** Checks if a type is a GObject (class with GType). */
|
|
281
|
+
isGObject(qualifiedName: string): boolean {
|
|
282
|
+
return this.resolveClass(qualifiedName)?.hasGType() ?? false;
|
|
332
283
|
}
|
|
333
284
|
|
|
334
|
-
/**
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
isBoxed(qualifiedName: QualifiedName): boolean {
|
|
338
|
-
const record = this.resolveRecord(qualifiedName);
|
|
339
|
-
return record?.isBoxed() ?? false;
|
|
285
|
+
/** Checks if a type is a boxed type (record with GType). */
|
|
286
|
+
isBoxed(qualifiedName: string): boolean {
|
|
287
|
+
return this.resolveRecord(qualifiedName)?.isBoxed() ?? false;
|
|
340
288
|
}
|
|
341
289
|
|
|
342
|
-
/**
|
|
343
|
-
* Checks if a type is a primitive (intrinsic).
|
|
344
|
-
*/
|
|
290
|
+
/** Checks if a type is a primitive (intrinsic). */
|
|
345
291
|
isPrimitive(typeName: string): boolean {
|
|
346
292
|
return isIntrinsicType(typeName);
|
|
347
293
|
}
|
|
348
294
|
|
|
349
|
-
/**
|
|
350
|
-
* Finds all classes matching a predicate across all namespaces.
|
|
351
|
-
*/
|
|
295
|
+
/** Finds all classes matching a predicate across all namespaces. */
|
|
352
296
|
findClasses(predicate: (cls: GirClass) => boolean): GirClass[] {
|
|
353
|
-
this.ensureResolved();
|
|
354
297
|
const results: GirClass[] = [];
|
|
355
|
-
|
|
356
|
-
for (const ns of this.normalizedNamespaces.values()) {
|
|
298
|
+
for (const ns of this.namespaces.values()) {
|
|
357
299
|
for (const cls of ns.classes.values()) {
|
|
358
|
-
if (predicate(cls))
|
|
359
|
-
results.push(cls);
|
|
360
|
-
}
|
|
300
|
+
if (predicate(cls)) results.push(cls);
|
|
361
301
|
}
|
|
362
302
|
}
|
|
363
|
-
|
|
364
303
|
return results;
|
|
365
304
|
}
|
|
366
305
|
|
|
367
|
-
/**
|
|
368
|
-
* Finds all interfaces matching a predicate across all namespaces.
|
|
369
|
-
*/
|
|
306
|
+
/** Finds all interfaces matching a predicate across all namespaces. */
|
|
370
307
|
findInterfaces(predicate: (iface: GirInterface) => boolean): GirInterface[] {
|
|
371
|
-
this.ensureResolved();
|
|
372
308
|
const results: GirInterface[] = [];
|
|
373
|
-
|
|
374
|
-
for (const ns of this.normalizedNamespaces.values()) {
|
|
309
|
+
for (const ns of this.namespaces.values()) {
|
|
375
310
|
for (const iface of ns.interfaces.values()) {
|
|
376
|
-
if (predicate(iface))
|
|
377
|
-
results.push(iface);
|
|
378
|
-
}
|
|
311
|
+
if (predicate(iface)) results.push(iface);
|
|
379
312
|
}
|
|
380
313
|
}
|
|
381
|
-
|
|
382
314
|
return results;
|
|
383
315
|
}
|
|
384
316
|
|
|
385
|
-
/**
|
|
386
|
-
* Finds all records matching a predicate across all namespaces.
|
|
387
|
-
*/
|
|
317
|
+
/** Finds all records matching a predicate across all namespaces. */
|
|
388
318
|
findRecords(predicate: (record: GirRecord) => boolean): GirRecord[] {
|
|
389
|
-
this.ensureResolved();
|
|
390
319
|
const results: GirRecord[] = [];
|
|
391
|
-
|
|
392
|
-
for (const ns of this.normalizedNamespaces.values()) {
|
|
320
|
+
for (const ns of this.namespaces.values()) {
|
|
393
321
|
for (const record of ns.records.values()) {
|
|
394
|
-
if (predicate(record))
|
|
395
|
-
results.push(record);
|
|
396
|
-
}
|
|
322
|
+
if (predicate(record)) results.push(record);
|
|
397
323
|
}
|
|
398
324
|
}
|
|
399
|
-
|
|
400
325
|
return results;
|
|
401
326
|
}
|
|
327
|
+
}
|
|
402
328
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (diff !== 0) return diff;
|
|
410
|
-
}
|
|
411
|
-
return 0;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
private ensureResolved(): void {
|
|
415
|
-
if (!this.resolved) {
|
|
416
|
-
throw new Error(
|
|
417
|
-
"GirRepository.resolve() must be called before querying. Call resolve() after loading all GIR files.",
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
329
|
+
function splitQualifiedName(qn: string): { namespace: string; name: string } {
|
|
330
|
+
const dot = qn.indexOf(".");
|
|
331
|
+
return {
|
|
332
|
+
namespace: qn.slice(0, dot),
|
|
333
|
+
name: qn.slice(dot + 1),
|
|
334
|
+
};
|
|
421
335
|
}
|