@gtkx/codegen 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/analysis/descriptor-render.d.ts +7 -1
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +36 -15
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +4 -1
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +11 -2
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/param-capability.d.ts +5 -2
- package/dist/analysis/param-capability.d.ts.map +1 -1
- package/dist/analysis/param-capability.js +36 -4
- package/dist/analysis/param-capability.js.map +1 -1
- package/dist/analysis/param-structure.d.ts +1 -1
- package/dist/analysis/param-structure.d.ts.map +1 -1
- package/dist/analysis/param-structure.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +1 -1
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +28 -10
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/compile.js +1 -1
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +6 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +11 -2
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/pipeline.d.ts +3 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +10 -1
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/fingerprint.d.ts +5 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +107 -15
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +3 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +29 -7
- package/dist/gi.js.map +1 -1
- package/dist/gir/external-namespaces.d.ts +8 -0
- package/dist/gir/external-namespaces.d.ts.map +1 -0
- package/dist/gir/external-namespaces.js +4 -0
- package/dist/gir/external-namespaces.js.map +1 -0
- package/dist/gir/finish-overrides.d.ts +3 -0
- package/dist/gir/finish-overrides.d.ts.map +1 -0
- package/dist/gir/finish-overrides.js +5 -0
- package/dist/gir/finish-overrides.js.map +1 -0
- package/dist/gir/function.d.ts +5 -2
- package/dist/gir/function.d.ts.map +1 -1
- package/dist/gir/function.js +34 -5
- package/dist/gir/function.js.map +1 -1
- package/dist/gir/hidden-symbols.d.ts +3 -0
- package/dist/gir/hidden-symbols.d.ts.map +1 -0
- package/dist/gir/hidden-symbols.js +39 -0
- package/dist/gir/hidden-symbols.js.map +1 -0
- package/dist/gir/library.d.ts +22 -2
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +21 -3
- package/dist/gir/library.js.map +1 -1
- package/dist/gir/ucs4-overrides.d.ts +3 -0
- package/dist/gir/ucs4-overrides.d.ts.map +1 -0
- package/dist/gir/ucs4-overrides.js +7 -0
- package/dist/gir/ucs4-overrides.js.map +1 -0
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +27 -8
- package/dist/jsx.js.map +1 -1
- package/dist/runner.d.ts +8 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +9 -3
- package/dist/runner.js.map +1 -1
- package/dist/store/external-package-links.d.ts +6 -0
- package/dist/store/external-package-links.d.ts.map +1 -0
- package/dist/store/external-package-links.js +158 -0
- package/dist/store/external-package-links.js.map +1 -0
- package/dist/store/gi/callable-doc.d.ts.map +1 -1
- package/dist/store/gi/callable-doc.js +4 -4
- package/dist/store/gi/callable-doc.js.map +1 -1
- package/dist/store/gi/callables.d.ts +1 -1
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +4 -4
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +25 -15
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/constructor-props.js +1 -1
- package/dist/store/gi/constructor-props.js.map +1 -1
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +2 -1
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/gtype-binding.d.ts +2 -2
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +6 -13
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/interface.js +2 -2
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts +7 -2
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +126 -30
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/param-marshal.d.ts +8 -1
- package/dist/store/gi/param-marshal.d.ts.map +1 -1
- package/dist/store/gi/param-marshal.js +52 -4
- package/dist/store/gi/param-marshal.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +2 -3
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +2 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +142 -16
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record-layout.d.ts +5 -2
- package/dist/store/gi/record-layout.d.ts.map +1 -1
- package/dist/store/gi/record-layout.js +2 -1
- package/dist/store/gi/record-layout.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +9 -5
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/runtime-override.js +1 -1
- package/dist/store/gi/runtime-override.js.map +1 -1
- package/dist/store/gi/signal.js +2 -2
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/vtable.d.ts.map +1 -1
- package/dist/store/gi/vtable.js +82 -12
- package/dist/store/gi/vtable.js.map +1 -1
- package/dist/store/gi-store.d.ts +7 -2
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js +19 -4
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/jsx.d.ts.map +1 -1
- package/dist/store/jsx/jsx.js +3 -1
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx-store.d.ts +8 -1
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +9 -2
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts +2 -1
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +2 -1
- package/dist/store/resolve-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +2 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +8 -3
- package/dist/store/store-fs.js.map +1 -1
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +8 -0
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/gtk-doc.d.ts.map +1 -1
- package/dist/writer/gtk-doc.js +27 -1
- package/dist/writer/gtk-doc.js.map +1 -1
- package/overrides/gdk/rgba.ts.ejs +15 -1
- package/overrides/glib/index.ts.ejs +3 -0
- package/overrides/glib/regex.ts.ejs +66 -0
- package/overrides/gobject/index.ts.ejs +3 -0
- package/overrides/gobject/object-class.ts.ejs +27 -0
- package/overrides/gobject/param-spec-getters.ts.ejs +57 -0
- package/overrides/gobject/param-spec.ts.ejs +21 -0
- package/overrides/gobject/value.ts.ejs +6 -1
- package/overrides/graphene/structs.ts.ejs +38 -3
- package/overrides/gtk/index.ts.ejs +2 -0
- package/overrides/gtk/widget-class.ts.ejs +28 -0
- package/package.json +6 -5
- package/src/analysis/descriptor-render.ts +59 -16
- package/src/analysis/descriptor.ts +15 -3
- package/src/analysis/param-capability.ts +68 -5
- package/src/analysis/param-structure.ts +1 -1
- package/src/analysis/ts-type.ts +45 -11
- package/src/compile.ts +1 -1
- package/src/docs/api-reference.ts +20 -2
- package/src/docs/pipeline.ts +15 -1
- package/src/fingerprint.ts +144 -16
- package/src/gi.ts +44 -9
- package/src/gir/external-namespaces.ts +8 -0
- package/src/gir/finish-overrides.ts +5 -0
- package/src/gir/function.ts +52 -14
- package/src/gir/hidden-symbols.ts +39 -0
- package/src/gir/library.ts +36 -3
- package/src/gir/ucs4-overrides.ts +7 -0
- package/src/jsx.ts +33 -8
- package/src/runner.ts +17 -3
- package/src/store/external-package-links.ts +226 -0
- package/src/store/gi/callable-doc.ts +8 -4
- package/src/store/gi/callables.ts +5 -5
- package/src/store/gi/class.ts +42 -32
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/function.ts +2 -1
- package/src/store/gi/gtype-binding.ts +7 -15
- package/src/store/gi/interface.ts +2 -2
- package/src/store/gi/method.ts +189 -36
- package/src/store/gi/param-marshal.ts +67 -4
- package/src/store/gi/record-constructor.ts +8 -3
- package/src/store/gi/record-field-accessor.ts +209 -16
- package/src/store/gi/record-layout.ts +11 -1
- package/src/store/gi/record.ts +17 -13
- package/src/store/gi/runtime-override.ts +1 -1
- package/src/store/gi/signal.ts +2 -2
- package/src/store/gi/vtable.ts +118 -11
- package/src/store/gi-store.ts +33 -3
- package/src/store/jsx/jsx.ts +3 -1
- package/src/store/jsx-store.ts +23 -7
- package/src/store/resolve-store.ts +2 -1
- package/src/store/store-fs.ts +10 -2
- package/src/writer/context.ts +11 -0
- package/src/writer/gtk-doc.ts +38 -1
- package/overrides/cairo/context.ts.ejs +0 -1269
- package/overrides/cairo/font-face.ts.ejs +0 -151
- package/overrides/cairo/font-options.ts.ejs +0 -199
- package/overrides/cairo/image-surface.ts.ejs +0 -132
- package/overrides/cairo/index.ts.ejs +0 -22
- package/overrides/cairo/matrix.ts.ejs +0 -171
- package/overrides/cairo/pattern.ts.ejs +0 -476
- package/overrides/cairo/recording-surface.ts.ejs +0 -102
- package/overrides/cairo/region.ts.ejs +0 -237
- package/overrides/cairo/scaled-font.ts.ejs +0 -330
- package/overrides/cairo/surface.ts.ejs +0 -296
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { toCamelIdentifier } from "@gtkx/utils";
|
|
2
2
|
import type { GirAnnotations } from "../../gir/annotations.js";
|
|
3
3
|
import type { GirField } from "../../gir/field.js";
|
|
4
|
+
import type { PrimitiveCategory } from "../../gir/primitives.js";
|
|
4
5
|
import type { GirRecord } from "../../gir/record.js";
|
|
5
6
|
import type { FieldSlot } from "../../gir/size.js";
|
|
6
7
|
import type { TypeId } from "../../gir/type-id.js";
|
|
@@ -9,10 +10,16 @@ import type { ModuleContext } from "../../writer/context.js";
|
|
|
9
10
|
import { isInlineCallbackRef, renderDescriptor } from "../../analysis/descriptor-render.js";
|
|
10
11
|
import { tStruct } from "../../analysis/descriptor.js";
|
|
11
12
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
12
|
-
import { isUnboundedArray } from "../../analysis/type-shape.js";
|
|
13
|
+
import { isByteSequence, isUnboundedArray } from "../../analysis/type-shape.js";
|
|
13
14
|
import { indent, renderBlock } from "../../writer/emit.js";
|
|
14
15
|
import { getDoc } from "./doc-spec.js";
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
bitMask,
|
|
18
|
+
computeRecordFieldSlots,
|
|
19
|
+
inlineArrayStride,
|
|
20
|
+
mergeBitfield,
|
|
21
|
+
type RecordFieldSlot,
|
|
22
|
+
} from "./record-layout.js";
|
|
16
23
|
import { wrapReturnValue } from "./return-wrap.js";
|
|
17
24
|
import { isValueMarshalable } from "./value-marshalable.js";
|
|
18
25
|
|
|
@@ -99,6 +106,22 @@ type AccessorOptions = {
|
|
|
99
106
|
fieldType: TypeId;
|
|
100
107
|
};
|
|
101
108
|
|
|
109
|
+
type InlineArrayResolution = {
|
|
110
|
+
element: TypeId;
|
|
111
|
+
count: number;
|
|
112
|
+
stride: number;
|
|
113
|
+
isTypedByteArray: boolean;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
type InlineArrayAccessorOptions = {
|
|
117
|
+
context: ModuleContext;
|
|
118
|
+
jsName: string;
|
|
119
|
+
tsType: string;
|
|
120
|
+
descriptor: string;
|
|
121
|
+
offset: number;
|
|
122
|
+
resolution: InlineArrayResolution;
|
|
123
|
+
};
|
|
124
|
+
|
|
102
125
|
const isMarshalableField = (context: ModuleContext, field: GirField): boolean => {
|
|
103
126
|
if (field.cType?.endsWith("*") === true) {
|
|
104
127
|
return true;
|
|
@@ -187,6 +210,9 @@ const isStorableFieldType = (context: ModuleContext, ref: TypeId): boolean => {
|
|
|
187
210
|
return kind !== "carray" && kind !== "list" && kind !== "hashtable";
|
|
188
211
|
};
|
|
189
212
|
|
|
213
|
+
const hasArrayAccessor = (context: ModuleContext, target: StructArrayTarget): boolean =>
|
|
214
|
+
resolveInlineArray(context, target) !== undefined || resolveStructArray(context, target) !== undefined;
|
|
215
|
+
|
|
190
216
|
const admitAccessibleField = (
|
|
191
217
|
context: ModuleContext,
|
|
192
218
|
slot: RecordFieldSlot,
|
|
@@ -201,9 +227,9 @@ const admitAccessibleField = (
|
|
|
201
227
|
|
|
202
228
|
const { field, jsName } = admitted;
|
|
203
229
|
const target: StructArrayTarget = { field, jsName, slot: slot.slot, siblingFields };
|
|
204
|
-
const
|
|
205
|
-
const hasAccessor =
|
|
206
|
-
const isSettable = field.writable && (
|
|
230
|
+
const hasArray = hasArrayAccessor(context, target);
|
|
231
|
+
const hasAccessor = hasArray || isAccessibleFieldType(context, field.type);
|
|
232
|
+
const isSettable = field.writable && (hasArray || isStorableFieldType(context, field.type));
|
|
207
233
|
|
|
208
234
|
return hasAccessor ? { ...admitted, isSettable } : undefined;
|
|
209
235
|
};
|
|
@@ -222,13 +248,21 @@ const resolveRecordFieldEntry = (
|
|
|
222
248
|
|
|
223
249
|
return {
|
|
224
250
|
jsName: admitted.jsName,
|
|
225
|
-
tsType:
|
|
251
|
+
tsType: fieldTsType(context, admitted.field.type),
|
|
226
252
|
isWritable: admitted.isSettable,
|
|
227
253
|
doc: admitted.field.doc,
|
|
228
254
|
annotations: admitted.field.annotations,
|
|
229
255
|
};
|
|
230
256
|
};
|
|
231
257
|
|
|
258
|
+
const fieldTsType = (context: ModuleContext, ref: TypeId | undefined, isNullable = false): string => {
|
|
259
|
+
if (ref !== undefined && context.library.typeFor(ref)?.kind === "callback") {
|
|
260
|
+
return isNullable ? "bigint | null" : "bigint";
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return renderTsType(context, ref, isNullable);
|
|
264
|
+
};
|
|
265
|
+
|
|
232
266
|
const renderRecordFieldAccessor = (
|
|
233
267
|
context: ModuleContext,
|
|
234
268
|
slot: RecordFieldSlot,
|
|
@@ -243,17 +277,18 @@ const renderRecordFieldAccessor = (
|
|
|
243
277
|
|
|
244
278
|
const { field, jsName } = admitted;
|
|
245
279
|
const doc = getDoc(field);
|
|
246
|
-
const
|
|
280
|
+
const target: StructArrayTarget = { field, jsName, slot: slot.slot, siblingFields };
|
|
281
|
+
const arrayAccessor = renderInlineArrayAccessor(context, target) ?? renderStructArrayAccessor(context, target);
|
|
247
282
|
|
|
248
|
-
if (
|
|
249
|
-
return `${doc}${
|
|
283
|
+
if (arrayAccessor !== undefined) {
|
|
284
|
+
return `${doc}${arrayAccessor}`;
|
|
250
285
|
}
|
|
251
286
|
|
|
252
287
|
const descriptor = context.hoistDescriptor(
|
|
253
288
|
renderDescriptor(context, field.type, "none", { isInline: isInlineField(context, field) }),
|
|
254
289
|
);
|
|
255
290
|
|
|
256
|
-
const tsType =
|
|
291
|
+
const tsType = fieldTsType(context, field.type);
|
|
257
292
|
|
|
258
293
|
const accessorOptions: AccessorOptions = {
|
|
259
294
|
context,
|
|
@@ -295,7 +330,7 @@ const isAccessorEligibleType = (context: ModuleContext, ref: TypeId): boolean =>
|
|
|
295
330
|
return context.library.nameFor(ref) !== undefined;
|
|
296
331
|
}
|
|
297
332
|
case "carray": {
|
|
298
|
-
return type.fixedSize !== undefined;
|
|
333
|
+
return type.fixedSize !== undefined && type.arrayCType?.endsWith("*") === true;
|
|
299
334
|
}
|
|
300
335
|
case "list":
|
|
301
336
|
case "hashtable":
|
|
@@ -338,15 +373,96 @@ const resolveInlineStructFields = (
|
|
|
338
373
|
return type.value.fields;
|
|
339
374
|
};
|
|
340
375
|
|
|
376
|
+
const isInlineScalarCategory = (category: PrimitiveCategory, isBehindPointer: boolean): boolean => {
|
|
377
|
+
if (category === "pointer") {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return !isBehindPointer && category !== "void" && category !== "unichar" && category !== "string";
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const isInlineArrayElement = (context: ModuleContext, ref: TypeId | undefined, cType: string | undefined): boolean => {
|
|
385
|
+
const type = ref === undefined ? undefined : context.library.typeFor(ref);
|
|
386
|
+
|
|
387
|
+
if (type === undefined) {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const isBehindPointer = cType?.endsWith("*") === true;
|
|
392
|
+
|
|
393
|
+
switch (type.kind) {
|
|
394
|
+
case "primitive": {
|
|
395
|
+
return isInlineScalarCategory(type.category, isBehindPointer);
|
|
396
|
+
}
|
|
397
|
+
case "enum": {
|
|
398
|
+
return !isBehindPointer;
|
|
399
|
+
}
|
|
400
|
+
case "record": {
|
|
401
|
+
return (
|
|
402
|
+
resolveInlineStructFields(context, ref, cType) !== undefined &&
|
|
403
|
+
isValueMarshalable(context, type.namespace.name, type.value)
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
case "alias": {
|
|
407
|
+
return isInlineArrayElement(context, type.value.target, cType ?? type.value.targetCType);
|
|
408
|
+
}
|
|
409
|
+
case "callback":
|
|
410
|
+
case "carray":
|
|
411
|
+
case "class":
|
|
412
|
+
case "hashtable":
|
|
413
|
+
case "interface":
|
|
414
|
+
case "list":
|
|
415
|
+
case "varargs": {
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const inlineArrayType = (
|
|
422
|
+
context: ModuleContext,
|
|
423
|
+
target: StructArrayTarget,
|
|
424
|
+
): Extract<GirType, { kind: "carray" }> | undefined => {
|
|
425
|
+
const { field, slot } = target;
|
|
426
|
+
|
|
427
|
+
if (field.type === undefined || slot.bitWidth !== undefined) {
|
|
428
|
+
return undefined;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const type = context.library.typeFor(field.type);
|
|
432
|
+
|
|
433
|
+
if (type?.kind !== "carray" || type.fixedSize === undefined) {
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return type.arrayCType?.endsWith("*") === true ? undefined : type;
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
const resolveInlineArray = (context: ModuleContext, target: StructArrayTarget): InlineArrayResolution | undefined => {
|
|
441
|
+
const type = inlineArrayType(context, target);
|
|
442
|
+
|
|
443
|
+
if (type?.fixedSize === undefined || !isInlineArrayElement(context, type.element, type.elementCType)) {
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const stride = inlineArrayStride(context, type);
|
|
448
|
+
|
|
449
|
+
if (stride === 0) {
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
element: type.element,
|
|
455
|
+
count: type.fixedSize,
|
|
456
|
+
stride,
|
|
457
|
+
isTypedByteArray: context.library.isByteArrayTyped && isByteSequence(context.library, type),
|
|
458
|
+
};
|
|
459
|
+
};
|
|
460
|
+
|
|
341
461
|
const arrayLengthExpression = (
|
|
342
462
|
arrayRef: Extract<GirType, { kind: "carray" }>,
|
|
343
463
|
siblingFields: GirField[],
|
|
344
464
|
): string | undefined => {
|
|
345
|
-
if (arrayRef.fixedSize !== undefined) {
|
|
346
|
-
return String(arrayRef.fixedSize);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (arrayRef.lengthParameterIndex === undefined) {
|
|
465
|
+
if (arrayRef.fixedSize !== undefined || arrayRef.lengthParameterIndex === undefined) {
|
|
350
466
|
return undefined;
|
|
351
467
|
}
|
|
352
468
|
|
|
@@ -606,6 +722,82 @@ const resolveStructArray = (context: ModuleContext, target: StructArrayTarget):
|
|
|
606
722
|
};
|
|
607
723
|
};
|
|
608
724
|
|
|
725
|
+
const inlineArrayElementOffset = (options: InlineArrayAccessorOptions): string =>
|
|
726
|
+
`${String(options.offset)} + __index * ${String(options.resolution.stride)}`;
|
|
727
|
+
|
|
728
|
+
const inlineArrayGetterBlock = (options: InlineArrayAccessorOptions): string => {
|
|
729
|
+
const { context, jsName, tsType, descriptor, resolution } = options;
|
|
730
|
+
const container = resolution.isTypedByteArray ? `new ${tsType}(${String(resolution.count)})` : "[]";
|
|
731
|
+
|
|
732
|
+
const element = wrapReturnValue(context, {
|
|
733
|
+
ref: resolution.element,
|
|
734
|
+
isNullable: false,
|
|
735
|
+
valueExpression: `read(getHandle(this), ${descriptor}, ${inlineArrayElementOffset(options)})`,
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
const body = [
|
|
739
|
+
`const __result: ${tsType} = ${container};`,
|
|
740
|
+
`for (let __index = 0; __index < ${String(resolution.count)}; __index++) {`,
|
|
741
|
+
indent(`__result[__index] = ${element};`, 1),
|
|
742
|
+
"}",
|
|
743
|
+
"return __result;",
|
|
744
|
+
].join("\n");
|
|
745
|
+
|
|
746
|
+
return renderBlock(`get ${jsName}(): ${tsType}`, body);
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
const inlineArraySetterBlock = (options: InlineArrayAccessorOptions): string => {
|
|
750
|
+
const { jsName, tsType, descriptor, resolution } = options;
|
|
751
|
+
|
|
752
|
+
const write =
|
|
753
|
+
`write(getHandle(this), ${descriptor}, ${inlineArrayElementOffset(options)}, ` +
|
|
754
|
+
`toNative(${descriptor}, __element));`;
|
|
755
|
+
|
|
756
|
+
const body = [
|
|
757
|
+
"for (const [__index, __element] of __value.entries()) {",
|
|
758
|
+
indent(`if (__index >= ${String(resolution.count)}) {\n break;\n}\n\n${write}`, 1),
|
|
759
|
+
"}",
|
|
760
|
+
].join("\n");
|
|
761
|
+
|
|
762
|
+
return renderBlock(`set ${jsName}(__value: ${tsType})`, body);
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
const renderInlineArrayAccessor = (context: ModuleContext, target: StructArrayTarget): string | undefined => {
|
|
766
|
+
const resolution = resolveInlineArray(context, target);
|
|
767
|
+
|
|
768
|
+
if (resolution === undefined) {
|
|
769
|
+
return undefined;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const { field, jsName, slot } = target;
|
|
773
|
+
context.addRuntimeImport("read");
|
|
774
|
+
context.addRuntimeImport("getHandle");
|
|
775
|
+
context.addRuntimeImport("t");
|
|
776
|
+
|
|
777
|
+
const options: InlineArrayAccessorOptions = {
|
|
778
|
+
context,
|
|
779
|
+
jsName,
|
|
780
|
+
tsType: renderTsType(context, field.type, false),
|
|
781
|
+
descriptor: context.hoistDescriptor(renderDescriptor(context, resolution.element, "none", { isInline: true })),
|
|
782
|
+
offset: slot.byteOffset,
|
|
783
|
+
resolution,
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
const blocks: string[] = [];
|
|
787
|
+
|
|
788
|
+
if (field.readable) {
|
|
789
|
+
blocks.push(inlineArrayGetterBlock(options));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
if (field.writable) {
|
|
793
|
+
context.addRuntimeImport("write");
|
|
794
|
+
context.addRuntimeImport("toNative");
|
|
795
|
+
blocks.push(inlineArraySetterBlock(options));
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return blocks.length === 0 ? undefined : blocks.join("\n\n");
|
|
799
|
+
};
|
|
800
|
+
|
|
609
801
|
const renderStructArrayAccessor = (context: ModuleContext, target: StructArrayTarget): string | undefined => {
|
|
610
802
|
const resolution = resolveStructArray(context, target);
|
|
611
803
|
|
|
@@ -688,6 +880,7 @@ const setterBlock = (options: AccessorOptions): string =>
|
|
|
688
880
|
);
|
|
689
881
|
|
|
690
882
|
export {
|
|
883
|
+
fieldTsType,
|
|
691
884
|
isEmittableField,
|
|
692
885
|
isInlineField,
|
|
693
886
|
isStorableFieldType,
|
|
@@ -56,6 +56,9 @@ const recordInlineSize = (context: ModuleContext, record: ResolvedRecordValue):
|
|
|
56
56
|
return size > 0 ? size : undefined;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
const inlineArrayStride = (context: ModuleContext, array: Extract<GirType, { kind: "carray" }>): number =>
|
|
60
|
+
layoutOfType(context, array.element, array.elementCType, new Set()).size;
|
|
61
|
+
|
|
59
62
|
const bitMask = (width: number): number => {
|
|
60
63
|
if (width >= 32) {
|
|
61
64
|
return 0xFF_FF_FF_FF;
|
|
@@ -224,4 +227,11 @@ const resolveAliasLayout = (
|
|
|
224
227
|
return layoutOfType(context, ref, resolved.value.targetCType, visited);
|
|
225
228
|
};
|
|
226
229
|
|
|
227
|
-
export {
|
|
230
|
+
export {
|
|
231
|
+
computeRecordFieldSlots,
|
|
232
|
+
inlineArrayStride,
|
|
233
|
+
recordInlineSize,
|
|
234
|
+
bitMask,
|
|
235
|
+
mergeBitfield,
|
|
236
|
+
type RecordFieldSlot,
|
|
237
|
+
};
|
package/src/store/gi/record.ts
CHANGED
|
@@ -12,14 +12,6 @@ import { computeRecordFieldSlots } from "./record-layout.js";
|
|
|
12
12
|
import { appendWrapperClassRegistration } from "./registration.js";
|
|
13
13
|
import { isConstructibleRecord } from "./value-marshalable.js";
|
|
14
14
|
|
|
15
|
-
type RecordMembersOptions = {
|
|
16
|
-
context: ModuleContext;
|
|
17
|
-
record: GirRecord;
|
|
18
|
-
className: string;
|
|
19
|
-
callables: Callables;
|
|
20
|
-
gtypeExpr: string | undefined;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
15
|
const isGErrorRecord = (context: ModuleContext, record: GirRecord): boolean =>
|
|
24
16
|
context.namespace.name === "GLib" && record.glibGetType === "g_error_get_type";
|
|
25
17
|
|
|
@@ -38,8 +30,7 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
38
30
|
};
|
|
39
31
|
|
|
40
32
|
generateBindings(context, callables);
|
|
41
|
-
const
|
|
42
|
-
const members = renderRecordMembers({ context, record, className, callables, gtypeExpr });
|
|
33
|
+
const members = renderRecordMembers(context, record, className, callables);
|
|
43
34
|
const body = indentMembers(members);
|
|
44
35
|
const heritage = isErrorSubclass ? " extends globalThis.Error" : "";
|
|
45
36
|
const doc = getDoc(record);
|
|
@@ -59,16 +50,29 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
59
50
|
});
|
|
60
51
|
}
|
|
61
52
|
|
|
53
|
+
const gtypeExpr = renderSourceGtype(context, record);
|
|
54
|
+
|
|
62
55
|
appendWrapperClassRegistration(context, {
|
|
63
56
|
className,
|
|
64
57
|
gtypeExpr,
|
|
65
58
|
});
|
|
66
59
|
};
|
|
67
60
|
|
|
68
|
-
const renderRecordMembers = (
|
|
69
|
-
|
|
61
|
+
const renderRecordMembers = (
|
|
62
|
+
context: ModuleContext,
|
|
63
|
+
record: GirRecord,
|
|
64
|
+
className: string,
|
|
65
|
+
callables: Callables,
|
|
66
|
+
): string[] => {
|
|
70
67
|
const isErrorSubclass = isGErrorRecord(context, record);
|
|
71
|
-
|
|
68
|
+
|
|
69
|
+
const { members, claimedNames } = renderPlainTypeMembers({
|
|
70
|
+
context,
|
|
71
|
+
className,
|
|
72
|
+
callables,
|
|
73
|
+
hasGtype: record.glibGetType !== undefined,
|
|
74
|
+
});
|
|
75
|
+
|
|
72
76
|
members.unshift(renderRecordConstructor(context, { record, className, callables, isErrorSubclass }));
|
|
73
77
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
74
78
|
|
|
@@ -21,7 +21,7 @@ const RUNTIME_OVERRIDES: Map<string, RuntimeOverride> = new Map([
|
|
|
21
21
|
[
|
|
22
22
|
"g_value_set_boxed",
|
|
23
23
|
{
|
|
24
|
-
signature: "boxed: object | null",
|
|
24
|
+
signature: "boxed: object | string | number | bigint | boolean | null",
|
|
25
25
|
returnType: "void",
|
|
26
26
|
body: 'throw new Error("g_value_set_boxed: runtime override not installed");',
|
|
27
27
|
renames: [["v_boxed", "boxed"]],
|
package/src/store/gi/signal.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
resolvePrerequisiteReference,
|
|
18
18
|
} from "../../analysis/inheritance.js";
|
|
19
19
|
import { renderHandlerParameters, renderHandlerResultType } from "../../analysis/param-structure.js";
|
|
20
|
-
import { renderTsType } from "../../analysis/ts-type.js";
|
|
20
|
+
import { renderParameterTsType, renderTsType } from "../../analysis/ts-type.js";
|
|
21
21
|
import { resolveInterfaces } from "../../gir/ancestry.js";
|
|
22
22
|
import { isCallerAllocatedOut, isOutParameter } from "../../gir/parameter.js";
|
|
23
23
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
@@ -259,7 +259,7 @@ const renderResultType = (
|
|
|
259
259
|
const renderSignalEmitEntry = (context: ModuleContext, signal: GirCallable): string => {
|
|
260
260
|
const args = renderHandlerParameters(
|
|
261
261
|
signal.parameters,
|
|
262
|
-
(ref, nullable) =>
|
|
262
|
+
(ref, nullable) => renderParameterTsType(context, ref, nullable),
|
|
263
263
|
isCallerAllocatedOut,
|
|
264
264
|
);
|
|
265
265
|
|
package/src/store/gi/vtable.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { JsDocSpec } from "../../writer/doc.js";
|
|
|
11
11
|
import {
|
|
12
12
|
isInlineCallbackRef,
|
|
13
13
|
isScalarRef,
|
|
14
|
+
renderCallbackType,
|
|
14
15
|
renderDescriptor,
|
|
15
16
|
renderParamDescriptor,
|
|
16
17
|
} from "../../analysis/descriptor-render.js";
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
handlerParameters,
|
|
20
21
|
parameterIdentifier,
|
|
21
22
|
renamesWithInstance,
|
|
22
|
-
renderHandlerParameters,
|
|
23
23
|
renderHandlerResultType,
|
|
24
24
|
} from "../../analysis/param-structure.js";
|
|
25
25
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
@@ -74,6 +74,12 @@ type Vtable = {
|
|
|
74
74
|
slots: VtableSlot[];
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
type SlotParamPlan = {
|
|
78
|
+
parameters: GirParameter[];
|
|
79
|
+
argIndexMap: Map<number, number>;
|
|
80
|
+
decoded: Set<GirParameter>;
|
|
81
|
+
};
|
|
82
|
+
|
|
77
83
|
const PADDING_FIELD_NAME = /^(?:reserved|padding)\d*$/i;
|
|
78
84
|
|
|
79
85
|
const UNCALLABLE_SLOT_KEYS: Set<string> = new Set([
|
|
@@ -86,6 +92,7 @@ const UNCALLABLE_SLOT_KEYS: Set<string> = new Set([
|
|
|
86
92
|
const VTABLE_CACHE: WeakMap<GirClass, Vtable> = new WeakMap();
|
|
87
93
|
const PROTECTED_SLOT_NOTE = "It is `protected`, so only a subclass chaining up reaches it.";
|
|
88
94
|
const PUBLIC_SLOT_NOTE = "Calling it from anywhere else re-enters the slot on a live instance.";
|
|
95
|
+
const OPAQUE_CALLBACK_NOTE = "Received as the raw address of the C function pointer.";
|
|
89
96
|
|
|
90
97
|
const vfuncMemberName = (fieldName: string): string => `vfunc${pascalCase(fieldName)}`;
|
|
91
98
|
|
|
@@ -125,6 +132,79 @@ const vtableCallbackType = (context: ModuleContext, field: GirField): GirCallbac
|
|
|
125
132
|
return type.value;
|
|
126
133
|
};
|
|
127
134
|
|
|
135
|
+
const isCallbackParam = (context: ModuleContext, parameter: GirParameter): boolean =>
|
|
136
|
+
parameter.type !== undefined && context.library.typeFor(parameter.type)?.kind === "callback";
|
|
137
|
+
|
|
138
|
+
const isDecodedCallbackParam = (context: ModuleContext, parameter: GirParameter, index: number): boolean =>
|
|
139
|
+
isCallbackParam(context, parameter) &&
|
|
140
|
+
parameter.closureIndex === index + 1 &&
|
|
141
|
+
parameter.destroyIndex === undefined;
|
|
142
|
+
|
|
143
|
+
const decodedSlotParams = (context: ModuleContext, callback: GirCallback): Set<GirParameter> => {
|
|
144
|
+
const decoded: Set<GirParameter> = new Set();
|
|
145
|
+
|
|
146
|
+
for (const [index, parameter] of callback.parameters.entries()) {
|
|
147
|
+
if (isDecodedCallbackParam(context, parameter, index)) {
|
|
148
|
+
decoded.add(parameter);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return decoded;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const companionIndices = (decoded: Set<GirParameter>): Set<number> => {
|
|
156
|
+
const companions: Set<number> = new Set();
|
|
157
|
+
|
|
158
|
+
for (const parameter of decoded) {
|
|
159
|
+
if (parameter.closureIndex !== undefined) {
|
|
160
|
+
companions.add(parameter.closureIndex);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return companions;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const slotParamPlan = (context: ModuleContext, callback: GirCallback): SlotParamPlan => {
|
|
168
|
+
const decoded = decodedSlotParams(context, callback);
|
|
169
|
+
const companions = companionIndices(decoded);
|
|
170
|
+
const parameters: GirParameter[] = [];
|
|
171
|
+
const argIndexMap: Map<number, number> = new Map();
|
|
172
|
+
|
|
173
|
+
for (const [index, parameter] of callback.parameters.entries()) {
|
|
174
|
+
if (companions.has(index)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
argIndexMap.set(index, parameters.length);
|
|
179
|
+
parameters.push(parameter);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { parameters, argIndexMap, decoded };
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const isOpaqueCallbackParam = (context: ModuleContext, plan: SlotParamPlan, parameter: GirParameter): boolean =>
|
|
186
|
+
isCallbackParam(context, parameter) && !plan.decoded.has(parameter);
|
|
187
|
+
|
|
188
|
+
const renderSlotParamDescriptor = (context: ModuleContext, parameter: GirParameter, plan: SlotParamPlan): string => {
|
|
189
|
+
if (plan.decoded.has(parameter)) {
|
|
190
|
+
const callbackDescriptor = renderCallbackType(context, parameter.type, parameter);
|
|
191
|
+
|
|
192
|
+
if (callbackDescriptor !== undefined) {
|
|
193
|
+
return callbackDescriptor;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return renderParamDescriptor(context, parameter, parameter.type, { argIndexMap: plan.argIndexMap });
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const renderSlotParamTsType = (context: ModuleContext, plan: SlotParamPlan, parameter: GirParameter): string => {
|
|
201
|
+
if (isOpaqueCallbackParam(context, plan, parameter)) {
|
|
202
|
+
return parameter.nullable ? "bigint | null" : "bigint";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return renderTsType(context, parameter.type, parameter.nullable);
|
|
206
|
+
};
|
|
207
|
+
|
|
128
208
|
const vtableSlotEntry = (
|
|
129
209
|
context: ModuleContext,
|
|
130
210
|
field: GirField,
|
|
@@ -387,15 +467,35 @@ const hasCallableVfuncSlots = (context: ModuleContext, namespaceName: string, kl
|
|
|
387
467
|
|
|
388
468
|
const slotDoc = (slot: VtableSlot): string | undefined => slot.vfunc?.doc ?? slot.field.doc ?? slot.callback.doc;
|
|
389
469
|
|
|
390
|
-
const
|
|
470
|
+
const slotParamDoc = (
|
|
471
|
+
context: ModuleContext,
|
|
472
|
+
plan: SlotParamPlan,
|
|
473
|
+
parameter: GirParameter,
|
|
474
|
+
doc: string | undefined,
|
|
475
|
+
): string | undefined => {
|
|
476
|
+
if (!isOpaqueCallbackParam(context, plan, parameter)) {
|
|
477
|
+
return doc;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return doc === undefined ? OPAQUE_CALLBACK_NOTE : `${doc} ${OPAQUE_CALLBACK_NOTE}`;
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const slotDocParameters = (context: ModuleContext, slot: VtableSlot): GirParameter[] => {
|
|
484
|
+
const plan = slotParamPlan(context, slot.callback);
|
|
391
485
|
const [, ...parameters] = slot.callback.parameters;
|
|
392
486
|
const vfuncParameters = slot.vfunc?.parameters ?? [];
|
|
393
487
|
|
|
394
|
-
return parameters
|
|
488
|
+
return parameters
|
|
489
|
+
.map((parameter, index) => ({ parameter, index }))
|
|
490
|
+
.filter(({ index }) => plan.argIndexMap.has(index + 1))
|
|
491
|
+
.map(({ parameter, index }) => ({
|
|
492
|
+
...parameter,
|
|
493
|
+
doc: slotParamDoc(context, plan, parameter, vfuncParameters[index]?.doc ?? parameter.doc),
|
|
494
|
+
}));
|
|
395
495
|
};
|
|
396
496
|
|
|
397
|
-
const slotDocSpec = (slot: VtableSlot): JsDocSpec => {
|
|
398
|
-
const parameters = slotDocParameters(slot);
|
|
497
|
+
const slotDocSpec = (context: ModuleContext, slot: VtableSlot): JsDocSpec => {
|
|
498
|
+
const parameters = slotDocParameters(context, slot);
|
|
399
499
|
const source = slot.vfunc ?? slot.callback;
|
|
400
500
|
|
|
401
501
|
return {
|
|
@@ -446,12 +546,18 @@ const isCallableSlot = (context: ModuleContext, slot: VtableSlot): boolean =>
|
|
|
446
546
|
!UNCALLABLE_SLOT_KEYS.has(slot.key) && !hasUnannotatedPointerParam(context, slot);
|
|
447
547
|
|
|
448
548
|
const vfuncSlotSignature = (context: ModuleContext, slot: VtableSlot, isOptional = false): VfuncSignature => {
|
|
449
|
-
const
|
|
549
|
+
const plan = slotParamPlan(context, slot.callback);
|
|
550
|
+
const [, ...parameters] = plan.parameters;
|
|
450
551
|
|
|
451
552
|
const renderType = (ref: TypeId | undefined, isNullable: boolean): string =>
|
|
452
553
|
renderTsType(context, ref, isNullable);
|
|
453
554
|
|
|
454
|
-
const signature =
|
|
555
|
+
const signature = handlerParameters(parameters)
|
|
556
|
+
.map(
|
|
557
|
+
(parameter, index) =>
|
|
558
|
+
`${parameterIdentifier(parameter, index)}: ${renderSlotParamTsType(context, plan, parameter)}`)
|
|
559
|
+
.join(", ");
|
|
560
|
+
|
|
455
561
|
const folded = foldedLengthParameters(context.library, slot.callback);
|
|
456
562
|
|
|
457
563
|
const returnType = renderHandlerResultType({
|
|
@@ -470,13 +576,13 @@ const renderVfuncMember = (options: VfuncMemberOptions): string => {
|
|
|
470
576
|
const { context, ownerRef, slot, mode, isProtected } = options;
|
|
471
577
|
const { header, returnType } = vfuncSlotSignature(context, slot, mode === "requirement");
|
|
472
578
|
const declaration = `${isProtected ? "protected " : ""}${header}`;
|
|
473
|
-
const doc = renderJsDoc(slotDoc(slot), vfuncMemberNote(options), slotDocSpec(slot));
|
|
579
|
+
const doc = renderJsDoc(slotDoc(slot), vfuncMemberNote(options), slotDocSpec(context, slot));
|
|
474
580
|
|
|
475
581
|
if (mode !== "implementation") {
|
|
476
582
|
return `${doc}${declaration};`;
|
|
477
583
|
}
|
|
478
584
|
|
|
479
|
-
const [, ...parameters] = slot.callback.parameters;
|
|
585
|
+
const [, ...parameters] = slotParamPlan(context, slot.callback).parameters;
|
|
480
586
|
|
|
481
587
|
const inputs = handlerParameters(parameters).map((parameter, index) =>
|
|
482
588
|
parameterIdentifier(parameter, index));
|
|
@@ -511,9 +617,10 @@ const isVtableSlotEligible = (context: ModuleContext, callback: GirCallback): bo
|
|
|
511
617
|
|
|
512
618
|
const renderVtableSlotDescriptor = (context: ModuleContext, vtable: Vtable, slot: VtableSlot): string => {
|
|
513
619
|
const { key, field, callback, byteOffset } = slot;
|
|
620
|
+
const plan = slotParamPlan(context, callback);
|
|
514
621
|
|
|
515
|
-
const argDescriptors =
|
|
516
|
-
.map((param) =>
|
|
622
|
+
const argDescriptors = plan.parameters
|
|
623
|
+
.map((param) => renderSlotParamDescriptor(context, param, plan))
|
|
517
624
|
.join(", ");
|
|
518
625
|
|
|
519
626
|
const returnDescriptor = renderDescriptor(
|