@gtkx/gir 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/index.d.ts +25 -12
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +21 -10
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/loader.d.ts +30 -0
  6. package/dist/internal/loader.d.ts.map +1 -0
  7. package/dist/internal/loader.js +109 -0
  8. package/dist/internal/loader.js.map +1 -0
  9. package/dist/internal/normalizer.d.ts +98 -15
  10. package/dist/internal/normalizer.d.ts.map +1 -1
  11. package/dist/internal/normalizer.js +381 -412
  12. package/dist/internal/normalizer.js.map +1 -1
  13. package/dist/internal/parser.d.ts +23 -31
  14. package/dist/internal/parser.d.ts.map +1 -1
  15. package/dist/internal/parser.js +228 -244
  16. package/dist/internal/parser.js.map +1 -1
  17. package/dist/internal/raw-types.d.ts +58 -109
  18. package/dist/internal/raw-types.d.ts.map +1 -1
  19. package/dist/internal/raw-types.js +0 -8
  20. package/dist/internal/raw-types.js.map +1 -1
  21. package/dist/intrinsics.d.ts.map +1 -1
  22. package/dist/intrinsics.js +7 -0
  23. package/dist/intrinsics.js.map +1 -1
  24. package/dist/model/alias.d.ts +21 -0
  25. package/dist/model/alias.d.ts.map +1 -0
  26. package/dist/model/alias.js +22 -0
  27. package/dist/model/alias.js.map +1 -0
  28. package/dist/model/callables.d.ts +102 -0
  29. package/dist/model/callables.d.ts.map +1 -0
  30. package/dist/model/callables.js +123 -0
  31. package/dist/model/callables.js.map +1 -0
  32. package/dist/model/callback.d.ts +22 -0
  33. package/dist/model/callback.d.ts.map +1 -0
  34. package/dist/model/callback.js +20 -0
  35. package/dist/model/callback.js.map +1 -0
  36. package/dist/model/class.d.ts +92 -0
  37. package/dist/model/class.d.ts.map +1 -0
  38. package/dist/model/class.js +171 -0
  39. package/dist/model/class.js.map +1 -0
  40. package/dist/model/constant.d.ts +21 -0
  41. package/dist/model/constant.d.ts.map +1 -0
  42. package/dist/model/constant.js +20 -0
  43. package/dist/model/constant.js.map +1 -0
  44. package/dist/model/enumeration.d.ts +41 -0
  45. package/dist/model/enumeration.d.ts.map +1 -0
  46. package/dist/model/enumeration.js +47 -0
  47. package/dist/model/enumeration.js.map +1 -0
  48. package/dist/model/field.d.ts +21 -0
  49. package/dist/model/field.d.ts.map +1 -0
  50. package/dist/model/field.js +20 -0
  51. package/dist/model/field.js.map +1 -0
  52. package/dist/model/interface.d.ts +44 -0
  53. package/dist/model/interface.d.ts.map +1 -0
  54. package/dist/model/interface.js +67 -0
  55. package/dist/model/interface.js.map +1 -0
  56. package/dist/model/namespace.d.ts +44 -0
  57. package/dist/model/namespace.d.ts.map +1 -0
  58. package/dist/model/namespace.js +36 -0
  59. package/dist/model/namespace.js.map +1 -0
  60. package/dist/model/parameter.d.ts +43 -0
  61. package/dist/model/parameter.d.ts.map +1 -0
  62. package/dist/model/parameter.js +54 -0
  63. package/dist/model/parameter.js.map +1 -0
  64. package/dist/model/property.d.ts +62 -0
  65. package/dist/model/property.d.ts.map +1 -0
  66. package/dist/model/property.js +69 -0
  67. package/dist/model/property.js.map +1 -0
  68. package/dist/model/record.d.ts +56 -0
  69. package/dist/model/record.d.ts.map +1 -0
  70. package/dist/model/record.js +70 -0
  71. package/dist/model/record.js.map +1 -0
  72. package/dist/model/repository-like.d.ts +19 -0
  73. package/dist/model/repository-like.d.ts.map +1 -0
  74. package/dist/model/repository-like.js +2 -0
  75. package/dist/model/repository-like.js.map +1 -0
  76. package/dist/model/signal.d.ts +22 -0
  77. package/dist/model/signal.d.ts.map +1 -0
  78. package/dist/model/signal.js +22 -0
  79. package/dist/model/signal.js.map +1 -0
  80. package/dist/model/type.d.ts +71 -0
  81. package/dist/model/type.d.ts.map +1 -0
  82. package/dist/model/type.js +112 -0
  83. package/dist/model/type.js.map +1 -0
  84. package/dist/repository.d.ts +92 -138
  85. package/dist/repository.d.ts.map +1 -1
  86. package/dist/repository.js +155 -219
  87. package/dist/repository.js.map +1 -1
  88. package/package.json +4 -3
  89. package/src/index.ts +25 -39
  90. package/src/internal/loader.ts +127 -0
  91. package/src/internal/normalizer.ts +451 -475
  92. package/src/internal/parser.ts +242 -284
  93. package/src/internal/raw-types.ts +65 -116
  94. package/src/intrinsics.ts +7 -0
  95. package/src/model/alias.ts +31 -0
  96. package/src/model/callables.ts +172 -0
  97. package/src/model/callback.ts +30 -0
  98. package/src/model/class.ts +215 -0
  99. package/src/model/constant.ts +29 -0
  100. package/src/model/enumeration.ts +64 -0
  101. package/src/model/field.ts +29 -0
  102. package/src/model/interface.ts +89 -0
  103. package/src/model/namespace.ts +60 -0
  104. package/src/model/parameter.ts +74 -0
  105. package/src/model/property.ts +97 -0
  106. package/src/model/record.ts +97 -0
  107. package/src/model/repository-like.ts +20 -0
  108. package/src/model/signal.ts +32 -0
  109. package/src/model/type.ts +143 -0
  110. package/src/repository.ts +197 -283
  111. package/dist/types.d.ts +0 -655
  112. package/dist/types.d.ts.map +0 -1
  113. package/dist/types.js +0 -879
  114. package/dist/types.js.map +0 -1
  115. package/src/types.ts +0 -1192
