@gtkx/codegen 1.2.0 → 1.2.2
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/dist/docs/symbol-page.js +1 -1
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/gir/class.d.ts +7 -2
- package/dist/gir/class.d.ts.map +1 -1
- package/dist/gir/class.js +4 -1
- package/dist/gir/class.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/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +4 -2
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +3 -2
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +156 -18
- 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/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +14 -14
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +1 -0
- package/dist/store/resolve-store.js.map +1 -1
- package/package.json +3 -3
- package/src/docs/symbol-page.ts +1 -1
- package/src/gir/class.ts +12 -3
- package/src/store/gi/interface.ts +2 -2
- package/src/store/gi/record-constructor.ts +4 -2
- package/src/store/gi/record-field-accessor.ts +241 -20
- package/src/store/gi/record-layout.ts +11 -1
- package/src/store/gi/signal.ts +20 -23
- package/src/store/resolve-store.ts +1 -0
|
@@ -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,9 +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";
|
|
13
|
+
import { isByteSequence, isUnboundedArray } from "../../analysis/type-shape.js";
|
|
12
14
|
import { indent, renderBlock } from "../../writer/emit.js";
|
|
13
15
|
import { getDoc } from "./doc-spec.js";
|
|
14
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
bitMask,
|
|
18
|
+
computeRecordFieldSlots,
|
|
19
|
+
inlineArrayStride,
|
|
20
|
+
mergeBitfield,
|
|
21
|
+
type RecordFieldSlot,
|
|
22
|
+
} from "./record-layout.js";
|
|
15
23
|
import { wrapReturnValue } from "./return-wrap.js";
|
|
16
24
|
import { isValueMarshalable } from "./value-marshalable.js";
|
|
17
25
|
|
|
@@ -27,6 +35,10 @@ type AdmittedField = {
|
|
|
27
35
|
jsName: string;
|
|
28
36
|
};
|
|
29
37
|
|
|
38
|
+
type AccessibleField = AdmittedField & {
|
|
39
|
+
isSettable: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
30
42
|
type RecordFieldEntry = {
|
|
31
43
|
jsName: string;
|
|
32
44
|
tsType: string;
|
|
@@ -94,6 +106,22 @@ type AccessorOptions = {
|
|
|
94
106
|
fieldType: TypeId;
|
|
95
107
|
};
|
|
96
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
|
+
|
|
97
125
|
const isMarshalableField = (context: ModuleContext, field: GirField): boolean => {
|
|
98
126
|
if (field.cType?.endsWith("*") === true) {
|
|
99
127
|
return true;
|
|
@@ -167,12 +195,52 @@ const admitField = (
|
|
|
167
195
|
return { field, jsName };
|
|
168
196
|
};
|
|
169
197
|
|
|
198
|
+
const isNullTerminatedArrayField = (context: ModuleContext, ref: TypeId): boolean => {
|
|
199
|
+
const type = context.library.typeFor(ref);
|
|
200
|
+
|
|
201
|
+
return type?.kind === "carray" && isUnboundedArray(type) && type.elementCType?.endsWith("*") === true;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const isAccessibleFieldType = (context: ModuleContext, ref: TypeId): boolean =>
|
|
205
|
+
isAccessorEligibleType(context, ref) || isNullTerminatedArrayField(context, ref);
|
|
206
|
+
|
|
207
|
+
const isStorableFieldType = (context: ModuleContext, ref: TypeId): boolean => {
|
|
208
|
+
const kind = context.library.typeFor(ref)?.kind;
|
|
209
|
+
|
|
210
|
+
return kind !== "carray" && kind !== "list" && kind !== "hashtable";
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const hasArrayAccessor = (context: ModuleContext, target: StructArrayTarget): boolean =>
|
|
214
|
+
resolveInlineArray(context, target) !== undefined || resolveStructArray(context, target) !== undefined;
|
|
215
|
+
|
|
216
|
+
const admitAccessibleField = (
|
|
217
|
+
context: ModuleContext,
|
|
218
|
+
slot: RecordFieldSlot,
|
|
219
|
+
claimedNames: Set<string>,
|
|
220
|
+
siblingFields: GirField[],
|
|
221
|
+
): AccessibleField | undefined => {
|
|
222
|
+
const admitted = admitField(context, slot, claimedNames);
|
|
223
|
+
|
|
224
|
+
if (admitted === undefined) {
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const { field, jsName } = admitted;
|
|
229
|
+
const target: StructArrayTarget = { field, jsName, slot: slot.slot, siblingFields };
|
|
230
|
+
const hasArray = hasArrayAccessor(context, target);
|
|
231
|
+
const hasAccessor = hasArray || isAccessibleFieldType(context, field.type);
|
|
232
|
+
const isSettable = field.writable && (hasArray || isStorableFieldType(context, field.type));
|
|
233
|
+
|
|
234
|
+
return hasAccessor ? { ...admitted, isSettable } : undefined;
|
|
235
|
+
};
|
|
236
|
+
|
|
170
237
|
const resolveRecordFieldEntry = (
|
|
171
238
|
context: ModuleContext,
|
|
172
239
|
slot: RecordFieldSlot,
|
|
173
240
|
claimedNames: Set<string>,
|
|
241
|
+
siblingFields: GirField[],
|
|
174
242
|
): RecordFieldEntry | undefined => {
|
|
175
|
-
const admitted =
|
|
243
|
+
const admitted = admitAccessibleField(context, slot, claimedNames, siblingFields);
|
|
176
244
|
|
|
177
245
|
if (admitted === undefined) {
|
|
178
246
|
return undefined;
|
|
@@ -181,7 +249,7 @@ const resolveRecordFieldEntry = (
|
|
|
181
249
|
return {
|
|
182
250
|
jsName: admitted.jsName,
|
|
183
251
|
tsType: renderTsType(context, admitted.field.type, false),
|
|
184
|
-
isWritable: admitted.
|
|
252
|
+
isWritable: admitted.isSettable,
|
|
185
253
|
doc: admitted.field.doc,
|
|
186
254
|
annotations: admitted.field.annotations,
|
|
187
255
|
};
|
|
@@ -193,7 +261,7 @@ const renderRecordFieldAccessor = (
|
|
|
193
261
|
claimedNames: Set<string>,
|
|
194
262
|
siblingFields: GirField[],
|
|
195
263
|
): string | undefined => {
|
|
196
|
-
const admitted =
|
|
264
|
+
const admitted = admitAccessibleField(context, slot, claimedNames, siblingFields);
|
|
197
265
|
|
|
198
266
|
if (admitted === undefined) {
|
|
199
267
|
return undefined;
|
|
@@ -201,16 +269,11 @@ const renderRecordFieldAccessor = (
|
|
|
201
269
|
|
|
202
270
|
const { field, jsName } = admitted;
|
|
203
271
|
const doc = getDoc(field);
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
if (structArray !== undefined) {
|
|
207
|
-
return `${doc}${structArray}`;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (!isAccessorEligibleType(context, field.type)) {
|
|
211
|
-
const tsType = renderTsType(context, field.type, false);
|
|
272
|
+
const target: StructArrayTarget = { field, jsName, slot: slot.slot, siblingFields };
|
|
273
|
+
const arrayAccessor = renderInlineArrayAccessor(context, target) ?? renderStructArrayAccessor(context, target);
|
|
212
274
|
|
|
213
|
-
|
|
275
|
+
if (arrayAccessor !== undefined) {
|
|
276
|
+
return `${doc}${arrayAccessor}`;
|
|
214
277
|
}
|
|
215
278
|
|
|
216
279
|
const descriptor = context.hoistDescriptor(
|
|
@@ -230,7 +293,7 @@ const renderRecordFieldAccessor = (
|
|
|
230
293
|
|
|
231
294
|
const blocks: string[] = [getterBlock(accessorOptions)];
|
|
232
295
|
|
|
233
|
-
if (
|
|
296
|
+
if (admitted.isSettable) {
|
|
234
297
|
blocks.push(setterBlock(accessorOptions));
|
|
235
298
|
}
|
|
236
299
|
|
|
@@ -259,7 +322,7 @@ const isAccessorEligibleType = (context: ModuleContext, ref: TypeId): boolean =>
|
|
|
259
322
|
return context.library.nameFor(ref) !== undefined;
|
|
260
323
|
}
|
|
261
324
|
case "carray": {
|
|
262
|
-
return type.fixedSize !== undefined;
|
|
325
|
+
return type.fixedSize !== undefined && type.arrayCType?.endsWith("*") === true;
|
|
263
326
|
}
|
|
264
327
|
case "list":
|
|
265
328
|
case "hashtable":
|
|
@@ -302,15 +365,96 @@ const resolveInlineStructFields = (
|
|
|
302
365
|
return type.value.fields;
|
|
303
366
|
};
|
|
304
367
|
|
|
368
|
+
const isInlineScalarCategory = (category: PrimitiveCategory, isBehindPointer: boolean): boolean => {
|
|
369
|
+
if (category === "pointer") {
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return !isBehindPointer && category !== "void" && category !== "unichar" && category !== "string";
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const isInlineArrayElement = (context: ModuleContext, ref: TypeId | undefined, cType: string | undefined): boolean => {
|
|
377
|
+
const type = ref === undefined ? undefined : context.library.typeFor(ref);
|
|
378
|
+
|
|
379
|
+
if (type === undefined) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const isBehindPointer = cType?.endsWith("*") === true;
|
|
384
|
+
|
|
385
|
+
switch (type.kind) {
|
|
386
|
+
case "primitive": {
|
|
387
|
+
return isInlineScalarCategory(type.category, isBehindPointer);
|
|
388
|
+
}
|
|
389
|
+
case "enum": {
|
|
390
|
+
return !isBehindPointer;
|
|
391
|
+
}
|
|
392
|
+
case "record": {
|
|
393
|
+
return (
|
|
394
|
+
resolveInlineStructFields(context, ref, cType) !== undefined &&
|
|
395
|
+
isValueMarshalable(context, type.namespace.name, type.value)
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
case "alias": {
|
|
399
|
+
return isInlineArrayElement(context, type.value.target, cType ?? type.value.targetCType);
|
|
400
|
+
}
|
|
401
|
+
case "callback":
|
|
402
|
+
case "carray":
|
|
403
|
+
case "class":
|
|
404
|
+
case "hashtable":
|
|
405
|
+
case "interface":
|
|
406
|
+
case "list":
|
|
407
|
+
case "varargs": {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
const inlineArrayType = (
|
|
414
|
+
context: ModuleContext,
|
|
415
|
+
target: StructArrayTarget,
|
|
416
|
+
): Extract<GirType, { kind: "carray" }> | undefined => {
|
|
417
|
+
const { field, slot } = target;
|
|
418
|
+
|
|
419
|
+
if (field.type === undefined || slot.bitWidth !== undefined) {
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const type = context.library.typeFor(field.type);
|
|
424
|
+
|
|
425
|
+
if (type?.kind !== "carray" || type.fixedSize === undefined) {
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return type.arrayCType?.endsWith("*") === true ? undefined : type;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const resolveInlineArray = (context: ModuleContext, target: StructArrayTarget): InlineArrayResolution | undefined => {
|
|
433
|
+
const type = inlineArrayType(context, target);
|
|
434
|
+
|
|
435
|
+
if (type?.fixedSize === undefined || !isInlineArrayElement(context, type.element, type.elementCType)) {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const stride = inlineArrayStride(context, type);
|
|
440
|
+
|
|
441
|
+
if (stride === 0) {
|
|
442
|
+
return undefined;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return {
|
|
446
|
+
element: type.element,
|
|
447
|
+
count: type.fixedSize,
|
|
448
|
+
stride,
|
|
449
|
+
isTypedByteArray: context.library.isByteArrayTyped && isByteSequence(context.library, type),
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
|
|
305
453
|
const arrayLengthExpression = (
|
|
306
454
|
arrayRef: Extract<GirType, { kind: "carray" }>,
|
|
307
455
|
siblingFields: GirField[],
|
|
308
456
|
): string | undefined => {
|
|
309
|
-
if (arrayRef.fixedSize !== undefined) {
|
|
310
|
-
return String(arrayRef.fixedSize);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (arrayRef.lengthParameterIndex === undefined) {
|
|
457
|
+
if (arrayRef.fixedSize !== undefined || arrayRef.lengthParameterIndex === undefined) {
|
|
314
458
|
return undefined;
|
|
315
459
|
}
|
|
316
460
|
|
|
@@ -570,6 +714,82 @@ const resolveStructArray = (context: ModuleContext, target: StructArrayTarget):
|
|
|
570
714
|
};
|
|
571
715
|
};
|
|
572
716
|
|
|
717
|
+
const inlineArrayElementOffset = (options: InlineArrayAccessorOptions): string =>
|
|
718
|
+
`${String(options.offset)} + __index * ${String(options.resolution.stride)}`;
|
|
719
|
+
|
|
720
|
+
const inlineArrayGetterBlock = (options: InlineArrayAccessorOptions): string => {
|
|
721
|
+
const { context, jsName, tsType, descriptor, resolution } = options;
|
|
722
|
+
const container = resolution.isTypedByteArray ? `new ${tsType}(${String(resolution.count)})` : "[]";
|
|
723
|
+
|
|
724
|
+
const element = wrapReturnValue(context, {
|
|
725
|
+
ref: resolution.element,
|
|
726
|
+
isNullable: false,
|
|
727
|
+
valueExpression: `read(getHandle(this), ${descriptor}, ${inlineArrayElementOffset(options)})`,
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
const body = [
|
|
731
|
+
`const __result: ${tsType} = ${container};`,
|
|
732
|
+
`for (let __index = 0; __index < ${String(resolution.count)}; __index++) {`,
|
|
733
|
+
indent(`__result[__index] = ${element};`, 1),
|
|
734
|
+
"}",
|
|
735
|
+
"return __result;",
|
|
736
|
+
].join("\n");
|
|
737
|
+
|
|
738
|
+
return renderBlock(`get ${jsName}(): ${tsType}`, body);
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
const inlineArraySetterBlock = (options: InlineArrayAccessorOptions): string => {
|
|
742
|
+
const { jsName, tsType, descriptor, resolution } = options;
|
|
743
|
+
|
|
744
|
+
const write =
|
|
745
|
+
`write(getHandle(this), ${descriptor}, ${inlineArrayElementOffset(options)}, ` +
|
|
746
|
+
`toNative(${descriptor}, __element));`;
|
|
747
|
+
|
|
748
|
+
const body = [
|
|
749
|
+
"for (const [__index, __element] of __value.entries()) {",
|
|
750
|
+
indent(`if (__index >= ${String(resolution.count)}) {\n break;\n}\n\n${write}`, 1),
|
|
751
|
+
"}",
|
|
752
|
+
].join("\n");
|
|
753
|
+
|
|
754
|
+
return renderBlock(`set ${jsName}(__value: ${tsType})`, body);
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
const renderInlineArrayAccessor = (context: ModuleContext, target: StructArrayTarget): string | undefined => {
|
|
758
|
+
const resolution = resolveInlineArray(context, target);
|
|
759
|
+
|
|
760
|
+
if (resolution === undefined) {
|
|
761
|
+
return undefined;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
const { field, jsName, slot } = target;
|
|
765
|
+
context.addRuntimeImport("read");
|
|
766
|
+
context.addRuntimeImport("getHandle");
|
|
767
|
+
context.addRuntimeImport("t");
|
|
768
|
+
|
|
769
|
+
const options: InlineArrayAccessorOptions = {
|
|
770
|
+
context,
|
|
771
|
+
jsName,
|
|
772
|
+
tsType: renderTsType(context, field.type, false),
|
|
773
|
+
descriptor: context.hoistDescriptor(renderDescriptor(context, resolution.element, "none", { isInline: true })),
|
|
774
|
+
offset: slot.byteOffset,
|
|
775
|
+
resolution,
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
const blocks: string[] = [];
|
|
779
|
+
|
|
780
|
+
if (field.readable) {
|
|
781
|
+
blocks.push(inlineArrayGetterBlock(options));
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (field.writable) {
|
|
785
|
+
context.addRuntimeImport("write");
|
|
786
|
+
context.addRuntimeImport("toNative");
|
|
787
|
+
blocks.push(inlineArraySetterBlock(options));
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
return blocks.length === 0 ? undefined : blocks.join("\n\n");
|
|
791
|
+
};
|
|
792
|
+
|
|
573
793
|
const renderStructArrayAccessor = (context: ModuleContext, target: StructArrayTarget): string | undefined => {
|
|
574
794
|
const resolution = resolveStructArray(context, target);
|
|
575
795
|
|
|
@@ -654,6 +874,7 @@ const setterBlock = (options: AccessorOptions): string =>
|
|
|
654
874
|
export {
|
|
655
875
|
isEmittableField,
|
|
656
876
|
isInlineField,
|
|
877
|
+
isStorableFieldType,
|
|
657
878
|
emitFieldWrite,
|
|
658
879
|
resolveRecordFieldEntry,
|
|
659
880
|
renderRecordFieldAccessor,
|
|
@@ -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/signal.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { camelCase, sourceStringLiteral } from "@gtkx/utils";
|
|
2
|
-
import type { GirClass } from "../../gir/class.js";
|
|
2
|
+
import type { GirClass, GirSignal } from "../../gir/class.js";
|
|
3
3
|
import type { GirCallable, GirParameter, GirReturnValue } from "../../gir/parameter.js";
|
|
4
4
|
import type { GirProperty } from "../../gir/property.js";
|
|
5
5
|
import type { ModuleContext } from "../../writer/context.js";
|
|
@@ -139,16 +139,20 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
139
139
|
const { context, klass, className, isParentlessObjectSubclass, suffix, renderEntry } = spec;
|
|
140
140
|
const extendsRefs = signalMapParentRefs(context, klass, isParentlessObjectSubclass, suffix);
|
|
141
141
|
const extendsClause = extendsRefs.length === 0 ? "" : ` extends ${extendsRefs.join(", ")}`;
|
|
142
|
+
const signals = collectClassSignals(context, klass);
|
|
142
143
|
|
|
143
|
-
const signalEntries =
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
const signalEntries = signals.flatMap((signal) => {
|
|
145
|
+
const value = renderEntry(context, signal);
|
|
146
|
+
const entry = `${signalDoc(signal)}${sourceStringLiteral(signal.name)}: ${value};`;
|
|
146
147
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
if (!signal.isDetailed) {
|
|
149
|
+
return [entry];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return [entry, `[detail: \`${signal.name}::\${string}\`]: ${value};`];
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const entries = [...signalEntries, ...renderNotifyDetailEntries(context, klass, suffix)];
|
|
152
156
|
|
|
153
157
|
return renderBracedOrEmpty(`export interface ${className}${suffix}${extendsClause}`, entries.join("\n"));
|
|
154
158
|
};
|
|
@@ -156,14 +160,6 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
156
160
|
const signalDoc = (signal: GirCallable): string =>
|
|
157
161
|
renderJsDoc(signal.doc, undefined, handlerSpec(signal, signal.parameters));
|
|
158
162
|
|
|
159
|
-
const renderCustomNotifyEntry = (context: ModuleContext, klass: GirClass, suffix: string): string[] => {
|
|
160
|
-
if (context.namespace.name !== "GObject" || klass.name !== "Object") {
|
|
161
|
-
return [];
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return [`[detail: \`notify::\${string}\`]: ${gobjectObjectMapRef(context, suffix)}["notify"];`];
|
|
165
|
-
};
|
|
166
|
-
|
|
167
163
|
const renderNotifyDetailEntries = (context: ModuleContext, klass: GirClass, suffix: string): string[] => {
|
|
168
164
|
const notifyValue = `${gobjectObjectMapRef(context, suffix)}["notify"]`;
|
|
169
165
|
|
|
@@ -219,10 +215,11 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
219
215
|
`__signals__?: ${map};`,
|
|
220
216
|
`connect<K extends keyof ${map}>(signal: K, handler: ${map}[K], isAfter?: boolean): number;`,
|
|
221
217
|
`emit<K extends keyof ${emitMap}>(sigName: K, ...args: ${emitMap}[K]["args"]): ${emitMap}[K]["result"];`,
|
|
222
|
-
"emit(sigName: string, ...args: unknown[]): unknown;",
|
|
223
218
|
];
|
|
224
219
|
|
|
225
|
-
if (
|
|
220
|
+
if (isRootObject) {
|
|
221
|
+
lines.push("emit(sigName: string, ...args: unknown[]): unknown;");
|
|
222
|
+
} else {
|
|
226
223
|
const chainable = (methods: string[], trailing: string): void => {
|
|
227
224
|
for (const method of methods) {
|
|
228
225
|
lines.push(
|
|
@@ -382,7 +379,7 @@ const renderCallback = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
382
379
|
const forEachInterfaceSignal = (
|
|
383
380
|
context: ModuleContext,
|
|
384
381
|
klass: GirClass,
|
|
385
|
-
consider: (signal:
|
|
382
|
+
consider: (signal: GirSignal) => void,
|
|
386
383
|
): void => {
|
|
387
384
|
for (const iface of resolveInterfaces(context.library, context.namespace.name, klass.implements)) {
|
|
388
385
|
for (const signal of iface.klass.signals) {
|
|
@@ -391,12 +388,12 @@ const forEachInterfaceSignal = (
|
|
|
391
388
|
}
|
|
392
389
|
};
|
|
393
390
|
|
|
394
|
-
const collectClassSignals = (context: ModuleContext, klass: GirClass):
|
|
391
|
+
const collectClassSignals = (context: ModuleContext, klass: GirClass): GirSignal[] => {
|
|
395
392
|
const inheritedNames = collectInheritedSignalNames(context, klass);
|
|
396
393
|
const seen: Set<string> = new Set();
|
|
397
|
-
const result:
|
|
394
|
+
const result: GirSignal[] = [];
|
|
398
395
|
|
|
399
|
-
const consider = (signal:
|
|
396
|
+
const consider = (signal: GirSignal): void => {
|
|
400
397
|
const name = camelCase(signal.name);
|
|
401
398
|
|
|
402
399
|
if (!signal.introspectable || inheritedNames.has(name) || seen.has(name)) {
|