@gtkx/codegen 1.0.0 → 1.2.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 +1 -1
- package/dist/analysis/descriptor-render.d.ts +12 -15
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +59 -38
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +25 -10
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +37 -9
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/inheritance.d.ts +4 -2
- package/dist/analysis/inheritance.d.ts.map +1 -1
- package/dist/analysis/inheritance.js +80 -38
- package/dist/analysis/inheritance.js.map +1 -1
- package/dist/analysis/interface-conflicts.d.ts +25 -0
- package/dist/analysis/interface-conflicts.d.ts.map +1 -0
- package/dist/analysis/interface-conflicts.js +139 -0
- package/dist/analysis/interface-conflicts.js.map +1 -0
- package/dist/analysis/param-capability.d.ts.map +1 -1
- package/dist/analysis/param-capability.js +3 -4
- package/dist/analysis/param-capability.js.map +1 -1
- package/dist/analysis/param-structure.js +2 -2
- package/dist/analysis/param-structure.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +3 -2
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +26 -26
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/analysis/type-key.d.ts +5 -0
- package/dist/analysis/type-key.d.ts.map +1 -0
- package/dist/analysis/type-key.js +9 -0
- package/dist/analysis/type-key.js.map +1 -0
- package/dist/analysis/type-shape.d.ts +3 -2
- package/dist/analysis/type-shape.d.ts.map +1 -1
- package/dist/analysis/type-shape.js +2 -1
- package/dist/analysis/type-shape.js.map +1 -1
- package/dist/compile.d.ts +14 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +125 -24
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +2 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +11 -10
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/element-page.d.ts.map +1 -1
- package/dist/docs/element-page.js +5 -3
- package/dist/docs/element-page.js.map +1 -1
- package/dist/docs/pipeline.d.ts +1 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +93 -19
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/docs/render.d.ts +2 -1
- package/dist/docs/render.d.ts.map +1 -1
- package/dist/docs/render.js +5 -4
- package/dist/docs/render.js.map +1 -1
- package/dist/docs/symbol-page.d.ts.map +1 -1
- package/dist/docs/symbol-page.js +10 -9
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +20 -3
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +56 -37
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +1 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +8 -2
- package/dist/gi.js.map +1 -1
- package/dist/gir/ancestry.d.ts +7 -1
- package/dist/gir/ancestry.d.ts.map +1 -1
- package/dist/gir/ancestry.js +9 -1
- package/dist/gir/ancestry.js.map +1 -1
- package/dist/gir/annotations.d.ts +1 -2
- package/dist/gir/annotations.d.ts.map +1 -1
- package/dist/gir/annotations.js +1 -1
- package/dist/gir/annotations.js.map +1 -1
- package/dist/gir/cursor-overrides.d.ts +8 -0
- package/dist/gir/cursor-overrides.d.ts.map +1 -0
- package/dist/gir/cursor-overrides.js +6 -0
- package/dist/gir/cursor-overrides.js.map +1 -0
- package/dist/gir/emittable.d.ts +7 -0
- package/dist/gir/emittable.d.ts.map +1 -0
- package/dist/gir/emittable.js +3 -0
- package/dist/gir/emittable.js.map +1 -0
- package/dist/gir/function.d.ts.map +1 -1
- package/dist/gir/function.js +28 -2
- package/dist/gir/function.js.map +1 -1
- package/dist/gir/gir-path.d.ts +1 -1
- package/dist/gir/gir-path.js +1 -1
- package/dist/gir/gir-path.js.map +1 -1
- package/dist/gir/library.d.ts +5 -1
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +9 -2
- package/dist/gir/library.js.map +1 -1
- package/dist/gir/namespace.d.ts +5 -1
- package/dist/gir/namespace.d.ts.map +1 -1
- package/dist/gir/namespace.js +4 -2
- package/dist/gir/namespace.js.map +1 -1
- package/dist/gir/parameter.d.ts +13 -1
- package/dist/gir/parameter.d.ts.map +1 -1
- package/dist/gir/parameter.js +1 -0
- package/dist/gir/parameter.js.map +1 -1
- package/dist/gir/parse.d.ts.map +1 -1
- package/dist/gir/parse.js +6 -6
- package/dist/gir/parse.js.map +1 -1
- package/dist/gir/primitives.js +1 -1
- package/dist/gir/primitives.js.map +1 -1
- package/dist/guards.d.ts +16 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +11 -0
- package/dist/guards.js.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/json.d.ts +3 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +11 -0
- package/dist/json.js.map +1 -0
- package/dist/khronos/args.d.ts.map +1 -1
- package/dist/khronos/args.js +8 -6
- package/dist/khronos/args.js.map +1 -1
- package/dist/khronos/modules.d.ts.map +1 -1
- package/dist/khronos/modules.js +22 -7
- package/dist/khronos/modules.js.map +1 -1
- package/dist/khronos/parse.d.ts.map +1 -1
- package/dist/khronos/parse.js +3 -4
- package/dist/khronos/parse.js.map +1 -1
- package/dist/khronos/pipeline.d.ts +1 -1
- package/dist/khronos/pipeline.d.ts.map +1 -1
- package/dist/khronos/pipeline.js.map +1 -1
- package/dist/khronos/plan.d.ts +1 -7
- package/dist/khronos/plan.d.ts.map +1 -1
- package/dist/khronos/plan.js +1 -1
- package/dist/khronos/plan.js.map +1 -1
- package/dist/khronos/render.d.ts.map +1 -1
- package/dist/khronos/render.js +8 -4
- package/dist/khronos/render.js.map +1 -1
- package/dist/runner.d.ts +7 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +21 -3
- package/dist/runner.js.map +1 -1
- package/dist/staging.d.ts +5 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +57 -0
- package/dist/staging.js.map +1 -0
- package/dist/store/compile-store.d.ts +0 -1
- package/dist/store/compile-store.d.ts.map +1 -1
- package/dist/store/compile-store.js +7 -32
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts +6 -3
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +40 -30
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/callback.d.ts.map +1 -1
- package/dist/store/gi/callback.js +9 -5
- package/dist/store/gi/callback.js.map +1 -1
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +104 -44
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/companion.d.ts.map +1 -1
- package/dist/store/gi/companion.js +6 -6
- package/dist/store/gi/companion.js.map +1 -1
- package/dist/store/gi/constant.d.ts.map +1 -1
- package/dist/store/gi/constant.js +11 -3
- package/dist/store/gi/constant.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/enum.d.ts.map +1 -1
- package/dist/store/gi/enum.js +29 -12
- package/dist/store/gi/enum.js.map +1 -1
- package/dist/store/gi/function.d.ts +1 -3
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +24 -18
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +4 -1
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/interface.d.ts.map +1 -1
- package/dist/store/gi/interface.js +34 -19
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts +7 -6
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +13 -24
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/param-marshal.d.ts +3 -2
- package/dist/store/gi/param-marshal.d.ts.map +1 -1
- package/dist/store/gi/param-marshal.js +50 -5
- package/dist/store/gi/param-marshal.js.map +1 -1
- package/dist/store/gi/pipeline.d.ts.map +1 -1
- package/dist/store/gi/pipeline.js +21 -10
- package/dist/store/gi/pipeline.js.map +1 -1
- package/dist/store/gi/properties.d.ts +2 -1
- package/dist/store/gi/properties.d.ts.map +1 -1
- package/dist/store/gi/properties.js +6 -3
- package/dist/store/gi/properties.js.map +1 -1
- package/dist/store/gi/property-accessor.d.ts +10 -8
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +49 -91
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts +8 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +34 -13
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +20 -4
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record-layout.d.ts +6 -1
- package/dist/store/gi/record-layout.d.ts.map +1 -1
- package/dist/store/gi/record-layout.js +8 -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 +19 -8
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/registration.js +2 -2
- package/dist/store/gi/registration.js.map +1 -1
- package/dist/store/gi/return-wrap.js +1 -1
- package/dist/store/gi/return-wrap.js.map +1 -1
- package/dist/store/gi/signal.d.ts +2 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +55 -28
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/value-marshalable.d.ts.map +1 -1
- package/dist/store/gi/value-marshalable.js +2 -1
- package/dist/store/gi/value-marshalable.js.map +1 -1
- package/dist/store/gi/vtable.d.ts +4 -1
- package/dist/store/gi/vtable.d.ts.map +1 -1
- package/dist/store/gi/vtable.js +60 -17
- package/dist/store/gi/vtable.js.map +1 -1
- package/dist/store/gi-store.d.ts +1 -0
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js +15 -20
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/generated-elements.d.ts +2 -1
- package/dist/store/jsx/generated-elements.d.ts.map +1 -1
- package/dist/store/jsx/generated-elements.js +13 -7
- package/dist/store/jsx/generated-elements.js.map +1 -1
- package/dist/store/jsx/jsx.js +3 -3
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx/metadata.d.ts.map +1 -1
- package/dist/store/jsx/metadata.js +3 -1
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +3 -4
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts +14 -3
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +98 -15
- package/dist/store/resolve-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +9 -7
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +54 -25
- package/dist/store/store-fs.js.map +1 -1
- package/dist/store/store-links.d.ts +3 -0
- package/dist/store/store-links.d.ts.map +1 -0
- package/dist/store/store-links.js +39 -0
- package/dist/store/store-links.js.map +1 -0
- package/dist/writer/comparison-context.d.ts +4 -0
- package/dist/writer/comparison-context.d.ts.map +1 -0
- package/dist/writer/comparison-context.js +13 -0
- package/dist/writer/comparison-context.js.map +1 -0
- package/dist/writer/context.d.ts +3 -3
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +11 -6
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/module.d.ts +13 -5
- package/dist/writer/module.d.ts.map +1 -1
- package/dist/writer/module.js +68 -11
- package/dist/writer/module.js.map +1 -1
- package/dist/xml.d.ts +8 -1
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +70 -1
- package/dist/xml.js.map +1 -1
- package/overrides/gobject/object.ts.ejs +2 -0
- package/package.json +14 -3
- package/src/analysis/descriptor-render.ts +106 -52
- package/src/analysis/descriptor.ts +76 -15
- package/src/analysis/inheritance.ts +134 -44
- package/src/analysis/interface-conflicts.ts +235 -0
- package/src/analysis/param-capability.ts +3 -6
- package/src/analysis/param-structure.ts +2 -2
- package/src/analysis/ts-type.ts +43 -28
- package/src/analysis/type-key.ts +14 -0
- package/src/analysis/type-shape.ts +5 -2
- package/src/compile.ts +192 -27
- package/src/docs/api-reference.ts +13 -10
- package/src/docs/element-page.ts +5 -2
- package/src/docs/pipeline.ts +140 -24
- package/src/docs/render.ts +7 -3
- package/src/docs/symbol-page.ts +12 -11
- package/src/fingerprint.ts +95 -47
- package/src/gi.ts +10 -2
- package/src/gir/ancestry.ts +17 -1
- package/src/gir/annotations.ts +1 -1
- package/src/gir/cursor-overrides.ts +12 -0
- package/src/gir/emittable.ts +8 -0
- package/src/gir/function.ts +45 -9
- package/src/gir/gir-path.ts +1 -1
- package/src/gir/library.ts +10 -2
- package/src/gir/namespace.ts +8 -2
- package/src/gir/parameter.ts +15 -0
- package/src/gir/parse.ts +10 -7
- package/src/gir/primitives.ts +1 -1
- package/src/guards.ts +23 -0
- package/src/internal.ts +2 -0
- package/src/json.ts +11 -0
- package/src/khronos/args.ts +9 -6
- package/src/khronos/modules.ts +25 -9
- package/src/khronos/parse.ts +3 -4
- package/src/khronos/pipeline.ts +1 -1
- package/src/khronos/plan.ts +0 -1
- package/src/khronos/render.ts +8 -6
- package/src/runner.ts +26 -4
- package/src/staging.ts +67 -0
- package/src/store/compile-store.ts +7 -38
- package/src/store/gi/callables.ts +60 -33
- package/src/store/gi/callback.ts +9 -9
- package/src/store/gi/class.ts +140 -53
- package/src/store/gi/companion.ts +7 -6
- package/src/store/gi/constant.ts +13 -3
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/enum.ts +36 -26
- package/src/store/gi/function.ts +30 -24
- package/src/store/gi/gtype-binding.ts +7 -2
- package/src/store/gi/interface.ts +39 -20
- package/src/store/gi/method.ts +26 -32
- package/src/store/gi/param-marshal.ts +77 -6
- package/src/store/gi/pipeline.ts +25 -15
- package/src/store/gi/properties.ts +8 -4
- package/src/store/gi/property-accessor.ts +73 -161
- package/src/store/gi/record-constructor.ts +53 -21
- package/src/store/gi/record-field-accessor.ts +26 -4
- package/src/store/gi/record-layout.ts +11 -1
- package/src/store/gi/record.ts +20 -12
- package/src/store/gi/registration.ts +2 -2
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +66 -42
- package/src/store/gi/value-marshalable.ts +3 -1
- package/src/store/gi/vtable.ts +97 -20
- package/src/store/gi-store.ts +26 -31
- package/src/store/jsx/generated-elements.ts +17 -8
- package/src/store/jsx/jsx.ts +3 -3
- package/src/store/jsx/metadata.ts +4 -1
- package/src/store/jsx-store.ts +3 -4
- package/src/store/resolve-store.ts +133 -18
- package/src/store/store-fs.ts +82 -35
- package/src/store/store-links.ts +49 -0
- package/src/writer/comparison-context.ts +18 -0
- package/src/writer/context.ts +12 -6
- package/src/writer/module.ts +101 -14
- package/src/xml.ts +103 -1
|
@@ -46,6 +46,16 @@ const computeRecordFieldSlots = (
|
|
|
46
46
|
return { slots, size: result.size };
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
const recordInlineSize = (context: ModuleContext, record: ResolvedRecordValue): number | undefined => {
|
|
50
|
+
if (record.opaque || record.disguised || record.fields.length === 0) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { size } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
55
|
+
|
|
56
|
+
return size > 0 ? size : undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
49
59
|
const bitMask = (width: number): number => {
|
|
50
60
|
if (width >= 32) {
|
|
51
61
|
return 0xFF_FF_FF_FF;
|
|
@@ -214,4 +224,4 @@ const resolveAliasLayout = (
|
|
|
214
224
|
return layoutOfType(context, ref, resolved.value.targetCType, visited);
|
|
215
225
|
};
|
|
216
226
|
|
|
217
|
-
export { computeRecordFieldSlots, bitMask, mergeBitfield, type RecordFieldSlot };
|
|
227
|
+
export { computeRecordFieldSlots, recordInlineSize, bitMask, mergeBitfield, type RecordFieldSlot };
|
package/src/store/gi/record.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { sanitizeTypeIdentifier } from "@gtkx/utils";
|
|
1
2
|
import type { GirRecord } from "../../gir/record.js";
|
|
2
3
|
import type { ModuleContext } from "../../writer/context.js";
|
|
4
|
+
import { isEmittableEntity } from "../../gir/emittable.js";
|
|
3
5
|
import { indentMembers } from "../../writer/emit.js";
|
|
4
6
|
import { type Callables, dedupeCallables, generateBindings, renderPlainTypeMembers } from "./callables.js";
|
|
5
7
|
import { getDoc } from "./doc-spec.js";
|
|
@@ -8,20 +10,17 @@ import { renderRecordConstructor, renderRecordConstructorPropsInterface } from "
|
|
|
8
10
|
import { renderRecordFieldAccessor } from "./record-field-accessor.js";
|
|
9
11
|
import { computeRecordFieldSlots } from "./record-layout.js";
|
|
10
12
|
import { appendWrapperClassRegistration } from "./registration.js";
|
|
13
|
+
import { isConstructibleRecord } from "./value-marshalable.js";
|
|
11
14
|
|
|
12
15
|
const isGErrorRecord = (context: ModuleContext, record: GirRecord): boolean =>
|
|
13
16
|
context.namespace.name === "GLib" && record.glibGetType === "g_error_get_type";
|
|
14
17
|
|
|
15
18
|
const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
16
|
-
if (!record
|
|
19
|
+
if (!isEmittableEntity(record)) {
|
|
17
20
|
return;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const className = record.name;
|
|
23
|
+
const className = sanitizeTypeIdentifier(record.name);
|
|
25
24
|
const isErrorSubclass = isGErrorRecord(context, record);
|
|
26
25
|
|
|
27
26
|
const callables: Callables = {
|
|
@@ -35,13 +34,22 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
35
34
|
const body = indentMembers(members);
|
|
36
35
|
const heritage = isErrorSubclass ? " extends globalThis.Error" : "";
|
|
37
36
|
const doc = getDoc(record);
|
|
37
|
+
const isConstructible = isConstructibleRecord(context, context.namespace.name, record);
|
|
38
|
+
const modifier = isConstructible ? "" : "abstract ";
|
|
38
39
|
|
|
39
|
-
context.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
context.declare({
|
|
41
|
+
name: className,
|
|
42
|
+
code: `${doc}export ${modifier}class ${className}${heritage} {\n${body}\n}`,
|
|
43
|
+
owner: record.name,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (isConstructible) {
|
|
47
|
+
context.declare({
|
|
48
|
+
name: `${className}ConstructorProps`,
|
|
49
|
+
code: renderRecordConstructorPropsInterface(context, record, className),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
43
52
|
|
|
44
|
-
context.module.appendDeclaration(renderRecordConstructorPropsInterface(context, record, className));
|
|
45
53
|
const gtypeExpr = renderSourceGtype(context, record);
|
|
46
54
|
|
|
47
55
|
appendWrapperClassRegistration(context, {
|
|
@@ -65,7 +73,7 @@ const renderRecordMembers = (
|
|
|
65
73
|
hasGtype: record.glibGetType !== undefined,
|
|
66
74
|
});
|
|
67
75
|
|
|
68
|
-
members.unshift(renderRecordConstructor(context, record, className, isErrorSubclass));
|
|
76
|
+
members.unshift(renderRecordConstructor(context, { record, className, callables, isErrorSubclass }));
|
|
69
77
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
70
78
|
|
|
71
79
|
for (const slot of slots) {
|
|
@@ -25,7 +25,7 @@ const appendWrapperClassRegistration = (
|
|
|
25
25
|
|
|
26
26
|
context.addRuntimeImport("registerWrapperClass");
|
|
27
27
|
const args = vfuncs === undefined ? gtypeExpr : `${gtypeExpr}, ${vfuncs}`;
|
|
28
|
-
context.module.appendRegistration(`registerWrapperClass(${className}, ${args})
|
|
28
|
+
context.module.appendRegistration(`registerWrapperClass(${className}, ${args});`, [className]);
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const appendInterfaceRegistration = (context: ModuleContext, registration: InterfaceRegistration): void => {
|
|
@@ -38,7 +38,7 @@ const appendInterfaceRegistration = (context: ModuleContext, registration: Inter
|
|
|
38
38
|
context.addRuntimeImport("registerInterface");
|
|
39
39
|
const base = `${className}, ${gtypeExpr}, ${makerName}`;
|
|
40
40
|
const args = layout === undefined ? base : `${base}, ${layout}`;
|
|
41
|
-
context.module.appendRegistration(`registerInterface(${args})
|
|
41
|
+
context.module.appendRegistration(`registerInterface(${args});`, [className, makerName]);
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
export { appendWrapperClassRegistration, appendInterfaceRegistration };
|
|
@@ -10,7 +10,7 @@ type WrapReturnOptions = {
|
|
|
10
10
|
valueExpression: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["gtype", "bigint64", "biguint64"]);
|
|
13
|
+
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["gtype", "bigint64", "biguint64", "pointer"]);
|
|
14
14
|
|
|
15
15
|
const wrapReturnValue = (context: ModuleContext, options: WrapReturnOptions): string => {
|
|
16
16
|
const { ref, isNullable, valueExpression } = options;
|
package/src/store/gi/signal.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { camelCase, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { GirClass } from "../../gir/class.js";
|
|
3
|
-
import type { GirCallable, GirParameter } from "../../gir/parameter.js";
|
|
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";
|
|
6
|
+
import type { Declaration } from "../../writer/module.js";
|
|
6
7
|
import {
|
|
7
8
|
isCellInout,
|
|
9
|
+
primaryReturnKind,
|
|
8
10
|
renderDescriptor,
|
|
9
11
|
renderParamDescriptor,
|
|
10
|
-
shouldOmitPrimaryReturn,
|
|
11
12
|
} from "../../analysis/descriptor-render.js";
|
|
12
13
|
import { tCallback, tObject, tVoid } from "../../analysis/descriptor.js";
|
|
13
14
|
import {
|
|
@@ -23,7 +24,7 @@ import { renderJsDoc } from "../../writer/doc.js";
|
|
|
23
24
|
import { indent, renderBlock, renderBracedOrEmpty } from "../../writer/emit.js";
|
|
24
25
|
import { parentCompanionRef } from "./companion.js";
|
|
25
26
|
import { getDoc, handlerSpec } from "./doc-spec.js";
|
|
26
|
-
import {
|
|
27
|
+
import { isAllocatableCallerOut, isRecordInout, renderCallerOutInstance } from "./param-marshal.js";
|
|
27
28
|
|
|
28
29
|
type SignalMapSpec = {
|
|
29
30
|
context: ModuleContext;
|
|
@@ -47,6 +48,21 @@ const SIGNAL_HANDLER_TYPE = "(...args: any[]) => any";
|
|
|
47
48
|
const SIGNALS_SUFFIX = "Signals";
|
|
48
49
|
const SIGNAL_EMIT_SUFFIX = "SignalEmit";
|
|
49
50
|
|
|
51
|
+
const DEPRECATED_SIGNAL_ALIASES: Map<string, string> = new Map([
|
|
52
|
+
["addEventListener", "on"],
|
|
53
|
+
["removeEventListener", "off"],
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
const deprecatedAliasDoc = (method: string): string => {
|
|
57
|
+
const replacement = DEPRECATED_SIGNAL_ALIASES.get(method);
|
|
58
|
+
|
|
59
|
+
if (replacement === undefined) {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return `/** @deprecated Since 1.2. Use \`${replacement}\` instead. Removed in v2. */\n`;
|
|
64
|
+
};
|
|
65
|
+
|
|
50
66
|
const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[] => {
|
|
51
67
|
if (klass.glibGetType === undefined) {
|
|
52
68
|
return [];
|
|
@@ -67,7 +83,7 @@ const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[]
|
|
|
67
83
|
|
|
68
84
|
const connectDefault = isRootObject
|
|
69
85
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + signal + \"'\");"
|
|
70
|
-
: "default:\n return super.connect(signal, handler, isAfter);";
|
|
86
|
+
: "default:\n return super.connect(signal as never, handler as never, isAfter);";
|
|
71
87
|
|
|
72
88
|
const emitDefault = isRootObject
|
|
73
89
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + sigName + \"'\");"
|
|
@@ -92,12 +108,18 @@ const renderSignalDeclarations = (
|
|
|
92
108
|
klass: GirClass,
|
|
93
109
|
className: string,
|
|
94
110
|
isParentlessObjectSubclass: boolean,
|
|
95
|
-
):
|
|
111
|
+
): Declaration[] => {
|
|
96
112
|
const base = { context, klass, className, isParentlessObjectSubclass };
|
|
97
113
|
|
|
98
|
-
const declarations = [
|
|
99
|
-
|
|
100
|
-
|
|
114
|
+
const declarations: Declaration[] = [
|
|
115
|
+
{
|
|
116
|
+
name: `${className}${SIGNALS_SUFFIX}`,
|
|
117
|
+
code: renderSignalMap({ ...base, suffix: SIGNALS_SUFFIX, renderEntry: renderSignalHandlerType }),
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: `${className}${SIGNAL_EMIT_SUFFIX}`,
|
|
121
|
+
code: renderSignalMap({ ...base, suffix: SIGNAL_EMIT_SUFFIX, renderEntry: renderSignalEmitEntry }),
|
|
122
|
+
},
|
|
101
123
|
];
|
|
102
124
|
|
|
103
125
|
if (
|
|
@@ -107,7 +129,7 @@ const renderSignalDeclarations = (
|
|
|
107
129
|
klass.implements.length > 0)
|
|
108
130
|
) {
|
|
109
131
|
const isRootObject = context.namespace.name === "GObject" && klass.name === "Object";
|
|
110
|
-
declarations.push(renderSignalConnectInterface(className, isRootObject));
|
|
132
|
+
declarations.push({ name: className, code: renderSignalConnectInterface(className, isRootObject) });
|
|
111
133
|
}
|
|
112
134
|
|
|
113
135
|
return declarations;
|
|
@@ -122,7 +144,11 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
122
144
|
(signal) => `${signalDoc(signal)}${sourceStringLiteral(signal.name)}: ${renderEntry(context, signal)};`,
|
|
123
145
|
);
|
|
124
146
|
|
|
125
|
-
const entries = [
|
|
147
|
+
const entries = [
|
|
148
|
+
...signalEntries,
|
|
149
|
+
...renderNotifyDetailEntries(context, klass, suffix),
|
|
150
|
+
...renderCustomNotifyEntry(context, klass, suffix),
|
|
151
|
+
];
|
|
126
152
|
|
|
127
153
|
return renderBracedOrEmpty(`export interface ${className}${suffix}${extendsClause}`, entries.join("\n"));
|
|
128
154
|
};
|
|
@@ -130,6 +156,14 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
130
156
|
const signalDoc = (signal: GirCallable): string =>
|
|
131
157
|
renderJsDoc(signal.doc, undefined, handlerSpec(signal, signal.parameters));
|
|
132
158
|
|
|
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
|
+
|
|
133
167
|
const renderNotifyDetailEntries = (context: ModuleContext, klass: GirClass, suffix: string): string[] => {
|
|
134
168
|
const notifyValue = `${gobjectObjectMapRef(context, suffix)}["notify"]`;
|
|
135
169
|
|
|
@@ -184,7 +218,6 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
184
218
|
const lines = [
|
|
185
219
|
`__signals__?: ${map};`,
|
|
186
220
|
`connect<K extends keyof ${map}>(signal: K, handler: ${map}[K], isAfter?: boolean): number;`,
|
|
187
|
-
`connect(signal: string, handler: ${SIGNAL_HANDLER_TYPE}, isAfter?: boolean): number;`,
|
|
188
221
|
`emit<K extends keyof ${emitMap}>(sigName: K, ...args: ${emitMap}[K]["args"]): ${emitMap}[K]["result"];`,
|
|
189
222
|
"emit(sigName: string, ...args: unknown[]): unknown;",
|
|
190
223
|
];
|
|
@@ -193,8 +226,8 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
193
226
|
const chainable = (methods: string[], trailing: string): void => {
|
|
194
227
|
for (const method of methods) {
|
|
195
228
|
lines.push(
|
|
229
|
+
deprecatedAliasDoc(method) +
|
|
196
230
|
`${method}<K extends keyof ${map}>(signal: K, handler: ${map}[K]${trailing}): this;`,
|
|
197
|
-
`${method}(signal: string, handler: ${SIGNAL_HANDLER_TYPE}${trailing}): this;`,
|
|
198
231
|
);
|
|
199
232
|
}
|
|
200
233
|
};
|
|
@@ -263,7 +296,7 @@ const renderEmitArgLiteral = (options: EmitArgOptions): { literal: string; nextA
|
|
|
263
296
|
}
|
|
264
297
|
|
|
265
298
|
if (isCallerAllocatedOut(parameter)) {
|
|
266
|
-
const value =
|
|
299
|
+
const value = renderCallerOutInstance(context, parameter);
|
|
267
300
|
|
|
268
301
|
return {
|
|
269
302
|
literal: `{ type: ${descriptor}, direction: "out", isCallerAllocated: true, value: ${value} }`,
|
|
@@ -283,10 +316,18 @@ const renderEmitArgLiteral = (options: EmitArgOptions): { literal: string; nextA
|
|
|
283
316
|
return { literal: `{ type: ${descriptor}, value: args[${String(argIndex)}] }`, nextArgIndex: argIndex + 1 };
|
|
284
317
|
};
|
|
285
318
|
|
|
319
|
+
const renderEmitReturnArg = (context: ModuleContext, returnValue: GirReturnValue): string => {
|
|
320
|
+
if (primaryReturnKind(context.library, returnValue) === "void") {
|
|
321
|
+
return "";
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return `, ${renderDescriptor(context, returnValue.type, returnValue.transferOwnership)}`;
|
|
325
|
+
};
|
|
326
|
+
|
|
286
327
|
const renderEmitCase = (context: ModuleContext, signal: GirCallable): string => {
|
|
287
328
|
const params = nonVarargParameters(signal);
|
|
288
329
|
|
|
289
|
-
if (params.some((parameter) => isCallerAllocatedOut(parameter) && !
|
|
330
|
+
if (params.some((parameter) => isCallerAllocatedOut(parameter) && !isAllocatableCallerOut(context, parameter))) {
|
|
290
331
|
return renderUnsupportedEmitCase(signal);
|
|
291
332
|
}
|
|
292
333
|
|
|
@@ -301,12 +342,7 @@ const renderEmitCase = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
301
342
|
return rendered.literal;
|
|
302
343
|
});
|
|
303
344
|
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
const returnArg = isVoid
|
|
307
|
-
? ""
|
|
308
|
-
: `, ${renderDescriptor(context, signal.returnValue.type, signal.returnValue.transferOwnership)}`;
|
|
309
|
-
|
|
345
|
+
const returnArg = renderEmitReturnArg(context, signal.returnValue);
|
|
310
346
|
const body = `return emitSignal(this, sigName, [${argLiterals.join(", ")}]${returnArg});`;
|
|
311
347
|
|
|
312
348
|
return renderBlock(`case ${sourceStringLiteral(signal.name)}:`, body);
|
|
@@ -321,16 +357,6 @@ const renderUnsupportedEmitCase = (signal: GirCallable): string => {
|
|
|
321
357
|
);
|
|
322
358
|
};
|
|
323
359
|
|
|
324
|
-
const renderCallerOutAllocation = (context: ModuleContext, parameter: GirParameter): string => {
|
|
325
|
-
const name = parameter.type === undefined ? undefined : context.library.nameFor(parameter.type);
|
|
326
|
-
|
|
327
|
-
if (name === undefined) {
|
|
328
|
-
throw new Error("renderCallerOutAllocation: expected a named caller-allocated out-parameter");
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return `new ${context.qualify(name.namespaceName, name.typeName)}()`;
|
|
332
|
-
};
|
|
333
|
-
|
|
334
360
|
const renderCallback = (context: ModuleContext, signal: GirCallable): string => {
|
|
335
361
|
const params = nonVarargParameters(signal);
|
|
336
362
|
|
|
@@ -338,21 +364,19 @@ const renderCallback = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
338
364
|
renderParamDescriptor(context, parameter, parameter.type, { argIndexOffset: 1 }),
|
|
339
365
|
);
|
|
340
366
|
|
|
341
|
-
const isVoid = shouldOmitPrimaryReturn(context.library, signal.returnValue);
|
|
342
|
-
|
|
343
|
-
const returnDescriptor = isVoid
|
|
344
|
-
? tVoid
|
|
345
|
-
: renderDescriptor(context, signal.returnValue.type, signal.returnValue.transferOwnership);
|
|
346
|
-
|
|
347
367
|
const callbackArgs = [tObject("borrowed"), ...callbackParamDescriptors, tVoid];
|
|
348
368
|
const userDataIndex = String(params.length + 1);
|
|
349
|
-
const destroy = "hasDestroy: true, destroyKind: \"closureNotify\"";
|
|
350
369
|
|
|
351
|
-
return tCallback(
|
|
352
|
-
callbackArgs,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
370
|
+
return tCallback({
|
|
371
|
+
argTypes: callbackArgs,
|
|
372
|
+
returns: renderDescriptor(context, signal.returnValue.type, signal.returnValue.transferOwnership),
|
|
373
|
+
options: [
|
|
374
|
+
"hasDestroy: true",
|
|
375
|
+
"destroyKind: \"closureNotify\"",
|
|
376
|
+
"hasUserData: true",
|
|
377
|
+
`userDataIndex: ${userDataIndex}`,
|
|
378
|
+
],
|
|
379
|
+
});
|
|
356
380
|
};
|
|
357
381
|
|
|
358
382
|
const forEachInterfaceSignal = (
|
|
@@ -15,6 +15,8 @@ const hasOwnCopySemantics = (record: GirRecord): boolean =>
|
|
|
15
15
|
record.glibGetType !== undefined ||
|
|
16
16
|
((record.glibRefFunc ?? record.copyFunc) !== undefined && (record.glibUnrefFunc ?? record.freeFunc) !== undefined);
|
|
17
17
|
|
|
18
|
+
const isOpaqueRecord = (record: GirRecord): boolean => record.opaque || record.disguised;
|
|
19
|
+
|
|
18
20
|
const isValueSafeArray = (scope: Scope, type: Extract<GirType, { kind: "carray" }>): boolean =>
|
|
19
21
|
type.fixedSize !== undefined && isValueSafeRef(scope, type.element, type.elementCType);
|
|
20
22
|
|
|
@@ -82,6 +84,6 @@ const isValueMarshalable = (context: ModuleContext, namespaceName: string, recor
|
|
|
82
84
|
isValueSafeRecord({ context, seen: new Set<string>() }, namespaceName, record);
|
|
83
85
|
|
|
84
86
|
const isConstructibleRecord = (context: ModuleContext, namespaceName: string, record: GirRecord): boolean =>
|
|
85
|
-
hasOwnCopySemantics(record) || isValueMarshalable(context, namespaceName, record);
|
|
87
|
+
!isOpaqueRecord(record) && (hasOwnCopySemantics(record) || isValueMarshalable(context, namespaceName, record));
|
|
86
88
|
|
|
87
89
|
export { isConstructibleRecord, isValueMarshalable };
|
package/src/store/gi/vtable.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { pascalCase, sourceStringLiteral } from "@gtkx/utils";
|
|
2
|
-
import type { GirCallback } from "../../gir/callback.js";
|
|
1
|
+
import { pascalCase, sanitizeTypeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
3
2
|
import type { GirClass, GirVirtualMethod } from "../../gir/class.js";
|
|
4
3
|
import type { GirField } from "../../gir/field.js";
|
|
4
|
+
import type { GirFunction } from "../../gir/function.js";
|
|
5
|
+
import type { Library } from "../../gir/library.js";
|
|
5
6
|
import type { GirParameter } from "../../gir/parameter.js";
|
|
6
7
|
import type { GirRecord } from "../../gir/record.js";
|
|
7
8
|
import type { TypeId } from "../../gir/type-id.js";
|
|
@@ -22,7 +23,9 @@ import {
|
|
|
22
23
|
renderHandlerResultType,
|
|
23
24
|
} from "../../analysis/param-structure.js";
|
|
24
25
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
26
|
+
import { typeKey } from "../../analysis/type-key.js";
|
|
25
27
|
import { ancestorChain, type ResolvedAncestor, resolveInterfaces } from "../../gir/ancestry.js";
|
|
28
|
+
import { callbackAsFunction, type GirCallback } from "../../gir/callback.js";
|
|
26
29
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
27
30
|
import { renderBlock, renderBraced } from "../../writer/emit.js";
|
|
28
31
|
import { handlerSpec, THROWS_TEXT } from "./doc-spec.js";
|
|
@@ -80,6 +83,7 @@ const UNCALLABLE_SLOT_KEYS: Set<string> = new Set([
|
|
|
80
83
|
"vfuncSetProperty",
|
|
81
84
|
]);
|
|
82
85
|
|
|
86
|
+
const VTABLE_CACHE: WeakMap<GirClass, Vtable> = new WeakMap();
|
|
83
87
|
const PROTECTED_SLOT_NOTE = "It is `protected`, so only a subclass chaining up reaches it.";
|
|
84
88
|
const PUBLIC_SLOT_NOTE = "Calling it from anywhere else re-enters the slot on a live instance.";
|
|
85
89
|
|
|
@@ -193,7 +197,7 @@ const attachVirtualMethods = (slots: VtableSlot[], klass: GirClass): VtableSlot[
|
|
|
193
197
|
return slots.map((slot) => ({ ...slot, vfunc: byKey.get(slot.key) }));
|
|
194
198
|
};
|
|
195
199
|
|
|
196
|
-
const
|
|
200
|
+
const buildVtable = (context: ModuleContext, namespaceName: string, klass: GirClass): Vtable | undefined => {
|
|
197
201
|
const resolved = resolveVtableRecord(context, namespaceName, klass);
|
|
198
202
|
|
|
199
203
|
if (resolved === undefined) {
|
|
@@ -210,10 +214,63 @@ const collectVtable = (context: ModuleContext, namespaceName: string, klass: Gir
|
|
|
210
214
|
structName: pascalCase(resolved.typeStruct),
|
|
211
215
|
kind: klass.isInterface ? "interface" : "class",
|
|
212
216
|
vtableSize,
|
|
213
|
-
slots: attachVirtualMethods(slots, klass),
|
|
217
|
+
slots: disambiguateSlots(context, namespaceName, klass, attachVirtualMethods(slots, klass)),
|
|
214
218
|
};
|
|
215
219
|
};
|
|
216
220
|
|
|
221
|
+
const collectVtable = (context: ModuleContext, namespaceName: string, klass: GirClass): Vtable | undefined => {
|
|
222
|
+
const cached = VTABLE_CACHE.get(klass);
|
|
223
|
+
|
|
224
|
+
if (cached !== undefined) {
|
|
225
|
+
return cached;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const vtable = buildVtable(context, namespaceName, klass);
|
|
229
|
+
|
|
230
|
+
if (vtable !== undefined) {
|
|
231
|
+
VTABLE_CACHE.set(klass, vtable);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return vtable;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const shadowedSlotKey = (klass: GirClass, slot: VtableSlot): string =>
|
|
238
|
+
`vfunc${sanitizeTypeIdentifier(klass.name)}${pascalCase(slot.field.name)}`;
|
|
239
|
+
|
|
240
|
+
const slotSignatureKey = (library: Library, slot: VtableSlot): string => {
|
|
241
|
+
const [, ...parameters] = slot.callback.parameters;
|
|
242
|
+
|
|
243
|
+
const parts = parameters.map(
|
|
244
|
+
(parameter) => `${typeKey(library, parameter.type)}/${parameter.direction}/${String(parameter.nullable)}`);
|
|
245
|
+
|
|
246
|
+
return `${parts.join(",")}->${typeKey(library, slot.callback.returnValue.type)}`;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const isShadowingSlot = (library: Library, slot: VtableSlot, inherited: VtableSlot[]): boolean =>
|
|
250
|
+
inherited.some(
|
|
251
|
+
(other) =>
|
|
252
|
+
other.key === slot.key &&
|
|
253
|
+
slotIdentity(other) !== slotIdentity(slot) &&
|
|
254
|
+
slotSignatureKey(library, other) !== slotSignatureKey(library, slot));
|
|
255
|
+
|
|
256
|
+
const disambiguateSlots = (
|
|
257
|
+
context: ModuleContext,
|
|
258
|
+
namespaceName: string,
|
|
259
|
+
klass: GirClass,
|
|
260
|
+
slots: VtableSlot[],
|
|
261
|
+
): VtableSlot[] => {
|
|
262
|
+
const inherited = ancestorSlots(context, namespaceName, klass);
|
|
263
|
+
|
|
264
|
+
return slots.map((slot) =>
|
|
265
|
+
isShadowingSlot(context.library, slot, inherited) ? { ...slot, key: shadowedSlotKey(klass, slot) } : slot);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const ancestorSlots = (context: ModuleContext, namespaceName: string, klass: GirClass): VtableSlot[] => {
|
|
269
|
+
const [, ...ancestors] = [...ancestorChain(context.library, klass, namespaceName)];
|
|
270
|
+
|
|
271
|
+
return ancestors.flatMap((ancestor) => collectVtable(context, ancestor.namespaceName, ancestor.klass)?.slots ?? []);
|
|
272
|
+
};
|
|
273
|
+
|
|
217
274
|
const vfuncMemberNames = (context: ModuleContext, namespaceName: string, klass: GirClass): string[] =>
|
|
218
275
|
collectVtable(context, namespaceName, klass)?.slots.map((slot) => slot.key) ?? [];
|
|
219
276
|
|
|
@@ -231,21 +288,8 @@ const renderVfuncMetadata = (context: ModuleContext, klass: GirClass): string |
|
|
|
231
288
|
|
|
232
289
|
const slotIdentity = (slot: VtableSlot): string => `${slot.key}:${String(slot.byteOffset)}`;
|
|
233
290
|
|
|
234
|
-
const inheritedSlotIdentities = (context: ModuleContext, namespaceName: string, klass: GirClass): Set<string> =>
|
|
235
|
-
|
|
236
|
-
const [, ...ancestors] = [...ancestorChain(context.library, klass, namespaceName)];
|
|
237
|
-
|
|
238
|
-
for (const ancestor of ancestors) {
|
|
239
|
-
const vtable = collectVtable(context, ancestor.namespaceName, ancestor.klass);
|
|
240
|
-
const slots = vtable?.slots ?? [];
|
|
241
|
-
|
|
242
|
-
for (const slot of slots) {
|
|
243
|
-
identities.add(slotIdentity(slot));
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return identities;
|
|
248
|
-
};
|
|
291
|
+
const inheritedSlotIdentities = (context: ModuleContext, namespaceName: string, klass: GirClass): Set<string> =>
|
|
292
|
+
new Set(ancestorSlots(context, namespaceName, klass).map((slot) => slotIdentity(slot)));
|
|
249
293
|
|
|
250
294
|
const addInterfaceSlotKeys = (
|
|
251
295
|
context: ModuleContext,
|
|
@@ -295,6 +339,37 @@ const protectedSlotKeys = (options: VfuncMembersOptions, slots: VtableSlot[]): S
|
|
|
295
339
|
return new Set(slots.map((slot) => slot.key).filter((key) => !shared.has(key)));
|
|
296
340
|
};
|
|
297
341
|
|
|
342
|
+
const vfuncCallables = (context: ModuleContext, namespaceName: string, klass: GirClass): Map<string, GirFunction> => {
|
|
343
|
+
const members: Map<string, GirFunction> = new Map();
|
|
344
|
+
|
|
345
|
+
for (const slot of callableVfuncSlots(context, namespaceName, klass)) {
|
|
346
|
+
const [, ...parameters] = slot.callback.parameters;
|
|
347
|
+
members.set(slot.key, { ...callbackAsFunction(slot.callback), parameters });
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return members;
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const addProtectedSlotKeys = (context: ModuleContext, ancestor: ResolvedAncestor, keys: Set<string>): void => {
|
|
354
|
+
const shared = implementedSlotKeys(context, ancestor.namespaceName, ancestor.klass);
|
|
355
|
+
|
|
356
|
+
for (const slot of callableVfuncSlots(context, ancestor.namespaceName, ancestor.klass)) {
|
|
357
|
+
if (!shared.has(slot.key)) {
|
|
358
|
+
keys.add(slot.key);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const protectedChainSlotKeys = (context: ModuleContext, klass: GirClass): Set<string> => {
|
|
364
|
+
const keys: Set<string> = new Set();
|
|
365
|
+
|
|
366
|
+
for (const ancestor of ancestorChain(context.library, klass, context.namespace.name)) {
|
|
367
|
+
addProtectedSlotKeys(context, ancestor, keys);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return keys;
|
|
371
|
+
};
|
|
372
|
+
|
|
298
373
|
const callableVfuncSlots = (context: ModuleContext, namespaceName: string, klass: GirClass): VtableSlot[] => {
|
|
299
374
|
const vtable = collectVtable(context, namespaceName, klass);
|
|
300
375
|
|
|
@@ -339,7 +414,7 @@ const vfuncEntries = (context: ModuleContext, namespaceName: string, klass: GirC
|
|
|
339
414
|
|
|
340
415
|
const renderVfuncMembers = (options: VfuncMembersOptions): string[] => {
|
|
341
416
|
const { context, klass, mode } = options;
|
|
342
|
-
const ownerRef =
|
|
417
|
+
const ownerRef = sanitizeTypeIdentifier(klass.name);
|
|
343
418
|
const slots = callableVfuncSlots(context, context.namespace.name, klass);
|
|
344
419
|
|
|
345
420
|
if (slots.length === 0) {
|
|
@@ -468,7 +543,9 @@ const renderVtableSlotDescriptor = (context: ModuleContext, vtable: Vtable, slot
|
|
|
468
543
|
|
|
469
544
|
export {
|
|
470
545
|
hasCallableVfuncSlots,
|
|
546
|
+
protectedChainSlotKeys,
|
|
471
547
|
renderVfuncMembers,
|
|
548
|
+
vfuncCallables,
|
|
472
549
|
renderVfuncMetadata,
|
|
473
550
|
vfuncEntries,
|
|
474
551
|
vfuncMemberNames,
|
package/src/store/gi-store.ts
CHANGED
|
@@ -1,64 +1,59 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import type { SourceModule } from "../compile.js";
|
|
4
5
|
import { FINGERPRINT_FILENAME, type GiFingerprint } from "../fingerprint.js";
|
|
5
|
-
import { buildManifest, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
6
|
+
import { buildManifest, namespaceBarrel, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
6
7
|
|
|
7
8
|
type GiNamespaceInput = {
|
|
8
9
|
directory: string;
|
|
9
10
|
rawSource: string;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type CollectedFile = {
|
|
13
|
-
fileName: string;
|
|
14
|
-
source: string;
|
|
11
|
+
girFile: string;
|
|
15
12
|
};
|
|
16
13
|
|
|
17
14
|
const OVERRIDES_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "overrides");
|
|
18
15
|
|
|
19
|
-
const overrideFiles = (directory: string):
|
|
16
|
+
const overrideFiles = (directory: string): SourceModule[] => {
|
|
20
17
|
const dir = join(OVERRIDES_ROOT, directory);
|
|
21
18
|
|
|
22
19
|
if (!existsSync(dir)) {
|
|
23
20
|
return [];
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
return readdirSync(dir)
|
|
23
|
+
return readdirSync(dir)
|
|
24
|
+
.filter((name) => name.endsWith(".ejs") && name !== "index.ts.ejs")
|
|
25
|
+
.map((name) => overrideModule(`${directory}/overrides/${name.replace(/\.ejs$/, "")}`, join(dir, name)));
|
|
27
26
|
};
|
|
28
27
|
|
|
29
|
-
const
|
|
28
|
+
const overrideModule = (fileName: string, overridePath: string): SourceModule => ({
|
|
29
|
+
fileName,
|
|
30
|
+
source: readFileSync(overridePath, "utf8"),
|
|
31
|
+
origin: overridePath,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const barrelFile = (directory: string, girFile: string): SourceModule => {
|
|
35
|
+
const barrel = namespaceBarrel(directory);
|
|
30
36
|
const overrideIndex = join(OVERRIDES_ROOT, directory, "index.ts.ejs");
|
|
31
37
|
|
|
32
38
|
if (!existsSync(overrideIndex)) {
|
|
33
|
-
return
|
|
39
|
+
return { ...barrel, origin: girFile };
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
return
|
|
42
|
+
return overrideModule(barrel.fileName, overrideIndex);
|
|
37
43
|
};
|
|
38
44
|
|
|
39
45
|
const collectStoreSources = (
|
|
40
46
|
namespaces: GiNamespaceInput[],
|
|
41
|
-
): { collected:
|
|
47
|
+
): { collected: SourceModule[]; exportsMap: Record<string, unknown> } => {
|
|
42
48
|
const exportsMap: Record<string, unknown> = {};
|
|
43
|
-
const collected:
|
|
44
|
-
|
|
45
|
-
for (const { directory, rawSource } of namespaces) {
|
|
46
|
-
collected.push(
|
|
47
|
-
fileName: `${directory}/${directory}.ts`,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
for (const file of overrideFiles(directory)) {
|
|
52
|
-
collected.push({
|
|
53
|
-
fileName: `${directory}/overrides/${file.replace(/\.ejs$/, "")}`,
|
|
54
|
-
source: readFileSync(join(OVERRIDES_ROOT, directory, file), "utf8"),
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
collected.push({
|
|
59
|
-
fileName: `${directory}/index.ts`,
|
|
60
|
-
source: barrelSource(directory),
|
|
61
|
-
});
|
|
49
|
+
const collected: SourceModule[] = [];
|
|
50
|
+
|
|
51
|
+
for (const { directory, rawSource, girFile } of namespaces) {
|
|
52
|
+
collected.push(
|
|
53
|
+
{ fileName: `${directory}/${directory}.ts`, source: rawSource, origin: girFile },
|
|
54
|
+
...overrideFiles(directory),
|
|
55
|
+
barrelFile(directory, girFile),
|
|
56
|
+
);
|
|
62
57
|
|
|
63
58
|
exportsMap[`./${directory}`] = subpathExport(`${directory}/index`);
|
|
64
59
|
}
|