@ts-for-gir/lib 4.0.0-beta.40 → 4.0.0-beta.42
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 +13 -47
- 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/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
|
}
|
package/src/gir.ts
CHANGED
|
@@ -21,7 +21,7 @@ export enum ConflictType {
|
|
|
21
21
|
VFUNC_SIGNATURE_CONFLICT,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
import { ConsoleReporter,
|
|
24
|
+
import { type ConsoleReporter, LazyReporter } from "@ts-for-gir/reporter";
|
|
25
25
|
import type { IntrospectedField, IntrospectedProperty } from "./gir/property.ts";
|
|
26
26
|
import type { OptionsBase } from "./types/index.ts";
|
|
27
27
|
import { isInvalid, sanitizeIdentifierName, sanitizeNamespace } from "./utils/naming.ts";
|
|
@@ -49,44 +49,14 @@ export class TypeIdentifier extends TypeExpression {
|
|
|
49
49
|
readonly name: string;
|
|
50
50
|
readonly namespace: string;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
private static reporterConfig: { enabled: boolean; output: string } = {
|
|
54
|
-
enabled: false,
|
|
55
|
-
output: "ts-for-gir-report.json",
|
|
56
|
-
};
|
|
57
|
-
private static globalReporter: ConsoleReporter | null = null;
|
|
52
|
+
private static readonly reporter = new LazyReporter("TypeIdentifier");
|
|
58
53
|
|
|
59
|
-
static configureReporter(enabled: boolean, output
|
|
60
|
-
TypeIdentifier.
|
|
61
|
-
|
|
62
|
-
// Reset global reporter to force recreation with new config
|
|
63
|
-
if (TypeIdentifier.globalReporter) {
|
|
64
|
-
TypeIdentifier.globalReporter = null;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Create and register the global reporter if enabled
|
|
68
|
-
if (enabled) {
|
|
69
|
-
TypeIdentifier.globalReporter = new ConsoleReporter(true, "TypeIdentifier", enabled, output);
|
|
70
|
-
const reporterService = ReporterService.getInstance();
|
|
71
|
-
reporterService.registerReporter("TypeIdentifier", TypeIdentifier.globalReporter);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private static getReporter(): ConsoleReporter {
|
|
76
|
-
if (!TypeIdentifier.globalReporter) {
|
|
77
|
-
const config = TypeIdentifier.reporterConfig;
|
|
78
|
-
TypeIdentifier.globalReporter = new ConsoleReporter(true, "TypeIdentifier", config.enabled, config.output);
|
|
79
|
-
|
|
80
|
-
if (config.enabled) {
|
|
81
|
-
const reporterService = ReporterService.getInstance();
|
|
82
|
-
reporterService.registerReporter("TypeIdentifier", TypeIdentifier.globalReporter);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return TypeIdentifier.globalReporter;
|
|
54
|
+
static configureReporter(enabled: boolean, output?: string) {
|
|
55
|
+
TypeIdentifier.reporter.configure(enabled, output);
|
|
86
56
|
}
|
|
87
57
|
|
|
88
58
|
get log(): ConsoleReporter {
|
|
89
|
-
return TypeIdentifier.
|
|
59
|
+
return TypeIdentifier.reporter.get();
|
|
90
60
|
}
|
|
91
61
|
|
|
92
62
|
constructor(name: string, namespace: string) {
|
|
@@ -194,7 +164,7 @@ export class TypeIdentifier extends TypeExpression {
|
|
|
194
164
|
|
|
195
165
|
return new TypeIdentifier(c_resolved_name, ns.namespace);
|
|
196
166
|
} else if (namespace.namespace === ns.namespace) {
|
|
197
|
-
this.log.
|
|
167
|
+
this.log.reportTypeResolutionWarning(
|
|
198
168
|
this.name,
|
|
199
169
|
ns.namespace,
|
|
200
170
|
`Unable to resolve type ${this.name} in same namespace ${ns.namespace}!`,
|
|
@@ -203,11 +173,12 @@ export class TypeIdentifier extends TypeExpression {
|
|
|
203
173
|
return null;
|
|
204
174
|
}
|
|
205
175
|
|
|
206
|
-
this.log.
|
|
176
|
+
this.log.reportTypeResolutionWarning(
|
|
207
177
|
this.name,
|
|
208
178
|
this.namespace,
|
|
209
179
|
`Type ${this.name} could not be resolved in ${namespace.namespace} ${namespace.version}`,
|
|
210
|
-
`
|
|
180
|
+
`Referenced from ${namespace.namespace} ${namespace.version}`,
|
|
181
|
+
`${namespace.namespace} ${namespace.version}`,
|
|
211
182
|
);
|
|
212
183
|
return null;
|
|
213
184
|
}
|
|
@@ -876,7 +847,12 @@ export class ArrayType extends TypeExpression {
|
|
|
876
847
|
}
|
|
877
848
|
}
|
|
878
849
|
|
|
879
|
-
|
|
850
|
+
/**
|
|
851
|
+
* Common native types as constants.
|
|
852
|
+
* These represent TypeScript types in generated .d.ts output for GJS runtime,
|
|
853
|
+
* not internal tool types. Uses of `any` here are intentional — they produce
|
|
854
|
+
* correct type definitions for GLib/GIO/GObject APIs that accept dynamic values.
|
|
855
|
+
*/
|
|
880
856
|
export const ThisType = new NativeType("this");
|
|
881
857
|
export const ObjectType = new NativeType("object");
|
|
882
858
|
export const AnyType = new NativeType("any");
|
package/src/injections/gio.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GIO type injection overrides.
|
|
3
|
+
* Uses of `any`/`AnyType` in this file are intentional — they produce
|
|
4
|
+
* generated .d.ts output matching GIO's dynamic runtime behavior.
|
|
5
|
+
*/
|
|
1
6
|
import { GirDirection } from "@gi.ts/parser";
|
|
2
7
|
import { IntrospectedAlias } from "../gir/alias.ts";
|
|
3
8
|
import { IntrospectedConstructor } from "../gir/constructor.ts";
|
|
@@ -28,6 +33,7 @@ import {
|
|
|
28
33
|
Uint8ArrayType,
|
|
29
34
|
VoidType,
|
|
30
35
|
} from "../gir.ts";
|
|
36
|
+
import { girParsingReporter } from "../utils/gir-parsing.ts";
|
|
31
37
|
|
|
32
38
|
export default {
|
|
33
39
|
namespace: "Gio",
|
|
@@ -700,7 +706,14 @@ export default {
|
|
|
700
706
|
if (existingMethodIndex !== -1) {
|
|
701
707
|
ActionMap.members[existingMethodIndex] = newMethod;
|
|
702
708
|
} else {
|
|
703
|
-
|
|
709
|
+
girParsingReporter
|
|
710
|
+
.get()
|
|
711
|
+
.reportParsingFailure(
|
|
712
|
+
"add_action_entries",
|
|
713
|
+
"method",
|
|
714
|
+
"Gio",
|
|
715
|
+
"Could not find existing add_action_entries method to override in Gio.ActionMap",
|
|
716
|
+
);
|
|
704
717
|
ActionMap.members.push(newMethod);
|
|
705
718
|
}
|
|
706
719
|
},
|
package/src/injections/glib.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GLib type injection overrides.
|
|
3
|
+
* Uses of `any`/`AnyType` in this file are intentional — they produce
|
|
4
|
+
* generated .d.ts output matching GLib's dynamic runtime behavior.
|
|
5
|
+
*/
|
|
1
6
|
import { GirDirection } from "@gi.ts/parser";
|
|
2
7
|
import { IntrospectedConstructor } from "../gir/constructor.ts";
|
|
3
8
|
import { IntrospectedDirectAllocationConstructor } from "../gir/direct-allocation-constructor.ts";
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GObject type injection overrides.
|
|
3
|
+
* Uses of `any`/`AnyType` in this file are intentional — they produce
|
|
4
|
+
* generated .d.ts output matching GObject's dynamic runtime behavior.
|
|
5
|
+
*/
|
|
1
6
|
import { GirDirection } from "@gi.ts/parser";
|
|
2
7
|
import { IntrospectedAlias } from "../gir/alias.ts";
|
|
3
8
|
import { IntrospectedFunction } from "../gir/function.ts";
|
|
@@ -50,4 +50,16 @@ export interface OptionsGeneration extends OptionsBase {
|
|
|
50
50
|
* Output file path for the reporter
|
|
51
51
|
*/
|
|
52
52
|
reporterOutput: string;
|
|
53
|
+
/** Generate a single unified documentation for all modules instead of separate per-module docs */
|
|
54
|
+
combined?: boolean;
|
|
55
|
+
/** URL template for source links in generated documentation. Supports {path}, {line}, {gitRevision} placeholders */
|
|
56
|
+
sourceLinkTemplate?: string;
|
|
57
|
+
/** Theme for HTML documentation generation (default: "gi-docgen") */
|
|
58
|
+
theme?: string;
|
|
59
|
+
/** Path to a README file to use as the documentation index page (default: "none") */
|
|
60
|
+
readme?: string;
|
|
61
|
+
/** Use TypeDoc merge mode to generate HTML from pre-generated JSON files */
|
|
62
|
+
merge?: boolean;
|
|
63
|
+
/** Directory containing pre-generated TypeDoc JSON files for merge mode (from 'ts-for-gir json') */
|
|
64
|
+
jsonDir?: string;
|
|
53
65
|
}
|
package/src/types/user-config.ts
CHANGED
|
@@ -55,4 +55,16 @@ export interface UserConfig {
|
|
|
55
55
|
* Output file path for the reporter
|
|
56
56
|
*/
|
|
57
57
|
reporterOutput: string;
|
|
58
|
+
/** Generate a single unified documentation for all modules instead of separate per-module docs */
|
|
59
|
+
combined?: boolean;
|
|
60
|
+
/** URL template for source links in generated documentation. Supports {path}, {line}, {gitRevision} placeholders */
|
|
61
|
+
sourceLinkTemplate?: string;
|
|
62
|
+
/** Theme for HTML documentation generation (default: "gi-docgen") */
|
|
63
|
+
theme?: string;
|
|
64
|
+
/** Path to a README file to use as the documentation index page (default: "none") */
|
|
65
|
+
readme?: string;
|
|
66
|
+
/** Use TypeDoc merge mode to generate HTML from pre-generated JSON files */
|
|
67
|
+
merge?: boolean;
|
|
68
|
+
/** Directory containing pre-generated TypeDoc JSON files for merge mode (from 'ts-for-gir json') */
|
|
69
|
+
jsonDir?: string;
|
|
58
70
|
}
|
package/src/utils/conflicts.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GirDirection } from "@gi.ts/parser";
|
|
2
|
-
import {
|
|
2
|
+
import { LazyReporter } from "@ts-for-gir/reporter";
|
|
3
3
|
import { IntrospectedConstructor } from "../gir/constructor.ts";
|
|
4
4
|
import { FilterBehavior } from "../gir/data.ts";
|
|
5
5
|
import type { IntrospectedFunction } from "../gir/function.ts";
|
|
@@ -20,48 +20,14 @@ import { AnyType, ArrayType, ConflictType, NeverType, TypeConflict } from "../gi
|
|
|
20
20
|
import { findMap } from "../util.ts";
|
|
21
21
|
import { isSubtypeOf } from "./type-resolution.ts";
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
let conflictsReporterInstance: ConsoleReporter | null = null;
|
|
25
|
-
let conflictsReporterConfig: { enabled: boolean; output: string } = {
|
|
26
|
-
enabled: false,
|
|
27
|
-
output: "ts-for-gir-report.json",
|
|
28
|
-
};
|
|
23
|
+
export const conflictsReporter = new LazyReporter("conflicts");
|
|
29
24
|
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Create and register the global reporter if enabled
|
|
39
|
-
if (enabled) {
|
|
40
|
-
conflictsReporterInstance = new ConsoleReporter(true, "conflicts", enabled, output);
|
|
41
|
-
const reporterService = ReporterService.getInstance();
|
|
42
|
-
reporterService.registerReporter("conflicts", conflictsReporterInstance);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getConflictsReporterInstance(): ConsoleReporter {
|
|
47
|
-
if (!conflictsReporterInstance) {
|
|
48
|
-
const config = conflictsReporterConfig;
|
|
49
|
-
conflictsReporterInstance = new ConsoleReporter(true, "conflicts", config.enabled, config.output);
|
|
50
|
-
|
|
51
|
-
// Register with reporter service if reporting is enabled
|
|
52
|
-
if (config.enabled) {
|
|
53
|
-
const reporterService = ReporterService.getInstance();
|
|
54
|
-
reporterService.registerReporter("conflicts", conflictsReporterInstance);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return conflictsReporterInstance;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const log = getConflictsReporterInstance();
|
|
61
|
-
|
|
62
|
-
// Export function to configure conflicts reporter
|
|
63
|
-
export function configureConflictsReporter(enabled: boolean, output: string = "ts-for-gir-report.json") {
|
|
64
|
-
configureConflictsReporterInternal(enabled, output);
|
|
25
|
+
// Use a function to always get the current reporter instance.
|
|
26
|
+
// A module-level `const log = conflictsReporter.get()` would capture a stale
|
|
27
|
+
// reference from before configure() is called, causing problems to be logged
|
|
28
|
+
// to console but not stored in the report.
|
|
29
|
+
function getLog() {
|
|
30
|
+
return conflictsReporter.get();
|
|
65
31
|
}
|
|
66
32
|
|
|
67
33
|
// Constants for GObject methods that always conflict
|
|
@@ -119,7 +85,7 @@ export function filterFunctionConflict<
|
|
|
119
85
|
|
|
120
86
|
if (conflictResult.shouldOmit) {
|
|
121
87
|
// Always omit methods that conflict with properties/fields
|
|
122
|
-
|
|
88
|
+
getLog().reportTypeConflict(
|
|
123
89
|
"field_property",
|
|
124
90
|
next.name,
|
|
125
91
|
next.parent?.namespace.namespace || "unknown",
|
|
@@ -127,7 +93,7 @@ export function filterFunctionConflict<
|
|
|
127
93
|
);
|
|
128
94
|
} else if (conflictResult.hasConflict) {
|
|
129
95
|
if (isInheritedMethods) {
|
|
130
|
-
|
|
96
|
+
getLog().reportTypeConflict(
|
|
131
97
|
"method",
|
|
132
98
|
next.name,
|
|
133
99
|
next.parent?.namespace.namespace || "unknown",
|
|
@@ -445,7 +411,7 @@ function checkPropertyConflicts<T extends IntrospectedClassMember | Introspected
|
|
|
445
411
|
element instanceof IntrospectedProperty &&
|
|
446
412
|
!isSubtypeOf(ns, thisType, resolved_parent.getType(), element.type, p.type)
|
|
447
413
|
) {
|
|
448
|
-
|
|
414
|
+
getLog().reportTypeConflict(
|
|
449
415
|
"general",
|
|
450
416
|
element.name,
|
|
451
417
|
element.parent?.namespace.namespace || "unknown",
|