@@ -0,0 +1,215 @@
1
+ import type { GirConstructor, GirFunction, GirMethod } from "./callables.js";
2
+ import type { GirProperty } from "./property.js";
3
+ import type { RepositoryLike } from "./repository-like.js";
4
+ import type { GirSignal } from "./signal.js";
5
+
6
+ /**
7
+ * GObject class with helper methods for type graph traversal.
8
+ *
9
+ * Receives a repository reference at construction time to enable
10
+ * inheritance chain traversal and interface resolution.
11
+ */
12
+ export class GirClass {
13
+ readonly name: string;
14
+ readonly qualifiedName: string;
15
+ readonly cType: string;
16
+ readonly parent: string | null;
17
+ readonly abstract: boolean;
18
+ readonly glibTypeName?: string;
19
+ readonly glibGetType?: string;
20
+ readonly cSymbolPrefix?: string;
21
+ readonly fundamental: boolean;
22
+ readonly refFunc?: string;
23
+ readonly unrefFunc?: string;
24
+ readonly implements: string[];
25
+ readonly methods: GirMethod[];
26
+ readonly constructors: GirConstructor[];
27
+ readonly staticFunctions: GirFunction[];
28
+ readonly properties: GirProperty[];
29
+ readonly signals: GirSignal[];
30
+ readonly doc?: string;
31
+
32
+ private readonly repo: RepositoryLike;
33
+
34
+ constructor(
35
+ data: {
36
+ name: string;
37
+ qualifiedName: string;
38
+ cType: string;
39
+ parent: string | null;
40
+ abstract: boolean;
41
+ glibTypeName?: string;
42
+ glibGetType?: string;
43
+ cSymbolPrefix?: string;
44
+ fundamental?: boolean;
45
+ refFunc?: string;
46
+ unrefFunc?: string;
47
+ implements: string[];
48
+ methods: GirMethod[];
49
+ constructors: GirConstructor[];
50
+ staticFunctions: GirFunction[];
51
+ properties: GirProperty[];
52
+ signals: GirSignal[];
53
+ doc?: string;
54
+ },
55
+ repo: RepositoryLike,
56
+ ) {
57
+ this.name = data.name;
58
+ this.qualifiedName = data.qualifiedName;
59
+ this.cType = data.cType;
60
+ this.parent = data.parent;
61
+ this.abstract = data.abstract;
62
+ this.glibTypeName = data.glibTypeName;
63
+ this.glibGetType = data.glibGetType;
64
+ this.cSymbolPrefix = data.cSymbolPrefix;
65
+ this.fundamental = data.fundamental ?? false;
66
+ this.refFunc = data.refFunc;
67
+ this.unrefFunc = data.unrefFunc;
68
+ this.implements = data.implements;
69
+ this.methods = data.methods;
70
+ this.constructors = data.constructors;
71
+ this.staticFunctions = data.staticFunctions;
72
+ this.properties = data.properties;
73
+ this.signals = data.signals;
74
+ this.doc = data.doc;
75
+ this.repo = repo;
76
+ }
77
+
78
+ /** Checks if this class is a subclass of another (direct or transitive). */
79
+ isSubclassOf(qualifiedName: string): boolean {
80
+ if (this.qualifiedName === qualifiedName) return true;
81
+ if (!this.parent) return false;
82
+ if (this.parent === qualifiedName) return true;
83
+ const parentClass = this.repo.resolveClass(this.parent);
84
+ return parentClass?.isSubclassOf(qualifiedName) ?? false;
85
+ }
86
+
87
+ /** Gets the full inheritance chain from this class to the root. */
88
+ getInheritanceChain(): string[] {
89
+ const chain: string[] = [this.qualifiedName];
90
+ let current: GirClass | null = this as GirClass;
91
+ while (current?.parent) {
92
+ chain.push(current.parent);
93
+ current = this.repo.resolveClass(current.parent);
94
+ }
95
+ return chain;
96
+ }
97
+
98
+ /** Gets the parent class object, or null if this is a root class. */
99
+ getParent(): GirClass | null {
100
+ return this.parent ? this.repo.resolveClass(this.parent) : null;
101
+ }
102
+
103
+ /** Checks if this class directly or transitively implements an interface. */
104
+ implementsInterface(qualifiedName: string): boolean {
105
+ if (this.implements.includes(qualifiedName)) return true;
106
+ const parent = this.getParent();
107
+ return parent?.implementsInterface(qualifiedName) ?? false;
108
+ }
109
+
110
+ /** Gets all implemented interfaces including inherited ones. */
111
+ getAllImplementedInterfaces(): string[] {
112
+ const interfaces = new Set<string>(this.implements);
113
+ let current = this.getParent();
114
+ while (current) {
115
+ for (const iface of current.implements) {
116
+ interfaces.add(iface);
117
+ }
118
+ current = current.getParent();
119
+ }
120
+ return [...interfaces];
121
+ }
122
+
123
+ /** Finds a method defined on this class by name. */
124
+ getMethod(name: string): GirMethod | null {
125
+ return this.methods.find((m) => m.name === name) ?? null;
126
+ }
127
+
128
+ /** Finds a property defined on this class by name. */
129
+ getProperty(name: string): GirProperty | null {
130
+ return this.properties.find((p) => p.name === name) ?? null;
131
+ }
132
+
133
+ /** Finds a signal defined on this class by name. */
134
+ getSignal(name: string): GirSignal | null {
135
+ return this.signals.find((s) => s.name === name) ?? null;
136
+ }
137
+
138
+ /** Finds a constructor by name. */
139
+ getConstructor(name: string): GirConstructor | null {
140
+ return this.constructors.find((c) => c.name === name) ?? null;
141
+ }
142
+
143
+ /** Gets all methods including inherited ones. */
144
+ getAllMethods(): GirMethod[] {
145
+ const methods = [...this.methods];
146
+ let current = this.getParent();
147
+ while (current) {
148
+ methods.push(...current.methods);
149
+ current = current.getParent();
150
+ }
151
+ return methods;
152
+ }
153
+
154
+ /** Gets all properties including inherited ones. */
155
+ getAllProperties(): GirProperty[] {
156
+ const properties = [...this.properties];
157
+ let current = this.getParent();
158
+ while (current) {
159
+ properties.push(...current.properties);
160
+ current = current.getParent();
161
+ }
162
+ return properties;
163
+ }
164
+
165
+ /** Gets all signals including inherited ones. */
166
+ getAllSignals(): GirSignal[] {
167
+ const signals = [...this.signals];
168
+ let current = this.getParent();
169
+ while (current) {
170
+ signals.push(...current.signals);
171
+ current = current.getParent();
172
+ }
173
+ return signals;
174
+ }
175
+
176
+ /** Finds a method by name, searching up the inheritance chain. */
177
+ findMethod(name: string): GirMethod | null {
178
+ return this.getMethod(name) ?? this.getParent()?.findMethod(name) ?? null;
179
+ }
180
+
181
+ /** Finds a method by its C identifier. */
182
+ getMethodByCIdentifier(cIdentifier: string): GirMethod | null {
183
+ return this.methods.find((m) => m.cIdentifier === cIdentifier) ?? null;
184
+ }
185
+
186
+ /** Finds a property by name, searching up the inheritance chain. */
187
+ findProperty(name: string): GirProperty | null {
188
+ return this.getProperty(name) ?? this.getParent()?.findProperty(name) ?? null;
189
+ }
190
+
191
+ /** Finds a signal by name, searching up the inheritance chain. */
192
+ findSignal(name: string): GirSignal | null {
193
+ return this.getSignal(name) ?? this.getParent()?.findSignal(name) ?? null;
194
+ }
195
+
196
+ /** True if this is an abstract class. */
197
+ isAbstract(): boolean {
198
+ return this.abstract;
199
+ }
200
+
201
+ /** True if this has a GType (most GObject classes do). */
202
+ hasGType(): boolean {
203
+ return this.glibTypeName !== undefined;
204
+ }
205
+
206
+ /** True if this is a fundamental type with custom ref/unref functions. */
207
+ isFundamental(): boolean {
208
+ return this.fundamental && this.refFunc !== undefined && this.unrefFunc !== undefined;
209
+ }
210
+
211
+ /** Gets direct subclasses of this class. */
212
+ getDirectSubclasses(): GirClass[] {
213
+ return this.repo.findClasses((cls) => cls.parent === this.qualifiedName);
214
+ }
215
+ }
@@ -0,0 +1,29 @@
1
+ import type { GirType } from "./type.js";
2
+
3
+ /**
4
+ * Constant value defined in a GIR namespace.
5
+ */
6
+ export class GirConstant {
7
+ readonly name: string;
8
+ readonly qualifiedName: string;
9
+ readonly cType: string;
10
+ readonly value: string;
11
+ readonly type: GirType;
12
+ readonly doc?: string;
13
+
14
+ constructor(data: {
15
+ name: string;
16
+ qualifiedName: string;
17
+ cType: string;
18
+ value: string;
19
+ type: GirType;
20
+ doc?: string;
21
+ }) {
22
+ this.name = data.name;
23
+ this.qualifiedName = data.qualifiedName;
24
+ this.cType = data.cType;
25
+ this.value = data.value;
26
+ this.type = data.type;
27
+ this.doc = data.doc;
28
+ }
29
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Enumeration member.
3
+ */
4
+ export class GirEnumerationMember {
5
+ readonly name: string;
6
+ readonly value: string;
7
+ readonly cIdentifier: string;
8
+ readonly doc?: string;
9
+
10
+ constructor(data: {
11
+ name: string;
12
+ value: string;
13
+ cIdentifier: string;
14
+ doc?: string;
15
+ }) {
16
+ this.name = data.name;
17
+ this.value = data.value;
18
+ this.cIdentifier = data.cIdentifier;
19
+ this.doc = data.doc;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Enumeration or bitfield with helper methods.
25
+ */
26
+ export class GirEnumeration {
27
+ readonly name: string;
28
+ readonly qualifiedName: string;
29
+ readonly cType: string;
30
+ readonly members: GirEnumerationMember[];
31
+ readonly glibGetType?: string;
32
+ readonly doc?: string;
33
+
34
+ constructor(data: {
35
+ name: string;
36
+ qualifiedName: string;
37
+ cType: string;
38
+ members: GirEnumerationMember[];
39
+ glibGetType?: string;
40
+ doc?: string;
41
+ }) {
42
+ this.name = data.name;
43
+ this.qualifiedName = data.qualifiedName;
44
+ this.cType = data.cType;
45
+ this.members = data.members;
46
+ this.glibGetType = data.glibGetType;
47
+ this.doc = data.doc;
48
+ }
49
+
50
+ /** Finds a member by name. */
51
+ getMember(name: string): GirEnumerationMember | null {
52
+ return this.members.find((m) => m.name === name) ?? null;
53
+ }
54
+
55
+ /** Finds a member by value. */
56
+ getMemberByValue(value: string): GirEnumerationMember | null {
57
+ return this.members.find((m) => m.value === value) ?? null;
58
+ }
59
+
60
+ /** Gets all member names. */
61
+ getMemberNames(): string[] {
62
+ return this.members.map((m) => m.name);
63
+ }
64
+ }
@@ -0,0 +1,29 @@
1
+ import type { GirType } from "./type.js";
2
+
3
+ /**
4
+ * Field within a record or class.
5
+ */
6
+ export class GirField {
7
+ readonly name: string;
8
+ readonly type: GirType;
9
+ readonly writable: boolean;
10
+ readonly readable: boolean;
11
+ readonly private: boolean;
12
+ readonly doc?: string;
13
+
14
+ constructor(data: {
15
+ name: string;
16
+ type: GirType;
17
+ writable: boolean;
18
+ readable: boolean;
19
+ private: boolean;
20
+ doc?: string;
21
+ }) {
22
+ this.name = data.name;
23
+ this.type = data.type;
24
+ this.writable = data.writable;
25
+ this.readable = data.readable;
26
+ this.private = data.private;
27
+ this.doc = data.doc;
28
+ }
29
+ }
@@ -0,0 +1,89 @@
1
+ import type { GirMethod } from "./callables.js";
2
+ import type { GirProperty } from "./property.js";
3
+ import type { RepositoryLike } from "./repository-like.js";
4
+ import type { GirSignal } from "./signal.js";
5
+
6
+ /**
7
+ * GObject interface with helper methods.
8
+ *
9
+ * Receives a repository reference at construction time to enable
10
+ * prerequisite traversal across the type graph.
11
+ */
12
+ export class GirInterface {
13
+ readonly name: string;
14
+ readonly qualifiedName: string;
15
+ readonly cType: string;
16
+ readonly glibTypeName?: string;
17
+ readonly prerequisites: string[];
18
+ readonly methods: GirMethod[];
19
+ readonly properties: GirProperty[];
20
+ readonly signals: GirSignal[];
21
+ readonly doc?: string;
22
+
23
+ private readonly repo: RepositoryLike;
24
+
25
+ constructor(
26
+ data: {
27
+ name: string;
28
+ qualifiedName: string;
29
+ cType: string;
30
+ glibTypeName?: string;
31
+ prerequisites: string[];
32
+ methods: GirMethod[];
33
+ properties: GirProperty[];
34
+ signals: GirSignal[];
35
+ doc?: string;
36
+ },
37
+ repo: RepositoryLike,
38
+ ) {
39
+ this.name = data.name;
40
+ this.qualifiedName = data.qualifiedName;
41
+ this.cType = data.cType;
42
+ this.glibTypeName = data.glibTypeName;
43
+ this.prerequisites = data.prerequisites;
44
+ this.methods = data.methods;
45
+ this.properties = data.properties;
46
+ this.signals = data.signals;
47
+ this.doc = data.doc;
48
+ this.repo = repo;
49
+ }
50
+
51
+ /** Checks if this interface has a prerequisite (direct or transitive). */
52
+ hasPrerequisite(qualifiedName: string): boolean {
53
+ if (this.prerequisites.includes(qualifiedName)) return true;
54
+ for (const prereq of this.prerequisites) {
55
+ const prereqIface = this.repo.resolveInterface(prereq);
56
+ if (prereqIface?.hasPrerequisite(qualifiedName)) return true;
57
+ }
58
+ return false;
59
+ }
60
+
61
+ /** Gets all prerequisites including transitive ones. */
62
+ getAllPrerequisites(): string[] {
63
+ const all = new Set<string>(this.prerequisites);
64
+ for (const prereq of this.prerequisites) {
65
+ const prereqIface = this.repo.resolveInterface(prereq);
66
+ if (prereqIface) {
67
+ for (const p of prereqIface.getAllPrerequisites()) {
68
+ all.add(p);
69
+ }
70
+ }
71
+ }
72
+ return [...all];
73
+ }
74
+
75
+ /** Finds a method by name. */
76
+ getMethod(name: string): GirMethod | null {
77
+ return this.methods.find((m) => m.name === name) ?? null;
78
+ }
79
+
80
+ /** Finds a property by name. */
81
+ getProperty(name: string): GirProperty | null {
82
+ return this.properties.find((p) => p.name === name) ?? null;
83
+ }
84
+
85
+ /** Finds a signal by name. */
86
+ getSignal(name: string): GirSignal | null {
87
+ return this.signals.find((s) => s.name === name) ?? null;
88
+ }
89
+ }
@@ -0,0 +1,60 @@
1
+ import type { GirAlias } from "./alias.js";
2
+ import type { GirFunction } from "./callables.js";
3
+ import type { GirCallback } from "./callback.js";
4
+ import type { GirClass } from "./class.js";
5
+ import type { GirConstant } from "./constant.js";
6
+ import type { GirEnumeration } from "./enumeration.js";
7
+ import type { GirInterface } from "./interface.js";
8
+ import type { GirRecord } from "./record.js";
9
+
10
+ /**
11
+ * Namespace containing all resolved types from a single GIR file.
12
+ */
13
+ export class GirNamespace {
14
+ readonly name: string;
15
+ readonly version: string;
16
+ readonly sharedLibrary: string;
17
+ readonly cPrefix: string;
18
+ readonly classes: Map<string, GirClass>;
19
+ readonly interfaces: Map<string, GirInterface>;
20
+ readonly records: Map<string, GirRecord>;
21
+ readonly enumerations: Map<string, GirEnumeration>;
22
+ readonly bitfields: Map<string, GirEnumeration>;
23
+ readonly callbacks: Map<string, GirCallback>;
24
+ readonly functions: Map<string, GirFunction>;
25
+ readonly constants: Map<string, GirConstant>;
26
+ readonly aliases: Map<string, GirAlias>;
27
+ readonly doc?: string;
28
+
29
+ constructor(data: {
30
+ name: string;
31
+ version: string;
32
+ sharedLibrary: string;
33
+ cPrefix: string;
34
+ classes: Map<string, GirClass>;
35
+ interfaces: Map<string, GirInterface>;
36
+ records: Map<string, GirRecord>;
37
+ enumerations: Map<string, GirEnumeration>;
38
+ bitfields: Map<string, GirEnumeration>;
39
+ callbacks: Map<string, GirCallback>;
40
+ functions: Map<string, GirFunction>;
41
+ constants: Map<string, GirConstant>;
42
+ aliases: Map<string, GirAlias>;
43
+ doc?: string;
44
+ }) {
45
+ this.name = data.name;
46
+ this.version = data.version;
47
+ this.sharedLibrary = data.sharedLibrary;
48
+ this.cPrefix = data.cPrefix;
49
+ this.classes = data.classes;
50
+ this.interfaces = data.interfaces;
51
+ this.records = data.records;
52
+ this.enumerations = data.enumerations;
53
+ this.bitfields = data.bitfields;
54
+ this.callbacks = data.callbacks;
55
+ this.functions = data.functions;
56
+ this.constants = data.constants;
57
+ this.aliases = data.aliases;
58
+ this.doc = data.doc;
59
+ }
60
+ }
@@ -0,0 +1,74 @@
1
+ import type { GirType } from "./type.js";
2
+
3
+ /**
4
+ * Parameter to a function, method, or callback.
5
+ */
6
+ export class GirParameter {
7
+ readonly name: string;
8
+ readonly type: GirType;
9
+ readonly direction: "in" | "out" | "inout";
10
+ readonly callerAllocates: boolean;
11
+ readonly nullable: boolean;
12
+ readonly optional: boolean;
13
+ readonly scope?: "async" | "call" | "notified" | "forever";
14
+ readonly closure?: number;
15
+ readonly destroy?: number;
16
+ readonly transferOwnership?: "none" | "full" | "container";
17
+ readonly doc?: string;
18
+
19
+ constructor(data: {
20
+ name: string;
21
+ type: GirType;
22
+ direction: "in" | "out" | "inout";
23
+ callerAllocates: boolean;
24
+ nullable: boolean;
25
+ optional: boolean;
26
+ scope?: "async" | "call" | "notified" | "forever";
27
+ closure?: number;
28
+ destroy?: number;
29
+ transferOwnership?: "none" | "full" | "container";
30
+ doc?: string;
31
+ }) {
32
+ this.name = data.name;
33
+ this.type = data.type;
34
+ this.direction = data.direction;
35
+ this.callerAllocates = data.callerAllocates;
36
+ this.nullable = data.nullable;
37
+ this.optional = data.optional;
38
+ this.scope = data.scope;
39
+ this.closure = data.closure;
40
+ this.destroy = data.destroy;
41
+ this.transferOwnership = data.transferOwnership;
42
+ this.doc = data.doc;
43
+ }
44
+
45
+ /** True if this is an input parameter. */
46
+ isIn(): boolean {
47
+ return this.direction === "in";
48
+ }
49
+
50
+ /** True if this is an output parameter. */
51
+ isOut(): boolean {
52
+ return this.direction === "out" || this.direction === "inout";
53
+ }
54
+
55
+ /** True if this is a callback parameter (has scope). */
56
+ isCallback(): boolean {
57
+ return this.scope !== undefined;
58
+ }
59
+
60
+ /** True if this is the user_data for a callback. */
61
+ isClosureData(): boolean {
62
+ return this.closure !== undefined;
63
+ }
64
+
65
+ /** True if this is a destroy notify for a callback. */
66
+ isDestroyNotify(): boolean {
67
+ return this.destroy !== undefined;
68
+ }
69
+
70
+ /** True if caller must allocate memory for this out param. */
71
+ requiresCallerAllocation(): boolean {
72
+ return this.callerAllocates && this.isOut();
73
+ }
74
+ }
@@ -0,0 +1,97 @@
1
+ import type { GirType } from "./type.js";
2
+
3
+ /**
4
+ * Parsed default value from GIR property definitions.
5
+ */
6
+ export type DefaultValue =
7
+ | { kind: "null" }
8
+ | { kind: "boolean"; value: boolean }
9
+ | { kind: "number"; value: number }
10
+ | { kind: "string"; value: string }
11
+ | { kind: "enum"; cIdentifier: string }
12
+ | { kind: "unknown"; raw: string };
13
+
14
+ /**
15
+ * Parses a raw default value string from GIR into a typed DefaultValue.
16
+ */
17
+ export function parseDefaultValue(raw: string | undefined): DefaultValue | null {
18
+ if (raw === undefined) return null;
19
+ if (raw === "NULL") return { kind: "null" };
20
+ if (raw === "TRUE") return { kind: "boolean", value: true };
21
+ if (raw === "FALSE") return { kind: "boolean", value: false };
22
+
23
+ const num = Number(raw);
24
+ if (!Number.isNaN(num)) return { kind: "number", value: num };
25
+
26
+ if (raw.startsWith('"') && raw.endsWith('"')) {
27
+ return { kind: "string", value: raw.slice(1, -1) };
28
+ }
29
+
30
+ if (/^[A-Z][A-Z0-9_]*$/.test(raw)) {
31
+ return { kind: "enum", cIdentifier: raw };
32
+ }
33
+
34
+ return { kind: "unknown", raw };
35
+ }
36
+
37
+ /**
38
+ * GObject property with helper methods.
39
+ */
40
+ export class GirProperty {
41
+ readonly name: string;
42
+ readonly type: GirType;
43
+ readonly readable: boolean;
44
+ readonly writable: boolean;
45
+ readonly constructOnly: boolean;
46
+ readonly defaultValue: DefaultValue | null;
47
+ readonly getter?: string;
48
+ readonly setter?: string;
49
+ readonly doc?: string;
50
+
51
+ constructor(data: {
52
+ name: string;
53
+ type: GirType;
54
+ readable: boolean;
55
+ writable: boolean;
56
+ constructOnly: boolean;
57
+ defaultValue: DefaultValue | null;
58
+ getter?: string;
59
+ setter?: string;
60
+ doc?: string;
61
+ }) {
62
+ this.name = data.name;
63
+ this.type = data.type;
64
+ this.readable = data.readable;
65
+ this.writable = data.writable;
66
+ this.constructOnly = data.constructOnly;
67
+ this.defaultValue = data.defaultValue;
68
+ this.getter = data.getter;
69
+ this.setter = data.setter;
70
+ this.doc = data.doc;
71
+ }
72
+
73
+ /** True if this property has a default value. */
74
+ get hasDefault(): boolean {
75
+ return this.defaultValue !== null;
76
+ }
77
+
78
+ /** True if readable but not writable. */
79
+ isReadOnly(): boolean {
80
+ return this.readable && !this.writable;
81
+ }
82
+
83
+ /** True if writable but not readable. */
84
+ isWriteOnly(): boolean {
85
+ return this.writable && !this.readable;
86
+ }
87
+
88
+ /** True if can only be set during construction. */
89
+ isConstructOnly(): boolean {
90
+ return this.constructOnly;
91
+ }
92
+
93
+ /** True if has both getter and setter methods. */
94
+ hasAccessors(): boolean {
95
+ return this.getter !== undefined && this.setter !== undefined;
96
+ }
97
+ }