@ts-for-gir/lib 4.0.0-rc.1 → 4.0.0-rc.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-for-gir/lib",
3
- "version": "4.0.0-rc.1",
3
+ "version": "4.0.0-rc.3",
4
4
  "description": "Typescript .d.ts generator from GIR for gjs",
5
5
  "main": "src/index.ts",
6
6
  "module": "src/index.ts",
@@ -41,7 +41,7 @@
41
41
  "type definitions"
42
42
  ],
43
43
  "devDependencies": {
44
- "@ts-for-gir/tsconfig": "^4.0.0-rc.1",
44
+ "@ts-for-gir/tsconfig": "^4.0.0-rc.3",
45
45
  "@types/ejs": "^3.1.5",
46
46
  "@types/lodash": "^4.17.24",
47
47
  "@types/node": "^24.12.2",
@@ -49,9 +49,9 @@
49
49
  "typescript": "^6.0.2"
50
50
  },
51
51
  "dependencies": {
52
- "@gi.ts/parser": "^4.0.0-rc.1",
53
- "@ts-for-gir/reporter": "^4.0.0-rc.1",
54
- "@ts-for-gir/templates": "^4.0.0-rc.1",
52
+ "@gi.ts/parser": "^4.0.0-rc.3",
53
+ "@ts-for-gir/reporter": "^4.0.0-rc.3",
54
+ "@ts-for-gir/templates": "^4.0.0-rc.3",
55
55
  "colorette": "^2.0.20",
56
56
  "ejs": "^5.0.1",
57
57
  "glob": "^13.0.6",
@@ -8,7 +8,6 @@ import { inject } from "../injections/inject.ts";
8
8
  import type { GeneratorConstructor, OptionsGeneration, OptionsTransform } from "../types/index.ts";
9
9
  import { TwoKeyMap } from "../util.ts";
10
10
  import { ClassVisitor } from "../validators/class.ts";
11
- import { FunctionParametersVisitor } from "../validators/function-parameters.ts";
12
11
  import { InterfaceVisitor } from "../validators/interface.ts";
13
12
  import type { GirVisitor } from "../visitor.ts";
14
13
  import type { IntrospectedNamespace } from "./namespace.ts";
@@ -113,13 +112,12 @@ export class NSRegistry {
113
112
  GObject.package_version = [...GLib.package_version];
114
113
 
115
114
  const interfaceVisitor = new InterfaceVisitor();
115
+
116
116
  this.registerTransformation(interfaceVisitor);
117
117
 
118
118
  const classVisitor = new ClassVisitor();
119
- this.registerTransformation(classVisitor);
120
119
 
121
- const enumParamsVisitor = new FunctionParametersVisitor();
122
- this.registerTransformation(enumParamsVisitor);
120
+ this.registerTransformation(classVisitor);
123
121
 
124
122
  console.log("Adding generics...");
125
123
  generify(this, options.inferGenerics);
package/src/gir.ts CHANGED
@@ -23,7 +23,7 @@ export enum ConflictType {
23
23
 
24
24
  import { type ConsoleReporter, LazyReporter } from "@ts-for-gir/reporter";
25
25
  import type { IntrospectedField, IntrospectedProperty } from "./gir/property.ts";
26
- import type { OptionsBase } from "./types/index.ts";
26
+ import type { OptionsGeneration } from "./types/index.ts";
27
27
  import { isInvalid, sanitizeIdentifierName, sanitizeNamespace } from "./utils/naming.ts";
28
28
 
29
29
  export abstract class TypeExpression {
@@ -37,10 +37,10 @@ export abstract class TypeExpression {
37
37
  }
38
38
 
39
39
  abstract rewrap(type: TypeExpression): TypeExpression;
40
- abstract resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression;
40
+ abstract resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression;
41
41
 
42
- abstract print(namespace: IntrospectedNamespace, options: OptionsBase): string;
43
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase): string {
42
+ abstract print(namespace: IntrospectedNamespace, options: OptionsGeneration): string;
43
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
44
44
  return this.print(namespace, options);
45
45
  }
46
46
  }
@@ -89,7 +89,7 @@ export class TypeIdentifier extends TypeExpression {
89
89
  return new TypeIdentifier(sanitizeIdentifierName(this.namespace, this.name), sanitizeNamespace(this.namespace));
90
90
  }
91
91
 
92
- protected _resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeIdentifier | null {
92
+ protected _resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeIdentifier | null {
93
93
  const name: string = sanitizeIdentifierName(null, this.name);
94
94
  const unresolvedNamespaceName = this.namespace;
95
95
 
@@ -183,11 +183,11 @@ export class TypeIdentifier extends TypeExpression {
183
183
  return null;
184
184
  }
185
185
 
186
- resolveIdentifier(namespace: IntrospectedNamespace, options: OptionsBase): TypeIdentifier | null {
186
+ resolveIdentifier(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeIdentifier | null {
187
187
  return this._resolve(namespace, options);
188
188
  }
189
189
 
190
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
190
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
191
191
  const resolved = this._resolve(namespace, options);
192
192
 
193
193
  // Generally if we can't resolve a type it is not introspectable,
@@ -199,7 +199,7 @@ export class TypeIdentifier extends TypeExpression {
199
199
  return new TypeIdentifier(name, namespace);
200
200
  }
201
201
 
202
- print(namespace: IntrospectedNamespace, _options: OptionsBase): string {
202
+ print(namespace: IntrospectedNamespace, _options: OptionsGeneration): string {
203
203
  if (namespace.hasSymbol(this.namespace) && this.namespace !== namespace.namespace) {
204
204
  // TODO: Move to TypeScript generator...
205
205
  // Libraries like zbar have classes named things like "Gtk"
@@ -248,11 +248,11 @@ export class ModuleTypeIdentifier extends TypeIdentifier {
248
248
  );
249
249
  }
250
250
 
251
- protected _resolve(_namespace: IntrospectedNamespace, _options: OptionsBase): ModuleTypeIdentifier | null {
251
+ protected _resolve(_namespace: IntrospectedNamespace, _options: OptionsGeneration): ModuleTypeIdentifier | null {
252
252
  return this;
253
253
  }
254
254
 
255
- print(namespace: IntrospectedNamespace, _options: OptionsBase): string {
255
+ print(namespace: IntrospectedNamespace, _options: OptionsGeneration): string {
256
256
  if (namespace.namespace === this.namespace) {
257
257
  return `${this.moduleName}.${this.name}`;
258
258
  } else {
@@ -269,7 +269,7 @@ export class ClassStructTypeIdentifier extends TypeIdentifier {
269
269
  return type instanceof ClassStructTypeIdentifier && super.equals(type);
270
270
  }
271
271
 
272
- print(namespace: IntrospectedNamespace, _options: OptionsBase): string {
272
+ print(namespace: IntrospectedNamespace, _options: OptionsGeneration): string {
273
273
  if (namespace.namespace === this.namespace) {
274
274
  // TODO: Mapping to invalid names should happen at the generator level...
275
275
  return `typeof ${isInvalid(this.name) ? `__${this.name}` : this.name}`;
@@ -287,7 +287,7 @@ export class GenerifiedTypeIdentifier extends TypeIdentifier {
287
287
  this.generics = generics;
288
288
  }
289
289
 
290
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
290
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
291
291
  const Generics = this.generics.map((generic) => generic.print(namespace, options)).join(", ");
292
292
 
293
293
  if (namespace.namespace === this.namespace) {
@@ -297,7 +297,7 @@ export class GenerifiedTypeIdentifier extends TypeIdentifier {
297
297
  }
298
298
  }
299
299
 
300
- _resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeIdentifier | null {
300
+ _resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeIdentifier | null {
301
301
  const iden = super._resolve(namespace, options);
302
302
 
303
303
  if (iden) {
@@ -309,9 +309,9 @@ export class GenerifiedTypeIdentifier extends TypeIdentifier {
309
309
  }
310
310
 
311
311
  export class NativeType extends TypeExpression {
312
- readonly expression: (options?: OptionsBase) => string;
312
+ readonly expression: (options?: OptionsGeneration) => string;
313
313
 
314
- constructor(expression: ((options?: OptionsBase) => string) | string) {
314
+ constructor(expression: ((options?: OptionsGeneration) => string) | string) {
315
315
  super();
316
316
  this.expression = typeof expression === "string" ? () => expression : expression;
317
317
  }
@@ -324,11 +324,11 @@ export class NativeType extends TypeExpression {
324
324
  return this;
325
325
  }
326
326
 
327
- print(_namespace: IntrospectedNamespace, options: OptionsBase): string {
327
+ print(_namespace: IntrospectedNamespace, options: OptionsGeneration): string {
328
328
  return this.expression(options);
329
329
  }
330
330
 
331
- equals(type: TypeExpression, options?: OptionsBase): boolean {
331
+ equals(type: TypeExpression, options?: OptionsGeneration): boolean {
332
332
  return type instanceof NativeType && this.expression(options) === type.expression(options);
333
333
  }
334
334
 
@@ -336,7 +336,7 @@ export class NativeType extends TypeExpression {
336
336
  return this;
337
337
  }
338
338
 
339
- static withGenerator(generator: (options?: OptionsBase) => string): TypeExpression {
339
+ static withGenerator(generator: (options?: OptionsGeneration) => string): TypeExpression {
340
340
  return new NativeType(generator);
341
341
  }
342
342
 
@@ -361,17 +361,17 @@ export class OrType extends TypeExpression {
361
361
  return this;
362
362
  }
363
363
 
364
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
364
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
365
365
  const [type, ...types] = this.types;
366
366
 
367
367
  return new OrType(type.resolve(namespace, options), ...types.map((t) => t.resolve(namespace, options)));
368
368
  }
369
369
 
370
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
370
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
371
371
  return `(${this.types.map((t) => t.print(namespace, options)).join(" | ")})`;
372
372
  }
373
373
 
374
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase): string {
374
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
375
375
  return `${this.types.map((t) => t.print(namespace, options)).join(" | ")}`;
376
376
  }
377
377
 
@@ -385,15 +385,15 @@ export class OrType extends TypeExpression {
385
385
  }
386
386
 
387
387
  export class TupleType extends OrType {
388
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
388
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
389
389
  return `[${this.types.map((t) => t.print(namespace, options)).join(", ")}]`;
390
390
  }
391
391
 
392
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase): string {
392
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
393
393
  return this.print(namespace, options);
394
394
  }
395
395
 
396
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
396
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
397
397
  const [type, ...types] = this.types;
398
398
 
399
399
  return new TupleType(type.resolve(namespace, options), ...types.map((t) => t.resolve(namespace, options)));
@@ -413,7 +413,7 @@ export class BinaryType extends OrType {
413
413
  return this;
414
414
  }
415
415
 
416
- resolve(namespace: IntrospectedNamespace, options: OptionsBase) {
416
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration) {
417
417
  return new BinaryType(this.a.resolve(namespace, options), this.b.resolve(namespace, options));
418
418
  }
419
419
 
@@ -465,7 +465,7 @@ export class FunctionType extends TypeExpression {
465
465
  return this;
466
466
  }
467
467
 
468
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
468
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
469
469
  return new FunctionType(
470
470
  Object.fromEntries(
471
471
  Object.entries(this.parameterTypes).map(([k, p]) => {
@@ -476,7 +476,7 @@ export class FunctionType extends TypeExpression {
476
476
  );
477
477
  }
478
478
 
479
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase): string {
479
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
480
480
  const Parameters = Object.entries(this.parameterTypes)
481
481
  .map(([k, v]) => {
482
482
  return `${k}: ${v.rootPrint(namespace, options)}`;
@@ -486,7 +486,7 @@ export class FunctionType extends TypeExpression {
486
486
  return `(${Parameters}) => ${this.returnType.print(namespace, options)}`;
487
487
  }
488
488
 
489
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
489
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
490
490
  return `(${this.rootPrint(namespace, options)})`;
491
491
  }
492
492
  }
@@ -548,7 +548,7 @@ export class GenerifiedType extends TypeExpression {
548
548
  this.generic = generic;
549
549
  }
550
550
 
551
- resolve(namespace: IntrospectedNamespace, options: OptionsBase) {
551
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration) {
552
552
  return new GenerifiedType(this.type.resolve(namespace, options), this.generic);
553
553
  }
554
554
 
@@ -556,11 +556,11 @@ export class GenerifiedType extends TypeExpression {
556
556
  return this.type;
557
557
  }
558
558
 
559
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase) {
559
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration) {
560
560
  return this.type.rootPrint(namespace, options);
561
561
  }
562
562
 
563
- print(namespace: IntrospectedNamespace, options: OptionsBase) {
563
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration) {
564
564
  return `${this.type.print(namespace, options)}<${this.generic.print()}>`;
565
565
  }
566
566
 
@@ -652,11 +652,11 @@ export class PromiseType extends TypeExpression {
652
652
  return new PromiseType(this.type.rewrap(type));
653
653
  }
654
654
 
655
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
655
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
656
656
  return new PromiseType(this.type.resolve(namespace, options));
657
657
  }
658
658
 
659
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
659
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
660
660
  if (this.type.equals(VoidType)) {
661
661
  return "globalThis.Promise<void>";
662
662
  }
@@ -664,7 +664,7 @@ export class PromiseType extends TypeExpression {
664
664
  return `globalThis.Promise<${this.type.print(namespace, options)}>`;
665
665
  }
666
666
 
667
- rootPrint(namespace: IntrospectedNamespace, options: OptionsBase): string {
667
+ rootPrint(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
668
668
  return this.print(namespace, options);
669
669
  }
670
670
  }
@@ -703,13 +703,13 @@ export class TypeConflict extends TypeExpression {
703
703
  return true;
704
704
  }
705
705
 
706
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
706
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
707
707
  const resolvedType = this.type.resolve(namespace, options);
708
708
  const typeString = resolvedType.print(namespace, options);
709
709
  throw new Error(`Type conflict was not resolved for ${typeString} in ${namespace.namespace}`);
710
710
  }
711
711
 
712
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
712
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
713
713
  const resolvedType = this.type.resolve(namespace, options);
714
714
  const typeString = resolvedType.print(namespace, options);
715
715
  throw new Error(`Type conflict was not resolved for ${typeString} in ${namespace.namespace}`);
@@ -750,7 +750,7 @@ export class ClosureType extends TypeExpression {
750
750
  return this;
751
751
  }
752
752
 
753
- resolve(namespace: IntrospectedNamespace, options: OptionsBase) {
753
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration) {
754
754
  const { user_data, type } = this;
755
755
 
756
756
  return ClosureType.new({
@@ -759,7 +759,7 @@ export class ClosureType extends TypeExpression {
759
759
  });
760
760
  }
761
761
 
762
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
762
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
763
763
  return this.type.print(namespace, options);
764
764
  }
765
765
 
@@ -807,7 +807,7 @@ export class ArrayType extends TypeExpression {
807
807
  return false;
808
808
  }
809
809
 
810
- resolve(namespace: IntrospectedNamespace, options: OptionsBase): TypeExpression {
810
+ resolve(namespace: IntrospectedNamespace, options: OptionsGeneration): TypeExpression {
811
811
  const { type, arrayDepth, length } = this;
812
812
  return ArrayType.new({
813
813
  type: type.resolve(namespace, options),
@@ -816,7 +816,7 @@ export class ArrayType extends TypeExpression {
816
816
  });
817
817
  }
818
818
 
819
- print(namespace: IntrospectedNamespace, options: OptionsBase): string {
819
+ print(namespace: IntrospectedNamespace, options: OptionsGeneration): string {
820
820
  const depth = this.arrayDepth;
821
821
  let typeSuffix: string = "";
822
822
 
@@ -861,6 +861,7 @@ export const Uint8ArrayType = new NativeType("Uint8Array");
861
861
  export const BooleanType = new NativeType("boolean");
862
862
  export const StringType = new NativeType("string");
863
863
  export const NumberType = new NativeType("number");
864
+ export const BigintOrNumberType = new BinaryType(new NativeType("bigint"), NumberType);
864
865
  export const NullType = new NativeType("null");
865
866
  export const VoidType = new NativeType("void");
866
867
  export const UnknownType = new NativeType("unknown");
@@ -14,6 +14,7 @@ import { LazyReporter } from "@ts-for-gir/reporter";
14
14
  import type { IntrospectedNamespace } from "../gir/namespace.ts";
15
15
  import {
16
16
  ArrayType,
17
+ BigintOrNumberType,
17
18
  ClosureType,
18
19
  GenerifiedTypeIdentifier,
19
20
  NativeType,
@@ -238,7 +239,8 @@ export function getType(
238
239
  parameter.$ &&
239
240
  (parameter.$.direction === GirDirection.Inout || parameter.$.direction === GirDirection.Out) &&
240
241
  (nullable || allowNone) &&
241
- !(variableType instanceof NativeType)
242
+ !(variableType instanceof NativeType) &&
243
+ variableType !== BigintOrNumberType
242
244
  ) {
243
245
  return new NullableType(variableType);
244
246
  }
@@ -4,14 +4,19 @@ import type { IntrospectedNamespace } from "../gir/namespace.ts";
4
4
  import {
5
5
  AnyType,
6
6
  ArrayType,
7
+ BigintOrNumberType,
7
8
  BinaryType,
8
9
  BooleanType,
9
10
  NativeType,
10
11
  NeverType,
12
+ NullableType,
11
13
  NumberType,
12
14
  ObjectType,
15
+ OrType,
16
+ PromiseType,
13
17
  StringType,
14
18
  ThisType,
19
+ TupleType,
15
20
  type TypeExpression,
16
21
  TypeIdentifier,
17
22
  Uint8ArrayType,
@@ -167,18 +172,20 @@ export function resolvePrimitiveType(name: string): TypeExpression | null {
167
172
  case "gfloat":
168
173
  case "gchar":
169
174
  case "guint":
170
- case "glong":
171
- case "gulong":
172
175
  case "gint":
173
176
  case "guint8":
177
+ case "gdouble":
178
+ return NumberType;
179
+ case "glong":
180
+ case "gulong":
174
181
  case "guint64":
175
182
  case "gint64":
176
- case "gdouble":
177
183
  case "gssize":
178
184
  case "gsize":
185
+ case "guintptr": // Integer of the same width as a pointer
179
186
  case "time_t": // C standard library time type (seconds since Unix epoch)
180
187
  case "ulong": // C standard library unsigned long type
181
- return NumberType;
188
+ return BigintOrNumberType;
182
189
  case "gboolean":
183
190
  return BooleanType;
184
191
  case "gpointer": // This is typically used in callbacks to pass data, so we'll allow anything.
@@ -187,8 +194,6 @@ export function resolvePrimitiveType(name: string): TypeExpression | null {
187
194
  return ObjectType;
188
195
  case "va_list":
189
196
  return AnyType;
190
- case "guintptr": // You can't use pointers in GJS! (at least that I'm aware of)
191
- return NeverType;
192
197
  case "never": // Support TS "never"
193
198
  return NeverType;
194
199
  case "unknown": // Support TS "unknown"
@@ -243,6 +248,27 @@ export function resolveDirectedType(type: TypeExpression, direction: GirDirectio
243
248
  return type;
244
249
  }
245
250
  }
251
+ } else if (type === BigintOrNumberType && direction === GirDirection.Out) {
252
+ // 64-bit integers accept number or bigint, but only return number to JS
253
+ return NumberType;
254
+ } else if (type instanceof PromiseType) {
255
+ // Propagate direction into the Promise's inner type so e.g. async
256
+ // functions returning 64-bit ints resolve to `Promise<number>` rather
257
+ // than `Promise<bigint | number>`.
258
+ const resolvedInner = resolveDirectedType(type.type, direction);
259
+ if (resolvedInner) return new PromiseType(resolvedInner);
260
+ } else if (type instanceof BinaryType && !(type instanceof NullableType)) {
261
+ // Walk through binary unions like `Promise<T> | void` (the dual-call
262
+ // async overload) so the inner types still get direction propagation.
263
+ // NullableType is skipped to preserve its subclass behaviour.
264
+ const a = resolveDirectedType(type.a, direction) ?? type.a;
265
+ const b = resolveDirectedType(type.b, direction) ?? type.b;
266
+ if (a !== type.a || b !== type.b) return new BinaryType(a, b);
267
+ } else if (type instanceof OrType && !(type instanceof BinaryType || type instanceof TupleType)) {
268
+ // flatten "bigint | number" out of another OR-type
269
+ const types = type.types.map((t) => resolveDirectedType(t, direction) ?? t);
270
+ if (types.length === 1) return types[0];
271
+ return new OrType(types[0], ...types.slice(1));
246
272
  }
247
273
 
248
274
  return null;
@@ -1,52 +0,0 @@
1
- import type { IntrospectedEnum } from "../gir/enum.ts";
2
- import type { IntrospectedFunction } from "../gir/function.ts";
3
- import type { IntrospectedBaseClass, IntrospectedClassFunction } from "../gir/introspected-classes.ts";
4
-
5
- import { NullableType, TypeIdentifier } from "../gir.ts";
6
- import { GirVisitor } from "../visitor.ts";
7
-
8
- export class FunctionParametersVisitor extends GirVisitor {
9
- /**
10
- * Marks all enum parameters of a function as nullable,
11
- * because GJS allows null values for enum parameters and treats them as a 0 value.
12
- * See issue [#207](https://github.com/gjsify/ts-for-gir/issues/207).
13
- */
14
- private makeEnumParamsNullable(node: IntrospectedFunction): IntrospectedFunction;
15
- private makeEnumParamsNullable<T extends IntrospectedBaseClass | IntrospectedEnum>(
16
- node: IntrospectedClassFunction<T>,
17
- ): IntrospectedClassFunction<T>;
18
- private makeEnumParamsNullable(
19
- node: IntrospectedFunction | IntrospectedClassFunction,
20
- ): IntrospectedFunction | IntrospectedClassFunction {
21
- return node.copy({
22
- parameters: node.parameters.map((param) => {
23
- const type = param.type.deepUnwrap();
24
- if (type instanceof TypeIdentifier) {
25
- // Get the namespace where this type should be defined
26
- const ns = node.namespace.assertInstalledImport(type.namespace);
27
-
28
- // Check if the type is an enum
29
- const isEnumType = !!ns.getEnum(type.name);
30
-
31
- // If it is, make the parameter nullable
32
- if (isEnumType) {
33
- return param.copy({
34
- type: new NullableType(param.type),
35
- });
36
- }
37
- }
38
- return param;
39
- }),
40
- });
41
- }
42
-
43
- visitFunction = (node: IntrospectedFunction): IntrospectedFunction => {
44
- return this.makeEnumParamsNullable(node);
45
- };
46
-
47
- visitClassFunction = <T extends IntrospectedBaseClass | IntrospectedEnum>(
48
- node: IntrospectedClassFunction<T>,
49
- ): IntrospectedClassFunction<T> => {
50
- return this.makeEnumParamsNullable(node);
51
- };
52
- }