@gtkx/codegen 1.0.0 → 1.1.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 +48 -31
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +16 -7
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +15 -3
- 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 +23 -0
- package/dist/analysis/interface-conflicts.d.ts.map +1 -0
- package/dist/analysis/interface-conflicts.js +144 -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.map +1 -1
- package/dist/analysis/ts-type.js +10 -17
- 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/compile.d.ts +12 -3
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +73 -24
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +10 -9
- 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.map +1 -1
- package/dist/docs/pipeline.js +85 -18
- 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 +9 -6
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +12 -1
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +44 -28
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +1 -0
- 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/library.js +1 -1
- 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 +3 -6
- package/dist/gir/parse.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/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/runner.d.ts +5 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +16 -0
- 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.map +1 -1
- package/dist/store/compile-store.js +4 -2
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts +7 -2
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +25 -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 +59 -38
- 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 +10 -2
- 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 +28 -8
- 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 +32 -17
- 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 -21
- 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 -5
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +95 -44
- 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 +31 -10
- 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 +5 -1
- 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/signal.d.ts +2 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +30 -24
- 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 -3
- 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 -6
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +59 -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 +7 -1
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +43 -1
- package/dist/xml.js.map +1 -1
- package/package.json +14 -3
- package/src/analysis/descriptor-render.ts +90 -45
- package/src/analysis/descriptor.ts +35 -8
- package/src/analysis/inheritance.ts +134 -44
- package/src/analysis/interface-conflicts.ts +237 -0
- package/src/analysis/param-capability.ts +3 -6
- package/src/analysis/param-structure.ts +2 -2
- package/src/analysis/ts-type.ts +13 -17
- package/src/analysis/type-key.ts +14 -0
- package/src/compile.ts +110 -26
- package/src/docs/api-reference.ts +10 -9
- package/src/docs/element-page.ts +5 -2
- package/src/docs/pipeline.ts +129 -19
- package/src/docs/render.ts +7 -3
- package/src/docs/symbol-page.ts +12 -7
- package/src/fingerprint.ts +86 -31
- package/src/gi.ts +1 -0
- 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/library.ts +1 -1
- package/src/gir/namespace.ts +8 -2
- package/src/gir/parameter.ts +15 -0
- package/src/gir/parse.ts +5 -7
- package/src/guards.ts +23 -0
- package/src/internal.ts +2 -0
- package/src/json.ts +11 -0
- 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/runner.ts +19 -1
- package/src/staging.ts +69 -0
- package/src/store/compile-store.ts +6 -4
- package/src/store/gi/callables.ts +41 -33
- package/src/store/gi/callback.ts +9 -9
- package/src/store/gi/class.ts +79 -48
- package/src/store/gi/companion.ts +7 -6
- package/src/store/gi/constant.ts +12 -2
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/enum.ts +35 -21
- package/src/store/gi/function.ts +30 -24
- package/src/store/gi/gtype-binding.ts +7 -2
- package/src/store/gi/interface.ts +37 -18
- package/src/store/gi/method.ts +28 -29
- 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 +156 -73
- package/src/store/gi/record-constructor.ts +50 -18
- package/src/store/gi/record-field-accessor.ts +8 -1
- 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/signal.ts +36 -38
- 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 -3
- package/src/store/resolve-store.ts +133 -18
- package/src/store/store-fs.ts +87 -34
- 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 +61 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GirClass } from "../../gir/class.js";
|
|
2
2
|
import type { ModuleContext } from "../../writer/context.js";
|
|
3
|
+
import type { Declaration } from "../../writer/module.js";
|
|
3
4
|
import { collectInterfaceProperties } from "../../analysis/inheritance.js";
|
|
4
5
|
import { renderBracedOrEmpty } from "../../writer/emit.js";
|
|
5
6
|
import { parentCompanionRef } from "./companion.js";
|
|
@@ -8,7 +9,7 @@ import { propertyDoc, type ResolvedAccessor, resolveOwnerAccessor } from "./prop
|
|
|
8
9
|
const PROPERTIES_SUFFIX = "Properties";
|
|
9
10
|
|
|
10
11
|
const propertyEntry = (accessor: ResolvedAccessor): string =>
|
|
11
|
-
`${propertyDoc(accessor.property)}${accessor.jsName}: ${accessor.
|
|
12
|
+
`${propertyDoc(accessor.property)}${accessor.jsName}: ${accessor.readType};`;
|
|
12
13
|
|
|
13
14
|
const interfaceEntries = (context: ModuleContext, klass: GirClass): string[] => {
|
|
14
15
|
const entries: string[] = [];
|
|
@@ -31,7 +32,7 @@ const renderPropertyDeclarations = (
|
|
|
31
32
|
klass: GirClass,
|
|
32
33
|
className: string,
|
|
33
34
|
accessors: ResolvedAccessor[],
|
|
34
|
-
):
|
|
35
|
+
): Declaration[] => {
|
|
35
36
|
const parentRef = parentCompanionRef(context, klass, PROPERTIES_SUFFIX);
|
|
36
37
|
const extendsClause = parentRef === undefined ? "" : ` extends ${parentRef}`;
|
|
37
38
|
|
|
@@ -43,8 +44,11 @@ const renderPropertyDeclarations = (
|
|
|
43
44
|
const map = `${className}${PROPERTIES_SUFFIX}`;
|
|
44
45
|
|
|
45
46
|
return [
|
|
46
|
-
renderBracedOrEmpty(`export interface ${map}${extendsClause}`, entries.join("\n")),
|
|
47
|
-
|
|
47
|
+
{ name: map, code: renderBracedOrEmpty(`export interface ${map}${extendsClause}`, entries.join("\n")) },
|
|
48
|
+
{
|
|
49
|
+
name: className,
|
|
50
|
+
code: renderBracedOrEmpty(`export interface ${className}`, `__properties__: ${map};`),
|
|
51
|
+
},
|
|
48
52
|
];
|
|
49
53
|
};
|
|
50
54
|
|
|
@@ -6,19 +6,30 @@ import { renderDescriptor } from "../../analysis/descriptor-render.js";
|
|
|
6
6
|
import { inputParameters } from "../../analysis/param-structure.js";
|
|
7
7
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
8
8
|
import { type GirProperty, isConstructableProperty } from "../../gir/property.js";
|
|
9
|
+
import { comparisonContextFor } from "../../writer/comparison-context.js";
|
|
9
10
|
import { renderBlock } from "../../writer/emit.js";
|
|
10
11
|
import { isEmittableCallable } from "./callables.js";
|
|
11
12
|
import { getDoc } from "./doc-spec.js";
|
|
12
13
|
import { methodExportName, renderMethodReturnType } from "./method.js";
|
|
13
14
|
|
|
15
|
+
type AccessorTypes = {
|
|
16
|
+
readType: string;
|
|
17
|
+
writeType: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type InheritedAccessorTypes = {
|
|
21
|
+
readType: string | undefined;
|
|
22
|
+
writeType: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
|
|
14
25
|
type ResolvedAccessor = {
|
|
15
26
|
property: GirProperty;
|
|
16
27
|
jsName: string;
|
|
17
|
-
|
|
28
|
+
readType: string;
|
|
29
|
+
writeType: string;
|
|
18
30
|
hasGetter: boolean;
|
|
19
31
|
isWritable: boolean;
|
|
20
32
|
getterMember: string | undefined;
|
|
21
|
-
getterMethod: GirFunction | undefined;
|
|
22
33
|
setterMember: string | undefined;
|
|
23
34
|
};
|
|
24
35
|
|
|
@@ -27,18 +38,15 @@ type PropertyAccessorArgs = {
|
|
|
27
38
|
property: GirProperty;
|
|
28
39
|
claimedNames: Set<string>;
|
|
29
40
|
methodByName: Map<string, GirFunction>;
|
|
30
|
-
|
|
41
|
+
inheritedTypes?: InheritedAccessorTypes | undefined;
|
|
42
|
+
inheritedNames?: Set<string> | undefined;
|
|
31
43
|
};
|
|
32
44
|
|
|
33
|
-
type AccessorDelegate = { member: string
|
|
45
|
+
type AccessorDelegate = { member: string; method: GirFunction };
|
|
46
|
+
type AccessorDelegates = { getter: AccessorDelegate | undefined; setter: AccessorDelegate | undefined };
|
|
47
|
+
type TypedDelegates = { types: AccessorTypes; delegates: AccessorDelegates };
|
|
34
48
|
|
|
35
|
-
|
|
36
|
-
context: ModuleContext;
|
|
37
|
-
property: GirProperty;
|
|
38
|
-
getterMember: string | undefined;
|
|
39
|
-
getterMethod: GirFunction | undefined;
|
|
40
|
-
tsType: string;
|
|
41
|
-
};
|
|
49
|
+
const NULLABLE_SUFFIX = " | null";
|
|
42
50
|
|
|
43
51
|
const isNullablePropertyType = (context: ModuleContext, type: TypeId | undefined): boolean => {
|
|
44
52
|
if (type === undefined) {
|
|
@@ -71,14 +79,17 @@ const resolveDelegate = (
|
|
|
71
79
|
attribute: string | undefined,
|
|
72
80
|
member: string | undefined,
|
|
73
81
|
isDelegatable: (method: GirFunction) => boolean,
|
|
74
|
-
): AccessorDelegate => {
|
|
82
|
+
): AccessorDelegate | undefined => {
|
|
75
83
|
const method = member !== undefined && attribute !== undefined ? args.methodByName.get(attribute) : undefined;
|
|
76
|
-
const canDelegate = method === undefined || isDelegatable(method);
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
if (member === undefined || method === undefined || !isDelegatable(method)) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { member, method };
|
|
79
90
|
};
|
|
80
91
|
|
|
81
|
-
const resolveGetterDelegate = (args: PropertyAccessorArgs, jsName: string): AccessorDelegate => {
|
|
92
|
+
const resolveGetterDelegate = (args: PropertyAccessorArgs, jsName: string): AccessorDelegate | undefined => {
|
|
82
93
|
const { context, property, claimedNames } = args;
|
|
83
94
|
const member = delegateMember(property.getter, jsName, claimedNames);
|
|
84
95
|
|
|
@@ -92,7 +103,11 @@ const resolveGetterDelegate = (args: PropertyAccessorArgs, jsName: string): Acce
|
|
|
92
103
|
);
|
|
93
104
|
};
|
|
94
105
|
|
|
95
|
-
const resolveSetterDelegate = (
|
|
106
|
+
const resolveSetterDelegate = (
|
|
107
|
+
args: PropertyAccessorArgs,
|
|
108
|
+
jsName: string,
|
|
109
|
+
isWritable: boolean,
|
|
110
|
+
): AccessorDelegate | undefined => {
|
|
96
111
|
const { context, property, claimedNames } = args;
|
|
97
112
|
const member = isWritable ? delegateMember(property.setter, jsName, claimedNames) : undefined;
|
|
98
113
|
|
|
@@ -104,52 +119,114 @@ const resolveSetterDelegate = (args: PropertyAccessorArgs, jsName: string, isWri
|
|
|
104
119
|
);
|
|
105
120
|
};
|
|
106
121
|
|
|
107
|
-
const
|
|
122
|
+
const baseTypeName = (type: string): string =>
|
|
123
|
+
type.endsWith(NULLABLE_SUFFIX) ? type.slice(0, -NULLABLE_SUFFIX.length) : type;
|
|
124
|
+
|
|
125
|
+
const areDelegateBaseTypesAgreeing = (
|
|
108
126
|
context: ModuleContext,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const setterParam = setterMethod?.parameters[0];
|
|
127
|
+
getter: AccessorDelegate | undefined,
|
|
128
|
+
setter: AccessorDelegate | undefined,
|
|
129
|
+
): boolean => {
|
|
130
|
+
const setterParam = setter?.method.parameters[0];
|
|
114
131
|
|
|
115
|
-
if (setterParam
|
|
116
|
-
return
|
|
132
|
+
if (setterParam === undefined || getter === undefined) {
|
|
133
|
+
return true;
|
|
117
134
|
}
|
|
118
135
|
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
const scratch = comparisonContextFor(context);
|
|
137
|
+
const read = baseTypeName(renderMethodReturnType(scratch, getter.method));
|
|
138
|
+
const written = baseTypeName(renderTsType(scratch, setterParam.type, false));
|
|
139
|
+
|
|
140
|
+
return read === written;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const resolveDelegates = (args: PropertyAccessorArgs, jsName: string, isWritable: boolean): AccessorDelegates => {
|
|
144
|
+
const getter = resolveGetterDelegate(args, jsName);
|
|
145
|
+
const setter = resolveSetterDelegate(args, jsName, isWritable);
|
|
146
|
+
|
|
147
|
+
if (areDelegateBaseTypesAgreeing(args.context, getter, setter)) {
|
|
148
|
+
return { getter, setter };
|
|
121
149
|
}
|
|
122
150
|
|
|
123
|
-
return
|
|
151
|
+
return { getter, setter: undefined };
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const declaredPropertyType = (context: ModuleContext, property: GirProperty): string =>
|
|
155
|
+
renderTsType(context, property.type, isNullablePropertyType(context, property.type));
|
|
156
|
+
|
|
157
|
+
const resolveOwnTypes = (
|
|
158
|
+
context: ModuleContext,
|
|
159
|
+
property: GirProperty,
|
|
160
|
+
delegates: AccessorDelegates,
|
|
161
|
+
): AccessorTypes => {
|
|
162
|
+
const getterMethod = delegates.getter?.method;
|
|
163
|
+
const setterParam = delegates.setter?.method.parameters[0];
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
readType: getterMethod === undefined
|
|
167
|
+
? declaredPropertyType(context, property)
|
|
168
|
+
: renderMethodReturnType(context, getterMethod),
|
|
169
|
+
writeType: setterParam === undefined
|
|
170
|
+
? declaredPropertyType(context, property)
|
|
171
|
+
: renderTsType(context, setterParam.type, setterParam.nullable || setterParam.optional),
|
|
172
|
+
};
|
|
124
173
|
};
|
|
125
174
|
|
|
126
|
-
const
|
|
127
|
-
|
|
175
|
+
const isAssignableType = (source: string, target: string): boolean =>
|
|
176
|
+
source === target || baseTypeName(target) === source;
|
|
128
177
|
|
|
129
|
-
const
|
|
130
|
-
|
|
178
|
+
const agreeingDelegates = (
|
|
179
|
+
delegates: AccessorDelegates,
|
|
180
|
+
ownTypes: AccessorTypes,
|
|
181
|
+
declaredTypes: AccessorTypes,
|
|
182
|
+
): AccessorDelegates => ({
|
|
183
|
+
getter: isAssignableType(ownTypes.readType, declaredTypes.readType) ? delegates.getter : undefined,
|
|
184
|
+
setter: isAssignableType(declaredTypes.writeType, ownTypes.writeType) ? delegates.setter : undefined,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const resolveTypedDelegates = (args: PropertyAccessorArgs, resolved: AccessorDelegates): TypedDelegates => {
|
|
188
|
+
const ownTypes = resolveOwnTypes(args.context, args.property, resolved);
|
|
189
|
+
|
|
190
|
+
const types = {
|
|
191
|
+
readType: args.inheritedTypes?.readType ?? ownTypes.readType,
|
|
192
|
+
writeType: args.inheritedTypes?.writeType ?? ownTypes.writeType,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return { types, delegates: agreeingDelegates(resolved, ownTypes, types) };
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const isSkippedAccessor = (args: PropertyAccessorArgs, jsName: string): boolean =>
|
|
199
|
+
!args.property.introspectable ||
|
|
200
|
+
args.claimedNames.has(jsName) ||
|
|
201
|
+
args.inheritedNames?.has(jsName) === true ||
|
|
202
|
+
jsName === "constructor";
|
|
131
203
|
|
|
132
204
|
const resolveAccessor = (args: PropertyAccessorArgs): ResolvedAccessor | undefined => {
|
|
133
|
-
const {
|
|
205
|
+
const { property } = args;
|
|
134
206
|
const jsName = toCamelIdentifier(property.name);
|
|
135
207
|
|
|
136
|
-
if (isSkippedAccessor(
|
|
208
|
+
if (isSkippedAccessor(args, jsName)) {
|
|
137
209
|
return undefined;
|
|
138
210
|
}
|
|
139
211
|
|
|
140
212
|
const isWritable = isConstructableProperty(property) && !property.constructOnly;
|
|
141
|
-
const {
|
|
142
|
-
const
|
|
143
|
-
const hasGetter = property.readable || getterMember !== undefined;
|
|
213
|
+
const { types, delegates } = resolveTypedDelegates(args, resolveDelegates(args, jsName, isWritable));
|
|
214
|
+
const hasGetter = property.readable || delegates.getter !== undefined;
|
|
144
215
|
|
|
145
216
|
if (!hasGetter && !isWritable) {
|
|
146
217
|
return undefined;
|
|
147
218
|
}
|
|
148
219
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
220
|
+
return {
|
|
221
|
+
property,
|
|
222
|
+
jsName,
|
|
223
|
+
readType: types.readType,
|
|
224
|
+
writeType: types.writeType,
|
|
225
|
+
hasGetter,
|
|
226
|
+
isWritable,
|
|
227
|
+
getterMember: delegates.getter?.member,
|
|
228
|
+
setterMember: delegates.setter?.member,
|
|
229
|
+
};
|
|
153
230
|
};
|
|
154
231
|
|
|
155
232
|
const resolveOwnerAccessor = (
|
|
@@ -172,11 +249,22 @@ const resolveOwnerAccessor = (
|
|
|
172
249
|
return resolveAccessor({ context, property, claimedNames, methodByName });
|
|
173
250
|
};
|
|
174
251
|
|
|
175
|
-
const
|
|
252
|
+
const resolveAccessorTypes = (
|
|
176
253
|
context: ModuleContext,
|
|
177
254
|
property: GirProperty,
|
|
178
255
|
methods: GirFunction[],
|
|
179
|
-
):
|
|
256
|
+
): InheritedAccessorTypes | undefined => {
|
|
257
|
+
const accessor = resolveOwnerAccessor(context, property, methods);
|
|
258
|
+
|
|
259
|
+
if (accessor === undefined) {
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
readType: accessor.hasGetter ? accessor.readType : undefined,
|
|
265
|
+
writeType: accessor.isWritable ? accessor.writeType : undefined,
|
|
266
|
+
};
|
|
267
|
+
};
|
|
180
268
|
|
|
181
269
|
const withAccessor = (
|
|
182
270
|
args: PropertyAccessorArgs,
|
|
@@ -196,19 +284,18 @@ const renderResolvedPropertyAccessor = (
|
|
|
196
284
|
property: GirProperty,
|
|
197
285
|
accessor: ResolvedAccessor,
|
|
198
286
|
): string => {
|
|
199
|
-
const { jsName,
|
|
287
|
+
const { jsName, readType, writeType, hasGetter, isWritable, setterMember } = accessor;
|
|
200
288
|
const blocks: string[] = [];
|
|
201
289
|
|
|
202
290
|
if (hasGetter) {
|
|
203
|
-
|
|
204
|
-
blocks.push(renderBlock(`get ${jsName}(): ${tsType}`, getterBody));
|
|
291
|
+
blocks.push(renderBlock(`get ${jsName}(): ${readType}`, renderGetterBody(context, property, accessor)));
|
|
205
292
|
}
|
|
206
293
|
|
|
207
294
|
if (isWritable) {
|
|
208
295
|
const setterBody =
|
|
209
296
|
setterMember === undefined ? renderGenericSetBody(context, property) : `this.${setterMember}(value);`;
|
|
210
297
|
|
|
211
|
-
blocks.push(renderBlock(`set ${jsName}(value: ${
|
|
298
|
+
blocks.push(renderBlock(`set ${jsName}(value: ${writeType})`, setterBody));
|
|
212
299
|
}
|
|
213
300
|
|
|
214
301
|
return `${propertyDoc(property)}${blocks.join("\n\n")}`;
|
|
@@ -220,20 +307,26 @@ const propertyDoc = (property: GirProperty): string =>
|
|
|
220
307
|
const renderPropertyAccessor = (args: PropertyAccessorArgs): string | undefined =>
|
|
221
308
|
withAccessor(args, (accessor) => renderResolvedPropertyAccessor(args.context, args.property, accessor));
|
|
222
309
|
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
const doc = propertyDoc(args.property);
|
|
310
|
+
const renderAccessorPairSignature = (accessor: ResolvedAccessor): string => {
|
|
311
|
+
const { jsName, readType, writeType, hasGetter, isWritable } = accessor;
|
|
226
312
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
313
|
+
if (!hasGetter) {
|
|
314
|
+
return `set ${jsName}(value: ${writeType});`;
|
|
315
|
+
}
|
|
230
316
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
317
|
+
if (!isWritable) {
|
|
318
|
+
return `get ${jsName}(): ${readType};`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (readType === writeType) {
|
|
322
|
+
return `${jsName}: ${readType};`;
|
|
323
|
+
}
|
|
234
324
|
|
|
235
|
-
|
|
236
|
-
|
|
325
|
+
return `get ${jsName}(): ${readType};\nset ${jsName}(value: ${writeType});`;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const renderPropertyAccessorSignature = (args: PropertyAccessorArgs): string | undefined =>
|
|
329
|
+
withAccessor(args, (accessor) => `${propertyDoc(args.property)}${renderAccessorPairSignature(accessor)}`);
|
|
237
330
|
|
|
238
331
|
const renderPropertyDescriptor = (context: ModuleContext, property: GirProperty): string =>
|
|
239
332
|
renderDescriptor(context, property.type, property.transferOwnership);
|
|
@@ -254,21 +347,10 @@ const renderGenericSetBody = (context: ModuleContext, property: GirProperty): st
|
|
|
254
347
|
return `setObjectProperty(this, ${sourceStringLiteral(property.name)}, ${descriptor}, value);`;
|
|
255
348
|
};
|
|
256
349
|
|
|
257
|
-
const renderGetterBody = (
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return renderGenericGetBody(context, property, tsType);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (getterMethod === undefined) {
|
|
265
|
-
return `return this.${getterMember}() as ${tsType};`;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const getterType = renderMethodReturnType(context, getterMethod);
|
|
269
|
-
|
|
270
|
-
return getterType === tsType ? `return this.${getterMember}();` : `return this.${getterMember}() as ${tsType};`;
|
|
271
|
-
};
|
|
350
|
+
const renderGetterBody = (context: ModuleContext, property: GirProperty, accessor: ResolvedAccessor): string =>
|
|
351
|
+
accessor.getterMember === undefined
|
|
352
|
+
? renderGenericGetBody(context, property, accessor.readType)
|
|
353
|
+
: `return this.${accessor.getterMember}();`;
|
|
272
354
|
|
|
273
355
|
const delegateMember = (
|
|
274
356
|
attribute: string | undefined,
|
|
@@ -296,10 +378,11 @@ export {
|
|
|
296
378
|
propertyDoc,
|
|
297
379
|
resolveAccessor,
|
|
298
380
|
resolveOwnerAccessor,
|
|
299
|
-
|
|
381
|
+
resolveAccessorTypes,
|
|
300
382
|
renderResolvedPropertyAccessor,
|
|
301
383
|
renderPropertyAccessor,
|
|
302
384
|
renderPropertyAccessorSignature,
|
|
385
|
+
type InheritedAccessorTypes,
|
|
303
386
|
type ResolvedAccessor,
|
|
304
387
|
type PropertyAccessorArgs,
|
|
305
388
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { sourceStringLiteral, toCamelIdentifier } from "@gtkx/utils";
|
|
2
2
|
import type { GirField } from "../../gir/field.js";
|
|
3
|
+
import type { GirFunction } from "../../gir/function.js";
|
|
3
4
|
import type { GirRecord } from "../../gir/record.js";
|
|
4
5
|
import type { TypeId } from "../../gir/type-id.js";
|
|
5
6
|
import type { ModuleContext } from "../../writer/context.js";
|
|
6
7
|
import { renderDescriptor } from "../../analysis/descriptor-render.js";
|
|
8
|
+
import { inputParameters, parameterIdentifier } from "../../analysis/param-structure.js";
|
|
7
9
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
8
10
|
import { renderBlock, renderBracedOrEmpty } from "../../writer/emit.js";
|
|
11
|
+
import { type Callables, staticMembers } from "./callables.js";
|
|
9
12
|
import { getDoc } from "./doc-spec.js";
|
|
10
13
|
import { renderSourceGtype } from "./gtype-binding.js";
|
|
11
14
|
import { emitFieldWrite, isEmittableField, isInlineField } from "./record-field-accessor.js";
|
|
@@ -14,22 +17,22 @@ import { isConstructibleRecord } from "./value-marshalable.js";
|
|
|
14
17
|
|
|
15
18
|
type WritableFieldSlot = RecordFieldSlot & { field: GirField & { type: TypeId } };
|
|
16
19
|
|
|
20
|
+
type RecordConstructorSpec = {
|
|
21
|
+
record: GirRecord;
|
|
22
|
+
className: string;
|
|
23
|
+
callables: Callables;
|
|
24
|
+
isErrorSubclass: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
17
27
|
const isWritableFieldSlot = (context: ModuleContext, entry: RecordFieldSlot): entry is WritableFieldSlot =>
|
|
18
28
|
entry.field.writable && isEmittableField(context, entry.field);
|
|
19
29
|
|
|
20
|
-
const isOpaque = (record: GirRecord): boolean => record.opaque || record.disguised;
|
|
21
|
-
|
|
22
30
|
const renderRecordConstructorPropsInterface = (
|
|
23
31
|
context: ModuleContext,
|
|
24
32
|
record: GirRecord,
|
|
25
33
|
className: string,
|
|
26
34
|
): string => {
|
|
27
35
|
const head = `export interface ${className}ConstructorProps`;
|
|
28
|
-
|
|
29
|
-
if (isOpaque(record) || !isConstructibleRecord(context, context.namespace.name, record)) {
|
|
30
|
-
return renderBracedOrEmpty(head, "");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
36
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
34
37
|
|
|
35
38
|
const lines = slots
|
|
@@ -43,8 +46,41 @@ const renderRecordConstructorPropsInterface = (
|
|
|
43
46
|
return renderBracedOrEmpty(head, lines.join("\n"));
|
|
44
47
|
};
|
|
45
48
|
|
|
46
|
-
const
|
|
47
|
-
const
|
|
49
|
+
const isSelfReturning = (context: ModuleContext, record: GirRecord, callable: GirFunction): boolean => {
|
|
50
|
+
const ref = callable.returnValue.type;
|
|
51
|
+
const name = ref === undefined ? undefined : context.library.nameFor(ref);
|
|
52
|
+
|
|
53
|
+
return name?.namespaceName === context.namespace.name && name.typeName === record.name;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const renderStaticCall = (context: ModuleContext, callable: GirFunction, name: string): string => {
|
|
57
|
+
const args = inputParameters(context.library, callable).map(({ parameter, index }) =>
|
|
58
|
+
parameterIdentifier(parameter, index));
|
|
59
|
+
|
|
60
|
+
return `${name}(${args.join(", ")})`;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const constructionHint = (context: ModuleContext, spec: RecordConstructorSpec): string | undefined => {
|
|
64
|
+
const candidates = staticMembers(context, spec.callables).filter(({ callable }) =>
|
|
65
|
+
isSelfReturning(context, spec.record, callable));
|
|
66
|
+
|
|
67
|
+
const candidate = candidates.find(({ name }) => name === "new") ?? candidates[0];
|
|
68
|
+
|
|
69
|
+
return candidate === undefined ? undefined : renderStaticCall(context, candidate.callable, candidate.name);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const unconstructibleMessage = (context: ModuleContext, spec: RecordConstructorSpec): string => {
|
|
73
|
+
const qualified = `${context.namespace.name}.${spec.className}`;
|
|
74
|
+
const hint = constructionHint(context, spec);
|
|
75
|
+
|
|
76
|
+
return hint === undefined
|
|
77
|
+
? `Cannot construct ${qualified} with new: its instances come from the functions that return them.`
|
|
78
|
+
: `Cannot construct ${qualified} with new: use ${qualified}.${hint} instead.`;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const renderUnconstructibleGuard = (context: ModuleContext, spec: RecordConstructorSpec): string => {
|
|
82
|
+
const superCall = spec.isErrorSubclass ? ["super();"] : [];
|
|
83
|
+
const message = sourceStringLiteral(unconstructibleMessage(context, spec));
|
|
48
84
|
|
|
49
85
|
return renderBlock("constructor()", [...superCall, `throw new globalThis.Error(${message});`].join("\n"));
|
|
50
86
|
};
|
|
@@ -66,18 +102,14 @@ const renderFieldWrites = (context: ModuleContext, slots: RecordFieldSlot[]): st
|
|
|
66
102
|
return statements;
|
|
67
103
|
};
|
|
68
104
|
|
|
69
|
-
const renderRecordConstructor = (
|
|
70
|
-
|
|
71
|
-
record: GirRecord,
|
|
72
|
-
className: string,
|
|
73
|
-
isErrorSubclass = false,
|
|
74
|
-
): string => {
|
|
75
|
-
const superCall = isErrorSubclass ? ["super();"] : [];
|
|
105
|
+
const renderRecordConstructor = (context: ModuleContext, spec: RecordConstructorSpec): string => {
|
|
106
|
+
const { record, className, isErrorSubclass } = spec;
|
|
76
107
|
|
|
77
|
-
if (
|
|
78
|
-
return
|
|
108
|
+
if (!isConstructibleRecord(context, context.namespace.name, record)) {
|
|
109
|
+
return renderUnconstructibleGuard(context, spec);
|
|
79
110
|
}
|
|
80
111
|
|
|
112
|
+
const superCall = isErrorSubclass ? ["super();"] : [];
|
|
81
113
|
const { slots, size } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
82
114
|
|
|
83
115
|
if (size === 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 { GirRecord } from "../../gir/record.js";
|
|
4
5
|
import type { FieldSlot } from "../../gir/size.js";
|
|
5
6
|
import type { TypeId } from "../../gir/type-id.js";
|
|
6
7
|
import type { GirType } from "../../gir/type.js";
|
|
@@ -479,6 +480,12 @@ const structArraySetterBlock = (options: StructArrayAccessorOptions): string =>
|
|
|
479
480
|
structArraySetterStatements(options.context, options),
|
|
480
481
|
);
|
|
481
482
|
|
|
483
|
+
const isPlainDataRecord = (record: GirRecord): boolean =>
|
|
484
|
+
record.glibGetType === undefined &&
|
|
485
|
+
record.constructors.length === 0 &&
|
|
486
|
+
record.functions.length === 0 &&
|
|
487
|
+
record.methods.length === 0;
|
|
488
|
+
|
|
482
489
|
const resolveStructArrayElements = (context: ModuleContext, fieldType: TypeId): StructArrayElements | undefined => {
|
|
483
490
|
const arrayType = context.library.typeFor(fieldType);
|
|
484
491
|
|
|
@@ -488,7 +495,7 @@ const resolveStructArrayElements = (context: ModuleContext, fieldType: TypeId):
|
|
|
488
495
|
|
|
489
496
|
const elementType = context.library.typeFor(arrayType.element);
|
|
490
497
|
|
|
491
|
-
if (elementType?.kind === "record" && elementType.value
|
|
498
|
+
if (elementType?.kind === "record" && !isPlainDataRecord(elementType.value)) {
|
|
492
499
|
return undefined;
|
|
493
500
|
}
|
|
494
501
|
|
|
@@ -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 };
|