@ts-for-gir/lib 4.0.0-beta.40 → 4.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -6
- package/src/constants.ts +1 -1
- package/src/gir/alias.ts +2 -2
- package/src/gir/introspected-classes.ts +32 -69
- package/src/gir/record.ts +1 -1
- package/src/gir/registry.ts +0 -1
- package/src/gir/signal.ts +32 -0
- package/src/gir-module.ts +125 -165
- package/src/gir.ts +15 -39
- package/src/injections/gio.ts +14 -1
- package/src/injections/glib.ts +5 -0
- package/src/injections/gobject.ts +5 -0
- package/src/types/options-generation.ts +12 -0
- package/src/types/user-config.ts +12 -0
- package/src/utils/conflicts.ts +11 -45
- package/src/utils/documentation.ts +437 -27
- package/src/utils/gir-parsing.ts +31 -12
- package/src/utils/types.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-for-gir/lib",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.41",
|
|
4
4
|
"description": "Typescript .d.ts generator from GIR for gjs",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -41,18 +41,19 @@
|
|
|
41
41
|
"type definitions"
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
|
+
"@ts-for-gir/tsconfig": "^4.0.0-beta.41",
|
|
44
45
|
"@types/ejs": "^3.1.5",
|
|
45
46
|
"@types/lodash": "^4.17.24",
|
|
46
|
-
"@types/node": "^24.
|
|
47
|
+
"@types/node": "^24.12.0",
|
|
47
48
|
"rimraf": "^6.1.3",
|
|
48
49
|
"typescript": "^5.9.3"
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
|
-
"@gi.ts/parser": "^4.0.0-beta.
|
|
52
|
-
"@ts-for-gir/reporter": "^4.0.0-beta.
|
|
53
|
-
"@ts-for-gir/templates": "^4.0.0-beta.
|
|
52
|
+
"@gi.ts/parser": "^4.0.0-beta.41",
|
|
53
|
+
"@ts-for-gir/reporter": "^4.0.0-beta.41",
|
|
54
|
+
"@ts-for-gir/templates": "^4.0.0-beta.41",
|
|
54
55
|
"colorette": "^2.0.20",
|
|
55
|
-
"ejs": "^
|
|
56
|
+
"ejs": "^5.0.1",
|
|
56
57
|
"glob": "^13.0.6",
|
|
57
58
|
"lodash": "^4.17.23"
|
|
58
59
|
}
|
package/src/constants.ts
CHANGED
package/src/gir/alias.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { FormatGenerator, GenericDescriptor } from "../generators/generator
|
|
|
2
2
|
import type { TypeExpression } from "../gir.ts";
|
|
3
3
|
import type { GirAliasElement } from "../index.ts";
|
|
4
4
|
import type { IntrospectedOptions, OptionsLoad } from "../types/index.ts";
|
|
5
|
-
import { parseDoc, parseMetadata } from "../utils/gir-parsing.ts";
|
|
5
|
+
import { girParsingReporter, parseDoc, parseMetadata } from "../utils/gir-parsing.ts";
|
|
6
6
|
import { isIntrospectable } from "../utils/girs.ts";
|
|
7
7
|
import { sanitizeIdentifierName } from "../utils/naming.ts";
|
|
8
8
|
import { getAliasType } from "../utils/types.ts";
|
|
@@ -52,7 +52,7 @@ export class IntrospectedAlias extends IntrospectedNamespaceMember {
|
|
|
52
52
|
|
|
53
53
|
static fromXML(element: GirAliasElement, ns: IntrospectedNamespace, options: OptionsLoad): IntrospectedAlias | null {
|
|
54
54
|
if (!element.$.name) {
|
|
55
|
-
|
|
55
|
+
girParsingReporter.get().reportParsingFailure("alias", "alias", ns.namespace, "Alias lacks name attribute");
|
|
56
56
|
return null;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -72,6 +72,8 @@ export class IntrospectedClassFunction<
|
|
|
72
72
|
protected _generify: boolean = false;
|
|
73
73
|
interfaceParent: IntrospectedBaseClass | IntrospectedEnum | null = null;
|
|
74
74
|
returnTypeDoc?: string | null;
|
|
75
|
+
/** If this function was generated from a signal, stores the signal name. */
|
|
76
|
+
signalOrigin?: string;
|
|
75
77
|
|
|
76
78
|
generics: Generic[] = [];
|
|
77
79
|
|
|
@@ -794,105 +796,66 @@ export class IntrospectedClass extends IntrospectedBaseClass {
|
|
|
794
796
|
);
|
|
795
797
|
}
|
|
796
798
|
|
|
797
|
-
|
|
799
|
+
private collectImplementedItems<T extends { name: string }>(
|
|
800
|
+
getItems: (node: IntrospectedBaseClass) => T[],
|
|
801
|
+
validate: (item: T) => boolean,
|
|
802
|
+
): Map<string, T> {
|
|
798
803
|
const resolution = this.resolveParents();
|
|
799
804
|
const implementedOnParent = [...(resolution.extends() ?? [])].flatMap((r) => r.implements());
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
const validateProp = (prop: IntrospectedProperty) =>
|
|
803
|
-
!this.hasInstanceSymbol(prop) &&
|
|
804
|
-
!properties.has(prop.name) &&
|
|
805
|
-
potentialConflicts.every((p) => prop.name !== p.name);
|
|
805
|
+
const items = new Map<string, T>();
|
|
806
806
|
|
|
807
807
|
for (const implemented of resolution.implements()) {
|
|
808
808
|
if (implemented.node instanceof IntrospectedClass) continue;
|
|
809
|
-
|
|
810
809
|
if (implementedOnParent.find((p) => p.identifier.equals(implemented.identifier))?.node?.generics?.length === 0)
|
|
811
810
|
continue;
|
|
812
|
-
for (const
|
|
813
|
-
if (!
|
|
814
|
-
|
|
811
|
+
for (const item of getItems(implemented.node)) {
|
|
812
|
+
if (items.has(item.name) || !validate(item)) continue;
|
|
813
|
+
items.set(item.name, item);
|
|
815
814
|
}
|
|
816
815
|
}
|
|
817
816
|
|
|
818
817
|
for (const implemented of resolution.implements()) {
|
|
819
818
|
[...implemented].forEach((e) => {
|
|
820
819
|
if (e.node instanceof IntrospectedClass) return;
|
|
821
|
-
|
|
822
820
|
if (implementedOnParent.find((p) => p.identifier.equals(e.identifier))?.node.generics.length === 0) return;
|
|
823
|
-
for (const
|
|
824
|
-
if (!
|
|
825
|
-
|
|
826
|
-
properties.set(prop.name, prop);
|
|
821
|
+
for (const item of getItems(e.node)) {
|
|
822
|
+
if (items.has(item.name) || !validate(item)) continue;
|
|
823
|
+
items.set(item.name, item);
|
|
827
824
|
}
|
|
828
825
|
});
|
|
829
826
|
}
|
|
830
827
|
|
|
831
828
|
// If an interface inherits from a class (such as Gtk.Widget)
|
|
832
|
-
// we need to pull in every
|
|
829
|
+
// we need to pull in every item from that class...
|
|
833
830
|
for (const implemented of resolution.implements()) {
|
|
834
831
|
const extended = implemented.extends();
|
|
835
|
-
|
|
836
832
|
if (extended?.node instanceof IntrospectedClass) {
|
|
837
|
-
for (const
|
|
838
|
-
if (!
|
|
839
|
-
|
|
840
|
-
properties.set(prop.name, prop);
|
|
833
|
+
for (const item of getItems(extended.node)) {
|
|
834
|
+
if (items.has(item.name) || !validate(item)) continue;
|
|
835
|
+
items.set(item.name, item);
|
|
841
836
|
}
|
|
842
837
|
}
|
|
843
838
|
}
|
|
844
839
|
|
|
840
|
+
return items;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
implementedProperties(potentialConflicts: IntrospectedBase<never>[] = []) {
|
|
844
|
+
const properties = this.collectImplementedItems(
|
|
845
|
+
(node) => node.props,
|
|
846
|
+
(prop) => !this.hasInstanceSymbol(prop) && potentialConflicts.every((p) => prop.name !== p.name),
|
|
847
|
+
);
|
|
845
848
|
return [...properties.values()];
|
|
846
849
|
}
|
|
847
850
|
|
|
848
851
|
implementedMethods(potentialConflicts: ClassMember[] = []) {
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
!methods.has(method.name) &&
|
|
857
|
-
potentialConflicts.every((m) => method.name !== m.name);
|
|
858
|
-
|
|
859
|
-
for (const implemented of resolution.implements()) {
|
|
860
|
-
if (implemented.node instanceof IntrospectedClass) continue;
|
|
861
|
-
|
|
862
|
-
if (implementedOnParent.find((p) => p.identifier.equals(implemented.identifier))?.node?.generics?.length === 0)
|
|
863
|
-
continue;
|
|
864
|
-
for (const member of implemented.node.members) {
|
|
865
|
-
if (!validateMethod(member)) continue;
|
|
866
|
-
methods.set(member.name, member);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
for (const implemented of resolution.implements()) {
|
|
871
|
-
[...implemented].forEach((e) => {
|
|
872
|
-
if (e.node instanceof IntrospectedClass) return;
|
|
873
|
-
|
|
874
|
-
if (implementedOnParent.find((p) => p.identifier.equals(e.identifier))?.node.generics.length === 0) return;
|
|
875
|
-
for (const member of e.node.members) {
|
|
876
|
-
if (!validateMethod(member)) continue;
|
|
877
|
-
|
|
878
|
-
methods.set(member.name, member);
|
|
879
|
-
}
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// If an interface inherits from a class (such as Gtk.Widget)
|
|
884
|
-
// we need to pull in every method from that class...
|
|
885
|
-
for (const implemented of resolution.implements()) {
|
|
886
|
-
const extended = implemented.extends();
|
|
887
|
-
|
|
888
|
-
if (extended?.node instanceof IntrospectedClass) {
|
|
889
|
-
for (const member of extended.node.members) {
|
|
890
|
-
if (!validateMethod(member)) continue;
|
|
891
|
-
|
|
892
|
-
methods.set(member.name, member);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
}
|
|
852
|
+
const methods = this.collectImplementedItems(
|
|
853
|
+
(node) => node.members,
|
|
854
|
+
(method) =>
|
|
855
|
+
!(method instanceof IntrospectedStaticClassFunction) &&
|
|
856
|
+
!this.hasInstanceSymbol(method) &&
|
|
857
|
+
potentialConflicts.every((m) => method.name !== m.name),
|
|
858
|
+
);
|
|
896
859
|
|
|
897
860
|
return [...methods.values()].map((f) => {
|
|
898
861
|
const mapping = new Map<string, TypeExpression>();
|
package/src/gir/record.ts
CHANGED
|
@@ -248,7 +248,7 @@ export class IntrospectedRecord extends IntrospectedBaseClass {
|
|
|
248
248
|
namespace: IntrospectedNamespace,
|
|
249
249
|
name: string,
|
|
250
250
|
): void {
|
|
251
|
-
const gtypeStructFor = element.$["glib:is-gtype-struct-for"];
|
|
251
|
+
const gtypeStructFor = "glib:is-gtype-struct-for" in element.$ ? element.$["glib:is-gtype-struct-for"] : undefined;
|
|
252
252
|
|
|
253
253
|
if (typeof gtypeStructFor === "string" && gtypeStructFor) {
|
|
254
254
|
const structFor = parseTypeIdentifier(namespace.namespace, gtypeStructFor);
|
package/src/gir/registry.ts
CHANGED
|
@@ -13,7 +13,6 @@ import { InterfaceVisitor } from "../validators/interface.ts";
|
|
|
13
13
|
import type { GirVisitor } from "../visitor.ts";
|
|
14
14
|
import type { IntrospectedNamespace } from "./namespace.ts";
|
|
15
15
|
|
|
16
|
-
// TODO: Singleton
|
|
17
16
|
export class NSRegistry {
|
|
18
17
|
mapping: TwoKeyMap<string, string, IntrospectedNamespace> = new TwoKeyMap();
|
|
19
18
|
private formatters: Map<string, Formatter> = new Map();
|
package/src/gir/signal.ts
CHANGED
|
@@ -34,12 +34,20 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
34
34
|
parameters: IntrospectedFunctionParameter[];
|
|
35
35
|
return_type: TypeExpression;
|
|
36
36
|
detailed: boolean;
|
|
37
|
+
action: boolean;
|
|
38
|
+
noRecurse: boolean;
|
|
39
|
+
noHooks: boolean;
|
|
40
|
+
when?: "first" | "last" | "cleanup";
|
|
37
41
|
|
|
38
42
|
constructor({
|
|
39
43
|
name,
|
|
40
44
|
parameters = [],
|
|
41
45
|
return_type = UnknownType,
|
|
42
46
|
detailed = false,
|
|
47
|
+
action = false,
|
|
48
|
+
noRecurse = false,
|
|
49
|
+
noHooks = false,
|
|
50
|
+
when,
|
|
43
51
|
parent,
|
|
44
52
|
...args
|
|
45
53
|
}: Options<{
|
|
@@ -47,6 +55,10 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
47
55
|
parameters?: IntrospectedFunctionParameter[];
|
|
48
56
|
return_type?: TypeExpression;
|
|
49
57
|
detailed?: boolean;
|
|
58
|
+
action?: boolean;
|
|
59
|
+
noRecurse?: boolean;
|
|
60
|
+
noHooks?: boolean;
|
|
61
|
+
when?: "first" | "last" | "cleanup";
|
|
50
62
|
parent: IntrospectedClass;
|
|
51
63
|
}>) {
|
|
52
64
|
super(name, parent, { ...args });
|
|
@@ -54,6 +66,10 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
54
66
|
this.parameters = parameters.map((p) => p.copy({ parent: this }));
|
|
55
67
|
this.return_type = return_type;
|
|
56
68
|
this.detailed = detailed;
|
|
69
|
+
this.action = action;
|
|
70
|
+
this.noRecurse = noRecurse;
|
|
71
|
+
this.noHooks = noHooks;
|
|
72
|
+
this.when = when;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
accept(visitor: GirVisitor): IntrospectedSignal {
|
|
@@ -72,11 +88,19 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
72
88
|
parameters,
|
|
73
89
|
returnType,
|
|
74
90
|
detailed,
|
|
91
|
+
action,
|
|
92
|
+
noRecurse,
|
|
93
|
+
noHooks,
|
|
94
|
+
when,
|
|
75
95
|
}: {
|
|
76
96
|
parent?: IntrospectedClass;
|
|
77
97
|
parameters?: IntrospectedFunctionParameter[];
|
|
78
98
|
returnType?: TypeExpression;
|
|
79
99
|
detailed?: boolean;
|
|
100
|
+
action?: boolean;
|
|
101
|
+
noRecurse?: boolean;
|
|
102
|
+
noHooks?: boolean;
|
|
103
|
+
when?: "first" | "last" | "cleanup";
|
|
80
104
|
} = {}): IntrospectedSignal {
|
|
81
105
|
return new IntrospectedSignal({
|
|
82
106
|
name: this.name,
|
|
@@ -84,6 +108,10 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
84
108
|
parameters: parameters ?? this.parameters,
|
|
85
109
|
return_type: returnType ?? this.return_type,
|
|
86
110
|
detailed: detailed ?? this.detailed,
|
|
111
|
+
action: action ?? this.action,
|
|
112
|
+
noRecurse: noRecurse ?? this.noRecurse,
|
|
113
|
+
noHooks: noHooks ?? this.noHooks,
|
|
114
|
+
when: when ?? this.when,
|
|
87
115
|
})._copyBaseProperties(this);
|
|
88
116
|
}
|
|
89
117
|
|
|
@@ -93,6 +121,10 @@ export class IntrospectedSignal extends IntrospectedClassMember<IntrospectedClas
|
|
|
93
121
|
name: element.$.name,
|
|
94
122
|
parent,
|
|
95
123
|
detailed: element.$.detailed === "1",
|
|
124
|
+
action: element.$.action === "1",
|
|
125
|
+
noRecurse: element.$["no-recurse"] === "1",
|
|
126
|
+
noHooks: element.$["no-hooks"] === "1",
|
|
127
|
+
when: element.$.when as "first" | "last" | "cleanup" | undefined,
|
|
96
128
|
isIntrospectable: isIntrospectable(element),
|
|
97
129
|
});
|
|
98
130
|
|
package/src/gir-module.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GirType } from "@gi.ts/parser";
|
|
1
|
+
import type { GirBoxedElement, GirInfoAttrs, GirType } from "@gi.ts/parser";
|
|
2
2
|
import { ConsoleReporter, ReporterService } from "@ts-for-gir/reporter";
|
|
3
3
|
import { DependencyManager } from "./dependency-manager.ts";
|
|
4
4
|
import { IntrospectedAlias } from "./gir/alias.ts";
|
|
@@ -19,11 +19,13 @@ import { NullableType, ObjectType, TypeIdentifier } from "./gir.ts";
|
|
|
19
19
|
import type { LibraryVersion } from "./library-version.ts";
|
|
20
20
|
import type {
|
|
21
21
|
Dependency,
|
|
22
|
+
GirAliasElement,
|
|
22
23
|
GirBitfieldElement,
|
|
23
24
|
GirConstantElement,
|
|
24
25
|
GirEnumElement,
|
|
25
26
|
GirInterfaceElement,
|
|
26
27
|
IGirModule,
|
|
28
|
+
IntrospectedMetadata,
|
|
27
29
|
OptionsGeneration,
|
|
28
30
|
OptionsLoad,
|
|
29
31
|
TsDocTag,
|
|
@@ -244,6 +246,23 @@ export class GirModule implements IGirModule {
|
|
|
244
246
|
return tags;
|
|
245
247
|
}
|
|
246
248
|
|
|
249
|
+
getTsDocMetadataTags(metadata?: IntrospectedMetadata): TsDocTag[] {
|
|
250
|
+
const tags: TsDocTag[] = [];
|
|
251
|
+
if (metadata?.introducedVersion) {
|
|
252
|
+
tags.push({ tagName: "since", paramName: "", text: metadata.introducedVersion });
|
|
253
|
+
}
|
|
254
|
+
if (metadata?.deprecated) {
|
|
255
|
+
const text = [
|
|
256
|
+
metadata.deprecatedVersion ? `since ${metadata.deprecatedVersion}` : "",
|
|
257
|
+
metadata.deprecatedDoc ?? "",
|
|
258
|
+
]
|
|
259
|
+
.filter(Boolean)
|
|
260
|
+
.join(": ");
|
|
261
|
+
tags.push({ tagName: "deprecated", paramName: "", text });
|
|
262
|
+
}
|
|
263
|
+
return tags;
|
|
264
|
+
}
|
|
265
|
+
|
|
247
266
|
registerResolveName(resolveName: string, namespace: string, name: string) {
|
|
248
267
|
this._resolve_names.set(resolveName, new TypeIdentifier(name, namespace));
|
|
249
268
|
}
|
|
@@ -570,6 +589,90 @@ export class GirModule implements IGirModule {
|
|
|
570
589
|
return building;
|
|
571
590
|
}
|
|
572
591
|
|
|
592
|
+
/** Parse and store elements into this.members using a common pattern */
|
|
593
|
+
private parseAndStore<TXml, TResult extends GirNSMember>(
|
|
594
|
+
elements: TXml[] | undefined,
|
|
595
|
+
fromXML: (el: TXml) => TResult,
|
|
596
|
+
filter?: (el: TResult) => boolean,
|
|
597
|
+
): void {
|
|
598
|
+
if (!elements) return;
|
|
599
|
+
let items = (elements as Array<TXml & { $?: GirInfoAttrs }>).filter(isIntrospectable).map(fromXML);
|
|
600
|
+
if (filter) items = items.filter(filter);
|
|
601
|
+
for (const item of items) {
|
|
602
|
+
this.members.set(item.name, item);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** Parse enumerations, which may be either enums or error domains */
|
|
607
|
+
private parseEnumerations(
|
|
608
|
+
enumerations: GirEnumElement[] | undefined,
|
|
609
|
+
options: OptionsLoad,
|
|
610
|
+
importConflicts: (el: { name: string }) => boolean,
|
|
611
|
+
): void {
|
|
612
|
+
this.parseAndStore(
|
|
613
|
+
enumerations,
|
|
614
|
+
(enumeration) => {
|
|
615
|
+
if (enumeration.$["glib:error-domain"]) {
|
|
616
|
+
return IntrospectedError.fromXML(enumeration, this, options);
|
|
617
|
+
}
|
|
618
|
+
return IntrospectedEnum.fromXML(enumeration, this, options);
|
|
619
|
+
},
|
|
620
|
+
importConflicts,
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/** Parse glib:boxed elements into aliases */
|
|
625
|
+
private parseBoxed(boxed: GirBoxedElement[] | undefined): void {
|
|
626
|
+
if (!boxed) return;
|
|
627
|
+
const items = boxed.filter(isIntrospectable).map(
|
|
628
|
+
(b) =>
|
|
629
|
+
new IntrospectedAlias({
|
|
630
|
+
name: b.$["glib:name"],
|
|
631
|
+
namespace: this,
|
|
632
|
+
type: new NullableType(ObjectType),
|
|
633
|
+
}),
|
|
634
|
+
);
|
|
635
|
+
for (const item of items) {
|
|
636
|
+
this.members.set(item.name, item);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** Parse aliases, filtering out non-introspectable symbol references */
|
|
641
|
+
private parseAliases(aliases: GirAliasElement[], options: OptionsLoad): void {
|
|
642
|
+
type NamedType = GirType & { $: { name: string } };
|
|
643
|
+
|
|
644
|
+
const parsed = aliases
|
|
645
|
+
.filter(isIntrospectable)
|
|
646
|
+
.map((b) => {
|
|
647
|
+
b.type = b.type
|
|
648
|
+
?.filter((t): t is NamedType => !!t?.$.name)
|
|
649
|
+
.map((t) => {
|
|
650
|
+
if (t.$.name && !this.hasSymbol(t.$.name) && !isPrimitiveType(t.$.name) && !t.$.name.includes(".")) {
|
|
651
|
+
return { $: { name: "unknown", "c:type": "unknown" } } as GirType;
|
|
652
|
+
}
|
|
653
|
+
return t;
|
|
654
|
+
});
|
|
655
|
+
return b;
|
|
656
|
+
})
|
|
657
|
+
.map((alias) => IntrospectedAlias.fromXML(alias, this, options))
|
|
658
|
+
.filter((alias): alias is IntrospectedAlias => alias != null);
|
|
659
|
+
|
|
660
|
+
for (const c of parsed) {
|
|
661
|
+
this.members.set(c.name, c);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/** Build the enum_constants map from parsed enum members */
|
|
666
|
+
private buildEnumConstantsMap(): void {
|
|
667
|
+
for (const m of this.members.values()) {
|
|
668
|
+
if (m instanceof IntrospectedEnum) {
|
|
669
|
+
for (const member of m.members.values()) {
|
|
670
|
+
this.enum_constants.set(member.c_identifier, [m.name, member.name] as const);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
573
676
|
/** Start to parse all the data from the XML we need for the typescript generation */
|
|
574
677
|
public parse() {
|
|
575
678
|
this.log.debug(`Parsing ${this.dependency.packageName}...`);
|
|
@@ -590,170 +693,27 @@ export class GirModule implements IGirModule {
|
|
|
590
693
|
throw new Error(`Missing namespace in ${packageName}`);
|
|
591
694
|
}
|
|
592
695
|
|
|
593
|
-
const importConflicts = (
|
|
594
|
-
el: IntrospectedConstant | IntrospectedBaseClass | IntrospectedFunction | IntrospectedEnum | IntrospectedError,
|
|
595
|
-
) => {
|
|
596
|
-
return !this.hasImport(el.name);
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
if (ns.enumeration) {
|
|
600
|
-
// Get the requested enums
|
|
601
|
-
const enumerations = ns.enumeration
|
|
602
|
-
?.filter(isIntrospectable)
|
|
603
|
-
.map((enumeration) => {
|
|
604
|
-
if (enumeration.$["glib:error-domain"]) {
|
|
605
|
-
return IntrospectedError.fromXML(enumeration as GirEnumElement, this, options);
|
|
606
|
-
} else {
|
|
607
|
-
return IntrospectedEnum.fromXML(enumeration as GirEnumElement, this, options);
|
|
608
|
-
}
|
|
609
|
-
})
|
|
610
|
-
.filter(importConflicts);
|
|
611
|
-
|
|
612
|
-
for (const c of enumerations) {
|
|
613
|
-
this.members.set(c.name, c);
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Constants
|
|
618
|
-
if (ns.constant) {
|
|
619
|
-
const constants = ns.constant
|
|
620
|
-
?.filter(isIntrospectable)
|
|
621
|
-
.map((constant) => IntrospectedConstant.fromXML(constant, this, options))
|
|
622
|
-
.filter(importConflicts);
|
|
623
|
-
|
|
624
|
-
for (const c of constants) {
|
|
625
|
-
this.members.set(c.name, c);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
// Get the requested functions
|
|
630
|
-
if (ns.function) {
|
|
631
|
-
const functions = ns.function
|
|
632
|
-
?.filter(isIntrospectable)
|
|
633
|
-
.map((func) => IntrospectedFunction.fromXML(func, this, options))
|
|
634
|
-
.filter(importConflicts);
|
|
635
|
-
|
|
636
|
-
for (const c of functions) {
|
|
637
|
-
this.members.set(c.name, c);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
if (ns.callback) {
|
|
642
|
-
const callbacks = ns.callback
|
|
643
|
-
?.filter(isIntrospectable)
|
|
644
|
-
.map((callback) => IntrospectedCallback.fromXML(callback, this, options))
|
|
645
|
-
.filter(importConflicts);
|
|
646
|
-
|
|
647
|
-
for (const c of callbacks) {
|
|
648
|
-
this.members.set(c.name, c);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
if (ns["glib:boxed"]) {
|
|
653
|
-
const boxed = ns["glib:boxed"]?.filter(isIntrospectable).map(
|
|
654
|
-
(boxed) =>
|
|
655
|
-
new IntrospectedAlias({
|
|
656
|
-
name: boxed.$["glib:name"],
|
|
657
|
-
namespace: this,
|
|
658
|
-
type: new NullableType(ObjectType),
|
|
659
|
-
}),
|
|
660
|
-
);
|
|
661
|
-
|
|
662
|
-
for (const c of boxed) {
|
|
663
|
-
this.members.set(c.name, c);
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Bitfield is a type of enum
|
|
668
|
-
if (ns.bitfield) {
|
|
669
|
-
const bitfields = ns.bitfield
|
|
670
|
-
?.filter(isIntrospectable)
|
|
671
|
-
.map((field) => IntrospectedEnum.fromXML(field as GirBitfieldElement, this, options, true));
|
|
672
|
-
|
|
673
|
-
for (const c of bitfields) {
|
|
674
|
-
this.members.set(c.name, c);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// The `enum_constants` map maps the C identifiers (GTK_BUTTON_TYPE_Y)
|
|
679
|
-
// to the name of the enum (Button) to resolve references (Gtk.Button.Y)
|
|
680
|
-
Array.from(this.members.values())
|
|
681
|
-
.filter((m): m is IntrospectedEnum => m instanceof IntrospectedEnum)
|
|
682
|
-
.forEach((m) => {
|
|
683
|
-
m.members.forEach((member) => {
|
|
684
|
-
this.enum_constants.set(member.c_identifier, [m.name, member.name] as const);
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
// Get the requested classes
|
|
689
|
-
if (ns.class) {
|
|
690
|
-
const classes = ns.class
|
|
691
|
-
?.filter(isIntrospectable)
|
|
692
|
-
.map((klass) => IntrospectedClass.fromXML(klass, this, options))
|
|
693
|
-
.filter(importConflicts);
|
|
694
|
-
|
|
695
|
-
for (const c of classes) {
|
|
696
|
-
this.members.set(c.name, c);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
if (ns.record) {
|
|
701
|
-
const records = ns.record
|
|
702
|
-
?.filter(isIntrospectable)
|
|
703
|
-
.map((record) => IntrospectedRecord.fromXML(record, this, options))
|
|
704
|
-
.filter(importConflicts);
|
|
696
|
+
const importConflicts = (el: { name: string }) => !this.hasImport(el.name);
|
|
705
697
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
for (const c of interfaces) {
|
|
728
|
-
this.members.set(c.name, c);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
if (ns.alias) {
|
|
733
|
-
type NamedType = GirType & { $: { name: string } };
|
|
734
|
-
|
|
735
|
-
const aliases = ns.alias
|
|
736
|
-
?.filter(isIntrospectable)
|
|
737
|
-
// Avoid attempting to alias non-introspectable symbols.
|
|
738
|
-
.map((b) => {
|
|
739
|
-
b.type = b.type
|
|
740
|
-
?.filter((t): t is NamedType => !!t?.$.name)
|
|
741
|
-
.map((t) => {
|
|
742
|
-
if (t.$.name && !this.hasSymbol(t.$.name) && !isPrimitiveType(t.$.name) && !t.$.name.includes(".")) {
|
|
743
|
-
return { $: { name: "unknown", "c:type": "unknown" } } as GirType;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
return t;
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
return b;
|
|
750
|
-
})
|
|
751
|
-
.map((alias) => IntrospectedAlias.fromXML(alias, this, options))
|
|
752
|
-
.filter((alias): alias is IntrospectedAlias => alias != null);
|
|
753
|
-
|
|
754
|
-
for (const c of aliases) {
|
|
755
|
-
this.members.set(c.name, c);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
698
|
+
this.parseEnumerations(ns.enumeration as GirEnumElement[] | undefined, options, importConflicts);
|
|
699
|
+
this.parseAndStore(
|
|
700
|
+
ns.constant,
|
|
701
|
+
(c) => IntrospectedConstant.fromXML(c as GirConstantElement, this, options),
|
|
702
|
+
importConflicts,
|
|
703
|
+
);
|
|
704
|
+
this.parseAndStore(ns.function, (f) => IntrospectedFunction.fromXML(f, this, options), importConflicts);
|
|
705
|
+
this.parseAndStore(ns.callback, (cb) => IntrospectedCallback.fromXML(cb, this, options), importConflicts);
|
|
706
|
+
this.parseBoxed(ns["glib:boxed"]);
|
|
707
|
+
this.parseAndStore(ns.bitfield, (f) => IntrospectedEnum.fromXML(f as GirBitfieldElement, this, options, true));
|
|
708
|
+
this.buildEnumConstantsMap();
|
|
709
|
+
this.parseAndStore(ns.class, (k) => IntrospectedClass.fromXML(k, this, options), importConflicts);
|
|
710
|
+
this.parseAndStore(ns.record, (r) => IntrospectedRecord.fromXML(r, this, options), importConflicts);
|
|
711
|
+
this.parseAndStore(ns.union, (u) => IntrospectedRecord.fromXML(u, this, options), importConflicts);
|
|
712
|
+
this.parseAndStore(
|
|
713
|
+
ns.interface,
|
|
714
|
+
(i) => IntrospectedInterface.fromXML(i as GirInterfaceElement, this, options),
|
|
715
|
+
importConflicts,
|
|
716
|
+
);
|
|
717
|
+
if (ns.alias) this.parseAliases(ns.alias, options);
|
|
758
718
|
}
|
|
759
719
|
}
|