@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
package/src/store/gi/constant.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import { sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sanitizeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { GirConstant } from "../../gir/namespace.js";
|
|
3
3
|
import type { PrimitiveCategory } from "../../gir/primitives.js";
|
|
4
4
|
import type { TypeId } from "../../gir/type-id.js";
|
|
5
5
|
import type { ModuleContext } from "../../writer/context.js";
|
|
6
|
+
import { isEmittableEntity } from "../../gir/emittable.js";
|
|
6
7
|
import { getDoc } from "./doc-spec.js";
|
|
7
8
|
|
|
8
9
|
const TRUE_VALUES: Set<string> = new Set(["true", "1"]);
|
|
9
|
-
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["bigint64", "biguint64", "gtype"]);
|
|
10
|
+
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["bigint64", "biguint64", "gtype", "pointer"]);
|
|
10
11
|
|
|
11
12
|
const generateConstant = (context: ModuleContext, constant: GirConstant): void => {
|
|
13
|
+
if (!isEmittableEntity(constant)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
const doc = getDoc(constant);
|
|
13
|
-
|
|
18
|
+
const name = sanitizeIdentifier(constant.name);
|
|
19
|
+
|
|
20
|
+
context.declare({
|
|
21
|
+
name,
|
|
22
|
+
code: `${doc}export const ${name} = ${constantLiteral(context, constant)};`,
|
|
23
|
+
});
|
|
14
24
|
};
|
|
15
25
|
|
|
16
26
|
const constantLiteral = (context: ModuleContext, constant: GirConstant): string => {
|
|
@@ -96,7 +96,7 @@ const renderTranslatingConstructor = (context: ModuleContext, props: GirProperty
|
|
|
96
96
|
context.addRuntimeImport("t");
|
|
97
97
|
context.addRuntimeImport("registerConstructProperties");
|
|
98
98
|
const bindings = renderConstructBindings(context, props);
|
|
99
|
-
context.module.appendRegistration(`registerConstructProperties(${className}, ${bindings})
|
|
99
|
+
context.module.appendRegistration(`registerConstructProperties(${className}, ${bindings});`, [className]);
|
|
100
100
|
|
|
101
101
|
return renderBlock(`constructor(props: ${className}ConstructorProps = {})`, "super(props);");
|
|
102
102
|
};
|
package/src/store/gi/enum.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { escapeIdentifierStart, sanitizeTypeIdentifier, sourceStringLiteral, uniqBy } from "@gtkx/utils";
|
|
2
2
|
import type { EnumMember, GirEnum } from "../../gir/enum.js";
|
|
3
3
|
import type { ModuleContext } from "../../writer/context.js";
|
|
4
4
|
import { hasAnnotations } from "../../gir/annotations.js";
|
|
5
|
+
import { isEmittableEntity } from "../../gir/emittable.js";
|
|
5
6
|
import { indent } from "../../writer/emit.js";
|
|
6
7
|
import { getDoc } from "./doc-spec.js";
|
|
7
8
|
|
|
@@ -14,11 +15,17 @@ const enumDoc = (enumeration: GirEnum): string =>
|
|
|
14
15
|
getDoc(enumeration);
|
|
15
16
|
|
|
16
17
|
const generateEnum = (context: ModuleContext, enumeration: GirEnum): void => {
|
|
17
|
-
if (!enumeration
|
|
18
|
+
if (!isEmittableEntity(enumeration)) {
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const members =
|
|
22
|
+
const members = uniqBy(
|
|
23
|
+
enumeration.members
|
|
24
|
+
.map((member) => ({ ...member, key: enumMemberKey(member.name) }))
|
|
25
|
+
.filter((member) => member.key.length > 0),
|
|
26
|
+
(member) => member.key,
|
|
27
|
+
);
|
|
28
|
+
|
|
22
29
|
const errorDomain = enumeration.errorDomain;
|
|
23
30
|
|
|
24
31
|
if (errorDomain !== undefined) {
|
|
@@ -43,16 +50,20 @@ const appendErrorDomain = (
|
|
|
43
50
|
const quarkExpression = renderQuarkExpression(context, errorDomain);
|
|
44
51
|
const doc = enumDoc(enumeration);
|
|
45
52
|
const shape = typeFields.length === 0 ? "{}" : `{\n${indent(typeFields.join("\n"), 1)}\n}`;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const name = sanitizeTypeIdentifier(enumeration.name);
|
|
54
|
+
|
|
55
|
+
context.declare({
|
|
56
|
+
name,
|
|
57
|
+
code: `${doc}export type ${name} = number;`,
|
|
58
|
+
owner: enumeration.name,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
context.declare({
|
|
62
|
+
name,
|
|
63
|
+
code:
|
|
64
|
+
`${doc}export const ${name}: ErrorDomain<${shape}> = ` +
|
|
65
|
+
`createErrorDomain(${quarkExpression}, { ${memberEntries.join(", ")} });`,
|
|
66
|
+
});
|
|
56
67
|
};
|
|
57
68
|
|
|
58
69
|
const isMemberDocumented = (member: KeyedMember): boolean =>
|
|
@@ -60,31 +71,30 @@ const isMemberDocumented = (member: KeyedMember): boolean =>
|
|
|
60
71
|
|
|
61
72
|
const appendEnumDeclaration = (context: ModuleContext, enumeration: GirEnum, members: KeyedMember[]): void => {
|
|
62
73
|
const doc = enumDoc(enumeration);
|
|
74
|
+
const name = sanitizeTypeIdentifier(enumeration.name);
|
|
63
75
|
|
|
64
76
|
if (members.some((member) => isMemberDocumented(member))) {
|
|
65
77
|
const blocks = members.map((member) => `${memberDoc(member)}${member.key} = ${member.value},`);
|
|
66
78
|
|
|
67
|
-
context.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
context.declare({
|
|
80
|
+
name,
|
|
81
|
+
code: `${doc}export enum ${name} {\n${indent(blocks.join("\n"), 1)}\n}`,
|
|
82
|
+
owner: enumeration.name,
|
|
83
|
+
});
|
|
71
84
|
|
|
72
85
|
return;
|
|
73
86
|
}
|
|
74
87
|
|
|
75
88
|
const declarations = members.map((member) => `${member.key} = ${member.value}`);
|
|
76
89
|
|
|
77
|
-
context.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
context.declare({
|
|
91
|
+
name,
|
|
92
|
+
code: `${doc}export enum ${name} { ${declarations.join(", ")} }`,
|
|
93
|
+
owner: enumeration.name,
|
|
94
|
+
});
|
|
81
95
|
};
|
|
82
96
|
|
|
83
|
-
const enumMemberKey = (name: string): string =>
|
|
84
|
-
const upper = name.toUpperCase().replaceAll("-", "_");
|
|
85
|
-
|
|
86
|
-
return /^\d/.test(upper) ? `_${upper}` : upper;
|
|
87
|
-
};
|
|
97
|
+
const enumMemberKey = (name: string): string => escapeIdentifierStart(name.toUpperCase().replaceAll("-", "_"));
|
|
88
98
|
|
|
89
99
|
const renderQuarkExpression = (context: ModuleContext, errorDomain: string): string => {
|
|
90
100
|
if (context.namespace.name === "GLib") {
|
package/src/store/gi/function.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { toCamelIdentifier } from "@gtkx/utils";
|
|
2
2
|
import type { GirFunction } from "../../gir/function.js";
|
|
3
|
-
import type { GirNamespace } from "../../gir/namespace.js";
|
|
4
3
|
import type { ModuleContext } from "../../writer/context.js";
|
|
5
4
|
import { tFn } from "../../analysis/descriptor.js";
|
|
6
5
|
import { hasUnmarshalableParam } from "../../analysis/param-capability.js";
|
|
@@ -43,9 +42,14 @@ const renderFnExpression = (context: ModuleContext, fn: GirFunction): string | u
|
|
|
43
42
|
|
|
44
43
|
context.addRuntimeImport("t");
|
|
45
44
|
const params = planCallArgs(context, fn).map((arg) => arg.paramLiteral);
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
return tFn(library, fn.cIdentifier, {
|
|
45
|
+
const returnPlan = renderReturnDescriptor(context, fn);
|
|
46
|
+
|
|
47
|
+
return tFn(library, fn.cIdentifier, {
|
|
48
|
+
args: arrayLiteral(params),
|
|
49
|
+
returns: returnPlan.descriptor,
|
|
50
|
+
isReturnSkipped: returnPlan.isSkipped,
|
|
51
|
+
canThrow: fn.throws,
|
|
52
|
+
});
|
|
49
53
|
};
|
|
50
54
|
|
|
51
55
|
const isMovedOntoEmittedMember = (context: ModuleContext, fn: GirFunction): boolean => {
|
|
@@ -90,13 +94,25 @@ const generateNamespaceFunction = (context: ModuleContext, fn: GirFunction): voi
|
|
|
90
94
|
return;
|
|
91
95
|
}
|
|
92
96
|
|
|
93
|
-
const bindingName = toCamelIdentifier(cIdentifier);
|
|
94
|
-
context.module.appendBinding(`const ${bindingName} = ${expression};`, cIdentifier);
|
|
95
97
|
const exportName = namespaceFunctionExportName(cIdentifier, fn.name, context.namespace.cSymbolPrefixes);
|
|
98
|
+
|
|
99
|
+
if (exportName.length === 0) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const bindingName = namespaceBindingName(cIdentifier, exportName);
|
|
104
|
+
context.module.appendBinding(`const ${bindingName} = ${expression};`, cIdentifier);
|
|
96
105
|
const finish = matchNamespaceFinish(context, fn);
|
|
97
106
|
const declaration = renderNamespaceFunctionDeclaration({ context, fn, finish, exportName, bindingName });
|
|
98
107
|
const doc = callableDoc(context, fn, { finishFn: finish?.fn });
|
|
99
|
-
context.
|
|
108
|
+
context.declare({ name: exportName, code: `${doc}${declaration}` });
|
|
109
|
+
appendBootstrapRegistration(context, fn, exportName);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const namespaceBindingName = (cIdentifier: string, exportName: string): string => {
|
|
113
|
+
const bindingName = toCamelIdentifier(cIdentifier);
|
|
114
|
+
|
|
115
|
+
return bindingName === exportName ? `_${bindingName}` : bindingName;
|
|
100
116
|
};
|
|
101
117
|
|
|
102
118
|
const matchNamespaceFinish = (context: ModuleContext, fn: GirFunction): NamespaceFinish | undefined => {
|
|
@@ -159,31 +175,21 @@ const stripLongestPrefix = (input: string, prefixes: string[]): string => {
|
|
|
159
175
|
return best.length === 0 ? input : input.slice(best.length);
|
|
160
176
|
};
|
|
161
177
|
|
|
162
|
-
const isBootstrapFunction = (fn: GirFunction): boolean =>
|
|
163
|
-
fn.parameters.length === 0 && fn.introspectable && fn.shadowedBy === undefined && fn.cIdentifier !== undefined;
|
|
164
|
-
|
|
165
178
|
const appendBootstrapRegistration = (context: ModuleContext, fn: GirFunction, exportName: string): void => {
|
|
179
|
+
if (fn.parameters.length > 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
166
183
|
if (fn.name === "init") {
|
|
167
|
-
context.module.appendRegistration(`${exportName}()
|
|
184
|
+
context.module.appendRegistration(`${exportName}();`, [exportName]);
|
|
168
185
|
|
|
169
186
|
return;
|
|
170
187
|
}
|
|
171
188
|
|
|
172
189
|
if (fn.name === "finalize") {
|
|
173
190
|
context.addRuntimeImport("onExit");
|
|
174
|
-
context.module.appendRegistration(`onExit(${exportName})
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const generateNamespaceBootstrap = (context: ModuleContext, namespace: GirNamespace): void => {
|
|
179
|
-
for (const fn of namespace.functions) {
|
|
180
|
-
if (!isBootstrapFunction(fn) || fn.cIdentifier === undefined) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const exportName = namespaceFunctionExportName(fn.cIdentifier, fn.name, context.namespace.cSymbolPrefixes);
|
|
185
|
-
appendBootstrapRegistration(context, fn, exportName);
|
|
191
|
+
context.module.appendRegistration(`onExit(${exportName});`, [exportName]);
|
|
186
192
|
}
|
|
187
193
|
};
|
|
188
194
|
|
|
189
|
-
export { renderFnExpression, generateNamespaceFunction, namespaceFunctionExportName
|
|
195
|
+
export { renderFnExpression, generateNamespaceFunction, namespaceFunctionExportName };
|
|
@@ -24,9 +24,14 @@ const renderInternGtype = (context: ModuleContext, typeName: string | undefined)
|
|
|
24
24
|
return `typeFromName(${sourceStringLiteral(typeName)})`;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const renderResolveGtype = (context: ModuleContext, typeFnName: string): string => {
|
|
27
|
+
const renderResolveGtype = (context: ModuleContext, typeFnName: string): string | undefined => {
|
|
28
|
+
const lib = context.namespace.sharedLibrary;
|
|
29
|
+
|
|
30
|
+
if (lib === undefined) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
context.addRuntimeImport("resolveType");
|
|
29
|
-
const lib = context.namespace.sharedLibrary ?? "";
|
|
30
35
|
|
|
31
36
|
return `resolveType(${sourceStringLiteral(lib)}, ${sourceStringLiteral(typeFnName)})`;
|
|
32
37
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sanitizeTypeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { GirClass } from "../../gir/class.js";
|
|
3
3
|
import type { GirProperty } from "../../gir/property.js";
|
|
4
4
|
import type { ModuleContext } from "../../writer/context.js";
|
|
5
5
|
import { reservedSignalMemberRename, resolvePrerequisiteReference } from "../../analysis/inheritance.js";
|
|
6
|
-
import {
|
|
6
|
+
import { omittedTypeRef, prerequisiteConflicts } from "../../analysis/interface-conflicts.js";
|
|
7
|
+
import { resolveClassOrInterface, resolveInterfaces } from "../../gir/ancestry.js";
|
|
8
|
+
import { isEmittableEntity } from "../../gir/emittable.js";
|
|
7
9
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
8
10
|
import { renderBlock, renderBraced, renderBracedOrEmpty } from "../../writer/emit.js";
|
|
9
11
|
import {
|
|
@@ -72,15 +74,11 @@ const BRAND_NOTE = [
|
|
|
72
74
|
].join("\n");
|
|
73
75
|
|
|
74
76
|
const generateInterface = (context: ModuleContext, iface: GirClass): void => {
|
|
75
|
-
if (!iface
|
|
77
|
+
if (!isEmittableEntity(iface)) {
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const className = pascalCase(iface.name);
|
|
81
|
+
const className = sanitizeTypeIdentifier(iface.name);
|
|
84
82
|
|
|
85
83
|
const callables: Callables = {
|
|
86
84
|
constructors: dedupeCallables(iface.constructors),
|
|
@@ -92,13 +90,16 @@ const generateInterface = (context: ModuleContext, iface: GirClass): void => {
|
|
|
92
90
|
const gtypeExpr = renderSourceGtype(context, iface);
|
|
93
91
|
const implRef = appendInterfaceTypes(context, iface, className, callables) ?? "unknown";
|
|
94
92
|
const classCode = renderInterfaceClass(context, { iface, className, callables, gtypeExpr, implRef });
|
|
95
|
-
context.
|
|
93
|
+
context.declare({ name: className, code: classCode, owner: iface.name });
|
|
96
94
|
|
|
97
95
|
for (const declaration of renderSignalDeclarations(context, iface, className, true)) {
|
|
98
|
-
context.
|
|
96
|
+
context.declare(declaration);
|
|
99
97
|
}
|
|
100
98
|
|
|
101
|
-
context.
|
|
99
|
+
context.declare({
|
|
100
|
+
name: makerName(className),
|
|
101
|
+
code: renderInterfaceMaker(context, iface, className, callables),
|
|
102
|
+
});
|
|
102
103
|
|
|
103
104
|
appendInterfaceRegistration(context, {
|
|
104
105
|
className,
|
|
@@ -136,7 +137,7 @@ const renderInterfaceLayout = (
|
|
|
136
137
|
};
|
|
137
138
|
|
|
138
139
|
const invokerMembers = (context: ModuleContext, iface: GirClass, callables: Callables): Map<string, string> => {
|
|
139
|
-
const className =
|
|
140
|
+
const className = sanitizeTypeIdentifier(iface.name);
|
|
140
141
|
|
|
141
142
|
const invokers: Set<string> = new Set(
|
|
142
143
|
iface.vfuncs.map((vfunc) => vfunc.invoker).filter((invoker) => invoker !== undefined),
|
|
@@ -201,7 +202,7 @@ const appendInterfaceTypes = (
|
|
|
201
202
|
callables: Callables,
|
|
202
203
|
): string | undefined => {
|
|
203
204
|
const typeCode = renderInterfaceType(context, iface, className, callables);
|
|
204
|
-
context.
|
|
205
|
+
context.declare({ name: className, code: typeCode, owner: iface.name });
|
|
205
206
|
const implType = renderInterfaceImplType(context, iface, className);
|
|
206
207
|
|
|
207
208
|
if (implType === undefined) {
|
|
@@ -209,21 +210,39 @@ const appendInterfaceTypes = (
|
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
const implName = implTypeName(className);
|
|
212
|
-
context.
|
|
213
|
+
context.declare({ name: implName, code: implType, owner: iface.name });
|
|
213
214
|
|
|
214
215
|
return implName;
|
|
215
216
|
};
|
|
216
217
|
|
|
218
|
+
const prerequisiteRef = (context: ModuleContext, iface: GirClass, name: string): string | undefined => {
|
|
219
|
+
const ref = resolvePrerequisiteReference(context, name);
|
|
220
|
+
const base = resolveClassOrInterface(context.library, context.namespace.name, name);
|
|
221
|
+
|
|
222
|
+
if (ref === undefined || base === undefined) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return omittedTypeRef(ref, prerequisiteConflicts(context.library, iface, base));
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const rootPrerequisiteRef = (context: ModuleContext, iface: GirClass): string => {
|
|
230
|
+
const ref = context.qualify("GObject", "Object");
|
|
231
|
+
const base = resolveClassOrInterface(context.library, "GObject", "Object");
|
|
232
|
+
|
|
233
|
+
return base === undefined ? ref : omittedTypeRef(ref, prerequisiteConflicts(context.library, iface, base));
|
|
234
|
+
};
|
|
235
|
+
|
|
217
236
|
const interfaceTypeExtends = (context: ModuleContext, iface: GirClass): string => {
|
|
218
237
|
const refs = iface.prerequisites
|
|
219
|
-
.map((name) =>
|
|
238
|
+
.map((name) => prerequisiteRef(context, iface, name))
|
|
220
239
|
.filter((entry): entry is string => entry !== undefined);
|
|
221
240
|
|
|
222
241
|
if (refs.length > 0) {
|
|
223
242
|
return refs.join(", ");
|
|
224
243
|
}
|
|
225
244
|
|
|
226
|
-
return context
|
|
245
|
+
return rootPrerequisiteRef(context, iface);
|
|
227
246
|
};
|
|
228
247
|
|
|
229
248
|
const renderInterfaceType = (
|
|
@@ -264,7 +283,7 @@ const implPrerequisiteRefs = (context: ModuleContext, iface: GirClass): string[]
|
|
|
264
283
|
continue;
|
|
265
284
|
}
|
|
266
285
|
|
|
267
|
-
const name = implTypeName(
|
|
286
|
+
const name = implTypeName(sanitizeTypeIdentifier(prerequisite.klass.name));
|
|
268
287
|
refs.push(context.qualify(prerequisite.namespaceName, name));
|
|
269
288
|
}
|
|
270
289
|
|
|
@@ -317,11 +336,11 @@ const collectMethodMembers = (options: MethodMemberOptions): string[] => {
|
|
|
317
336
|
};
|
|
318
337
|
|
|
319
338
|
const collectPropertyMembers = (options: PropertyMemberOptions): string[] => {
|
|
320
|
-
const { context, iface,
|
|
339
|
+
const { context, iface, renderers, claimedNames } = options;
|
|
321
340
|
const members: string[] = [];
|
|
322
341
|
|
|
323
342
|
for (const property of iface.properties) {
|
|
324
|
-
const block = renderers.renderProperty({ context, property, claimedNames
|
|
343
|
+
const block = renderers.renderProperty({ context, property, claimedNames });
|
|
325
344
|
|
|
326
345
|
if (block !== undefined) {
|
|
327
346
|
members.push(block);
|
|
@@ -337,7 +356,7 @@ const renderInterfaceMembers = (
|
|
|
337
356
|
callables: Callables,
|
|
338
357
|
renderers: InterfaceMemberRenderers,
|
|
339
358
|
): string[] => {
|
|
340
|
-
const className =
|
|
359
|
+
const className = sanitizeTypeIdentifier(iface.name);
|
|
341
360
|
const scope = instanceScope(className, callables);
|
|
342
361
|
const claimedNames: Set<string> = new Set();
|
|
343
362
|
const methodMembers = collectMethodMembers({ context, className, scope, callables, renderers, claimedNames });
|
package/src/store/gi/method.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { camelCase, sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { camelCase, escapeIdentifierStart, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { GirFunction } from "../../gir/function.js";
|
|
3
3
|
import type { GirType } from "../../gir/type.js";
|
|
4
4
|
import type { ModuleContext } from "../../writer/context.js";
|
|
5
5
|
import {
|
|
6
|
+
isSkippedPrimaryReturn,
|
|
6
7
|
renderCallbackType,
|
|
7
8
|
renderDescriptor,
|
|
8
9
|
renderSelfDescriptor,
|
|
@@ -18,12 +19,18 @@ import {
|
|
|
18
19
|
inputParameters,
|
|
19
20
|
parameterIdentifier,
|
|
20
21
|
} from "../../analysis/param-structure.js";
|
|
21
|
-
import { renderTsType } from "../../analysis/ts-type.js";
|
|
22
|
+
import { renderParameterTsType, renderTsType } from "../../analysis/ts-type.js";
|
|
22
23
|
import { type GirParameter, isCallerAllocatedOut, isInoutParameter, isOutParameter } from "../../gir/parameter.js";
|
|
23
24
|
import { hasUnknownArrayLength, type TypeId } from "../../gir/type-id.js";
|
|
24
25
|
import { areClosuresInvoked } from "./closure-invocation.js";
|
|
25
26
|
import { itemComparatorArgDescriptors, itemComparatorTsType } from "./item-comparators.js";
|
|
26
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
isClosureType,
|
|
29
|
+
isCollectibleCallerOut,
|
|
30
|
+
isHandlePassedInPlace,
|
|
31
|
+
isHandlePassing,
|
|
32
|
+
renderCallerOutInstance,
|
|
33
|
+
} from "./param-marshal.js";
|
|
27
34
|
|
|
28
35
|
type PromisifiedStep = { hasSeenOptional: boolean; expression: string | undefined };
|
|
29
36
|
|
|
@@ -54,6 +61,11 @@ type CallArgPlan = {
|
|
|
54
61
|
inputExpr: string | undefined;
|
|
55
62
|
};
|
|
56
63
|
|
|
64
|
+
type ReturnDescriptorPlan = {
|
|
65
|
+
descriptor: string;
|
|
66
|
+
isSkipped: boolean;
|
|
67
|
+
};
|
|
68
|
+
|
|
57
69
|
type ParamDescriptorOptions = {
|
|
58
70
|
direction?: "out" | "inout";
|
|
59
71
|
isCallerAllocated?: boolean;
|
|
@@ -74,7 +86,8 @@ type PlanArgsContext = {
|
|
|
74
86
|
folded: Set<number>;
|
|
75
87
|
};
|
|
76
88
|
|
|
77
|
-
const
|
|
89
|
+
const memberName = (girName: string): string => escapeIdentifierStart(camelCase(girName));
|
|
90
|
+
const methodExportName = (fn: GirFunction): string => memberName(fn.name);
|
|
78
91
|
|
|
79
92
|
const arrayLengthArgument = (source: GirParameter, sourceIndex: number): string => {
|
|
80
93
|
const identifier = parameterIdentifier(source, sourceIndex);
|
|
@@ -107,7 +120,7 @@ const parameterAnnotation = (context: ModuleContext, fn: GirFunction, parameter:
|
|
|
107
120
|
return comparator;
|
|
108
121
|
}
|
|
109
122
|
|
|
110
|
-
const base =
|
|
123
|
+
const base = renderParameterTsType(context, parameter.type, parameter.nullable);
|
|
111
124
|
|
|
112
125
|
return requiresClosureAnnotation(context, fn, parameter) ? closureAnnotation(context, base) : base;
|
|
113
126
|
};
|
|
@@ -346,14 +359,16 @@ const paramDescriptorLiteral = (descriptor: string, options: ParamDescriptorOpti
|
|
|
346
359
|
return `{ ${parts.join(", ")} }`;
|
|
347
360
|
};
|
|
348
361
|
|
|
349
|
-
const renderReturnDescriptor = (context: ModuleContext, fn: GirFunction):
|
|
362
|
+
const renderReturnDescriptor = (context: ModuleContext, fn: GirFunction): ReturnDescriptorPlan => {
|
|
350
363
|
const instanceOffset = fn.instance === undefined ? 0 : 1;
|
|
351
364
|
|
|
352
|
-
|
|
365
|
+
const descriptor = renderDescriptor(context, fn.returnValue.type, fn.returnValue.transferOwnership, {
|
|
353
366
|
argIndexOffset: instanceOffset,
|
|
354
367
|
argIndexMap: emittedArgIndices(fn, instanceOffset),
|
|
355
368
|
isNewlyCreated: fn.instance === undefined,
|
|
356
369
|
});
|
|
370
|
+
|
|
371
|
+
return { descriptor, isSkipped: isSkippedPrimaryReturn(context.library, fn.returnValue) };
|
|
357
372
|
};
|
|
358
373
|
|
|
359
374
|
const planCallArgs = (context: ModuleContext, fn: GirFunction): CallArgPlan[] => {
|
|
@@ -473,6 +488,7 @@ const planOutParam = (
|
|
|
473
488
|
): CallArgPlan => {
|
|
474
489
|
const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, {
|
|
475
490
|
...argIndex,
|
|
491
|
+
cursor: parameter.cursor,
|
|
476
492
|
hasOutIndirection: true,
|
|
477
493
|
});
|
|
478
494
|
|
|
@@ -482,41 +498,19 @@ const planOutParam = (
|
|
|
482
498
|
};
|
|
483
499
|
};
|
|
484
500
|
|
|
485
|
-
const constructibleName = (
|
|
486
|
-
context: ModuleContext,
|
|
487
|
-
ref: GirParameter["type"],
|
|
488
|
-
): { namespaceName: string; typeName: string } | undefined => {
|
|
489
|
-
let current = ref;
|
|
490
|
-
|
|
491
|
-
while (current !== undefined) {
|
|
492
|
-
const resolved = context.library.typeFor(current);
|
|
493
|
-
|
|
494
|
-
if (resolved?.kind === "alias" && resolved.value.target !== undefined) {
|
|
495
|
-
current = resolved.value.target;
|
|
496
|
-
continue;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
return context.library.nameFor(current);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
return undefined;
|
|
503
|
-
};
|
|
504
|
-
|
|
505
501
|
const planCallerOut = (
|
|
506
502
|
context: ModuleContext,
|
|
507
503
|
parameter: GirParameter,
|
|
508
504
|
argIndex: ArgIndexOptions,
|
|
509
505
|
): CallArgPlan => {
|
|
510
506
|
const descriptor = renderDescriptor(context, parameter.type, "none", argIndex);
|
|
511
|
-
const name = constructibleName(context, parameter.type);
|
|
512
507
|
|
|
513
|
-
if (
|
|
508
|
+
if (isCollectibleCallerOut(context, parameter)) {
|
|
514
509
|
context.addRuntimeImport("getHandle");
|
|
515
|
-
const classExpression = context.qualify(name.namespaceName, name.typeName);
|
|
516
510
|
|
|
517
511
|
return {
|
|
518
512
|
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", isCallerAllocated: true }),
|
|
519
|
-
inputExpr:
|
|
513
|
+
inputExpr: renderCallerOutInstance(context, parameter),
|
|
520
514
|
};
|
|
521
515
|
}
|
|
522
516
|
|
|
@@ -678,8 +672,8 @@ const parameterCallExpression = (
|
|
|
678
672
|
};
|
|
679
673
|
|
|
680
674
|
export {
|
|
681
|
-
constructibleName,
|
|
682
675
|
isCallbackParameter,
|
|
676
|
+
memberName,
|
|
683
677
|
methodExportName,
|
|
684
678
|
renderMethodSignature,
|
|
685
679
|
renderMethodReturnType,
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { sanitizeTypeIdentifier } from "@gtkx/utils";
|
|
1
2
|
import type { TypeId } from "../../gir/type-id.js";
|
|
2
3
|
import type { GirType } from "../../gir/type.js";
|
|
3
4
|
import type { ModuleContext } from "../../writer/context.js";
|
|
4
5
|
import { type GirParameter, isInoutParameter } from "../../gir/parameter.js";
|
|
6
|
+
import { recordInlineSize } from "./record-layout.js";
|
|
7
|
+
import { isConstructibleRecord } from "./value-marshalable.js";
|
|
8
|
+
|
|
9
|
+
type TypeName = { namespaceName: string; typeName: string };
|
|
10
|
+
type CallerOutAllocation = TypeName & ({ strategy: "construct" } | { strategy: "allocate"; size: number });
|
|
5
11
|
|
|
6
12
|
const isHandlePassedInPlace = (context: ModuleContext, parameter: GirParameter): boolean => {
|
|
7
13
|
if (parameter.direction !== "out" && parameter.direction !== "inout") {
|
|
@@ -28,14 +34,78 @@ const underlyingType = (context: ModuleContext, ref: TypeId): GirType | undefine
|
|
|
28
34
|
const underlyingParamKind = (context: ModuleContext, parameter: GirParameter): GirType["kind"] | undefined =>
|
|
29
35
|
parameter.type === undefined ? undefined : underlyingType(context, parameter.type)?.kind;
|
|
30
36
|
|
|
31
|
-
const
|
|
32
|
-
|
|
37
|
+
const resolvedTypeName = (context: ModuleContext, ref: TypeId | undefined): TypeName | undefined => {
|
|
38
|
+
let current = ref;
|
|
39
|
+
|
|
40
|
+
while (current !== undefined) {
|
|
41
|
+
const resolved = context.library.typeFor(current);
|
|
42
|
+
|
|
43
|
+
if (resolved?.kind === "alias" && resolved.value.target !== undefined) {
|
|
44
|
+
current = resolved.value.target;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return context.library.nameFor(current);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return undefined;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const recordCallerOutAllocation = (
|
|
55
|
+
context: ModuleContext,
|
|
56
|
+
name: TypeName,
|
|
57
|
+
type: Extract<GirType, { kind: "record" }>,
|
|
58
|
+
): CallerOutAllocation | undefined => {
|
|
59
|
+
const size = recordInlineSize(context, type.value);
|
|
60
|
+
|
|
61
|
+
if (size === undefined) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return isConstructibleRecord(context, type.namespace.name, type.value)
|
|
66
|
+
? { ...name, strategy: "construct" }
|
|
67
|
+
: { ...name, strategy: "allocate", size };
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const callerOutAllocation = (context: ModuleContext, parameter: GirParameter): CallerOutAllocation | undefined => {
|
|
71
|
+
const name = resolvedTypeName(context, parameter.type);
|
|
72
|
+
const type = parameter.type === undefined ? undefined : underlyingType(context, parameter.type);
|
|
33
73
|
|
|
34
|
-
|
|
74
|
+
if (name === undefined || type === undefined) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (type.kind === "class") {
|
|
79
|
+
return { ...name, strategy: "construct" };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return type.kind === "record" ? recordCallerOutAllocation(context, name, type) : undefined;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const renderCallerOutInstance = (context: ModuleContext, parameter: GirParameter): string => {
|
|
86
|
+
const allocation = callerOutAllocation(context, parameter);
|
|
87
|
+
|
|
88
|
+
if (allocation === undefined) {
|
|
89
|
+
throw new Error("renderCallerOutInstance: expected a caller-allocated out-parameter with a known layout");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const classExpression = context.qualify(allocation.namespaceName, sanitizeTypeIdentifier(allocation.typeName));
|
|
93
|
+
|
|
94
|
+
if (allocation.strategy === "construct") {
|
|
95
|
+
return `new ${classExpression}()`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
context.addRuntimeImport("alloc");
|
|
99
|
+
context.addRuntimeImport("wrapHandle");
|
|
100
|
+
|
|
101
|
+
return `wrapHandle(alloc(${String(allocation.size)}), ${classExpression})`;
|
|
35
102
|
};
|
|
36
103
|
|
|
37
|
-
const
|
|
38
|
-
|
|
104
|
+
const isCollectibleCallerOut = (context: ModuleContext, parameter: GirParameter): boolean =>
|
|
105
|
+
callerOutAllocation(context, parameter) !== undefined;
|
|
106
|
+
|
|
107
|
+
const isAllocatableCallerOut = (context: ModuleContext, parameter: GirParameter): boolean =>
|
|
108
|
+
underlyingParamKind(context, parameter) === "record" && isCollectibleCallerOut(context, parameter);
|
|
39
109
|
|
|
40
110
|
const isRecordInout = (context: ModuleContext, parameter: GirParameter): boolean =>
|
|
41
111
|
isInoutParameter(parameter) && underlyingParamKind(context, parameter) === "record";
|
|
@@ -75,11 +145,12 @@ const isClosureType = (context: ModuleContext, ref: TypeId): boolean => {
|
|
|
75
145
|
};
|
|
76
146
|
|
|
77
147
|
export {
|
|
148
|
+
isAllocatableCallerOut,
|
|
78
149
|
isClosureType,
|
|
79
150
|
isHandlePassedInPlace,
|
|
80
151
|
isCollectibleCallerOut,
|
|
81
|
-
isRecordCallerOut,
|
|
82
152
|
isRecordInout,
|
|
83
153
|
isHandlePassing,
|
|
154
|
+
renderCallerOutInstance,
|
|
84
155
|
underlyingType,
|
|
85
156
|
};
|