@gtkx/codegen 1.0.0-rc.3 → 1.0.0-rc.4
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 +4 -5
- package/dist/analysis/descriptor-render.d.ts +1 -3
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +14 -37
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +6 -6
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +7 -7
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/param-structure.d.ts +2 -2
- package/dist/analysis/param-structure.d.ts.map +1 -1
- package/dist/analysis/param-structure.js +5 -7
- package/dist/analysis/param-structure.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +1 -1
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +3 -5
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +2 -1
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +77 -1
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +62 -0
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/pipeline.d.ts +4 -4
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +4 -4
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/docs/render.js +6 -6
- package/dist/docs/render.js.map +1 -1
- package/dist/docs/symbol-page.d.ts +5 -0
- package/dist/docs/symbol-page.d.ts.map +1 -1
- package/dist/docs/symbol-page.js +2 -2
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +2 -5
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +6 -8
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +3 -11
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +0 -7
- package/dist/gi.js.map +1 -1
- package/dist/gir/field.d.ts +0 -1
- package/dist/gir/field.d.ts.map +1 -1
- package/dist/gir/field.js +0 -3
- package/dist/gir/field.js.map +1 -1
- package/dist/gir/gir-path.d.ts +7 -0
- package/dist/gir/gir-path.d.ts.map +1 -1
- package/dist/gir/gir-path.js +7 -0
- package/dist/gir/gir-path.js.map +1 -1
- package/dist/gir/libraries.d.ts +13 -0
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +12 -0
- package/dist/gir/libraries.js.map +1 -1
- package/dist/gir/parameter.d.ts.map +1 -1
- package/dist/gir/parameter.js +0 -4
- package/dist/gir/parameter.js.map +1 -1
- package/dist/gir/size.d.ts.map +1 -1
- package/dist/gir/size.js +0 -3
- package/dist/gir/size.js.map +1 -1
- package/dist/gir/type-id.d.ts +1 -1
- package/dist/gir/type-id.d.ts.map +1 -1
- package/dist/gir/type-id.js +1 -3
- package/dist/gir/type-id.js.map +1 -1
- package/dist/gir/type-ref.js +1 -1
- package/dist/gir/type-ref.js.map +1 -1
- package/dist/index.d.ts +18 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -0
- package/dist/jsx.d.ts +7 -12
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +18 -19
- package/dist/jsx.js.map +1 -1
- package/dist/khronos/args.d.ts.map +1 -1
- package/dist/khronos/args.js +1 -1
- package/dist/khronos/args.js.map +1 -1
- package/dist/khronos/pipeline.js +1 -1
- package/dist/khronos/pipeline.js.map +1 -1
- package/dist/khronos/plan.d.ts +2 -2
- package/dist/khronos/plan.d.ts.map +1 -1
- package/dist/khronos/plan.js +6 -6
- package/dist/khronos/plan.js.map +1 -1
- package/dist/react/element-config.d.ts +17 -11
- package/dist/react/element-config.d.ts.map +1 -1
- package/dist/react/element-config.js +22 -15
- package/dist/react/element-config.js.map +1 -1
- package/dist/runner.d.ts +35 -17
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +19 -20
- package/dist/runner.js.map +1 -1
- package/dist/store/compile-store.d.ts +1 -2
- package/dist/store/compile-store.d.ts.map +1 -1
- package/dist/store/compile-store.js +2 -2
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.js +4 -4
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/constant.d.ts.map +1 -1
- package/dist/store/gi/constant.js +0 -2
- package/dist/store/gi/constant.js.map +1 -1
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +1 -5
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +25 -23
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/property-accessor.d.ts +1 -1
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +5 -7
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +3 -9
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record-layout.d.ts.map +1 -1
- package/dist/store/gi/record-layout.js +0 -4
- package/dist/store/gi/record-layout.js.map +1 -1
- package/dist/store/gi/return-wrap.d.ts +1 -1
- package/dist/store/gi/return-wrap.d.ts.map +1 -1
- package/dist/store/gi/return-wrap.js +4 -4
- package/dist/store/gi/return-wrap.js.map +1 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +13 -16
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/value-marshalable.d.ts +0 -8
- package/dist/store/gi/value-marshalable.d.ts.map +1 -1
- package/dist/store/gi/value-marshalable.js +0 -9
- package/dist/store/gi/value-marshalable.js.map +1 -1
- package/dist/store/gi-store.d.ts +2 -3
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/element-components.d.ts +0 -2
- package/dist/store/jsx/element-components.d.ts.map +1 -1
- package/dist/store/jsx/element-components.js +0 -4
- package/dist/store/jsx/element-components.js.map +1 -1
- package/dist/store/jsx/element-prop-imports.d.ts +2 -3
- package/dist/store/jsx/element-prop-imports.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-imports.js +0 -2
- package/dist/store/jsx/element-prop-imports.js.map +1 -1
- package/dist/store/jsx/element-prop-types.d.ts +0 -1
- package/dist/store/jsx/element-prop-types.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-types.js +0 -1
- package/dist/store/jsx/element-prop-types.js.map +1 -1
- package/dist/store/jsx/generated-elements.d.ts +29 -0
- package/dist/store/jsx/generated-elements.d.ts.map +1 -0
- package/dist/store/jsx/generated-elements.js +30 -0
- package/dist/store/jsx/generated-elements.js.map +1 -0
- package/dist/store/jsx/jsx.js +6 -6
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx/metadata.js +7 -7
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx/omitted-props.d.ts +2 -4
- package/dist/store/jsx/omitted-props.d.ts.map +1 -1
- package/dist/store/jsx/omitted-props.js +2 -4
- package/dist/store/jsx/omitted-props.js.map +1 -1
- package/dist/store/jsx/pipeline.d.ts +3 -1
- package/dist/store/jsx/pipeline.d.ts.map +1 -1
- package/dist/store/jsx/pipeline.js +3 -2
- package/dist/store/jsx/pipeline.js.map +1 -1
- package/dist/store/jsx/props.js +2 -2
- package/dist/store/jsx/props.js.map +1 -1
- package/dist/store/jsx-store.d.ts +2 -3
- 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 +28 -0
- package/dist/store/resolve-store.d.ts.map +1 -0
- package/dist/store/resolve-store.js +65 -0
- package/dist/store/resolve-store.js.map +1 -0
- package/dist/store/store-fs.d.ts +5 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +6 -4
- package/dist/store/store-fs.js.map +1 -1
- package/overrides/gobject/object.ts.ejs +8 -8
- package/package.json +6 -10
- package/src/analysis/descriptor-render.ts +20 -45
- package/src/analysis/descriptor.ts +13 -13
- package/src/analysis/param-structure.ts +8 -10
- package/src/analysis/ts-type.ts +4 -6
- package/src/compile.ts +2 -1
- package/src/docs/api-reference.ts +127 -4
- package/src/docs/pipeline.ts +8 -8
- package/src/docs/render.ts +7 -7
- package/src/docs/symbol-page.ts +7 -2
- package/src/fingerprint.ts +8 -13
- package/src/gi.ts +4 -11
- package/src/gir/field.ts +0 -4
- package/src/gir/gir-path.ts +7 -0
- package/src/gir/libraries.ts +13 -0
- package/src/gir/parameter.ts +0 -4
- package/src/gir/size.ts +0 -3
- package/src/gir/type-id.ts +2 -4
- package/src/gir/type-ref.ts +1 -1
- package/src/index.ts +18 -16
- package/src/internal.ts +2 -0
- package/src/jsx.ts +26 -26
- package/src/khronos/args.ts +1 -1
- package/src/khronos/pipeline.ts +1 -1
- package/src/khronos/plan.ts +8 -8
- package/src/react/element-config.ts +22 -19
- package/src/runner.ts +57 -39
- package/src/store/compile-store.ts +3 -4
- package/src/store/gi/callables.ts +5 -5
- package/src/store/gi/constant.ts +0 -2
- package/src/store/gi/function.ts +1 -5
- package/src/store/gi/method.ts +30 -28
- package/src/store/gi/property-accessor.ts +6 -8
- package/src/store/gi/record-field-accessor.ts +4 -10
- package/src/store/gi/record-layout.ts +0 -4
- package/src/store/gi/return-wrap.ts +5 -5
- package/src/store/gi/signal.ts +17 -17
- package/src/store/gi/value-marshalable.ts +0 -9
- package/src/store/gi-store.ts +2 -4
- package/src/store/jsx/element-components.ts +0 -6
- package/src/store/jsx/element-prop-imports.ts +7 -4
- package/src/store/jsx/element-prop-types.ts +0 -1
- package/src/store/jsx/generated-elements.ts +60 -0
- package/src/store/jsx/jsx.ts +7 -7
- package/src/store/jsx/metadata.ts +8 -8
- package/src/store/jsx/omitted-props.ts +2 -4
- package/src/store/jsx/pipeline.ts +5 -3
- package/src/store/jsx/props.ts +2 -2
- package/src/store/jsx-store.ts +5 -7
- package/src/store/resolve-store.ts +100 -0
- package/src/store/store-fs.ts +12 -5
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import type { ModuleExport } from "@gtkx/react/
|
|
1
|
+
import type { ModuleExport } from "@gtkx/react/internal";
|
|
2
2
|
import { readdirSync } from "node:fs";
|
|
3
3
|
import type { OmittedProps } from "../store/jsx/omitted-props.js";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
type BuiltinElement = { component?: ModuleExport; lazy?: boolean; props?: ModuleExport; omitProps?: string[] };
|
|
5
|
+
type BuiltinElement = { component?: ModuleExport; isLazy?: boolean; props?: ModuleExport; omittedProps?: string[] };
|
|
7
6
|
|
|
8
7
|
/** The framework's built-in element config, split into the maps codegen consumes. */
|
|
9
8
|
type BuiltinElements = {
|
|
9
|
+
/** Component wrappers keyed by GLib type name; an element without one inherits its nearest ancestor's. */
|
|
10
10
|
components: Record<string, ModuleExport>;
|
|
11
|
+
/** GLib type names with no GObject of their own, exported as elements that drop their construct-only props. */
|
|
11
12
|
lazyElements: string[];
|
|
13
|
+
/** Base props interfaces the generated element props extend, keyed by GLib type name. */
|
|
12
14
|
props: Record<string, ModuleExport>;
|
|
13
|
-
|
|
15
|
+
/** Props left out of the generated element props, keyed by GLib type name. */
|
|
16
|
+
omittedProps: OmittedProps;
|
|
14
17
|
};
|
|
15
18
|
|
|
16
19
|
const CONFIG_ENTRYPOINT = "config";
|
|
@@ -29,10 +32,6 @@ const presentNamespaceDirs = (giStoreDir: string): Set<string> => {
|
|
|
29
32
|
return dirs;
|
|
30
33
|
};
|
|
31
34
|
|
|
32
|
-
/**
|
|
33
|
-
* The clean, reconciler-free `@gtkx/react` config entrypoints to import: the base `config` entry plus
|
|
34
|
-
* each namespace's `<ns>/config` entry whose GIR namespace is present in the gi store.
|
|
35
|
-
*/
|
|
36
35
|
const configEntrypoints = (reactSubexports: string[], present: Set<string>): string[] =>
|
|
37
36
|
reactSubexports.filter((sub) => {
|
|
38
37
|
if (sub === CONFIG_ENTRYPOINT) {
|
|
@@ -61,30 +60,34 @@ const applyBuiltinElement = (target: BuiltinElements, type: string, config: Buil
|
|
|
61
60
|
target.props[type] = config.props;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
if (config.
|
|
65
|
-
target.
|
|
63
|
+
if (config.omittedProps !== undefined) {
|
|
64
|
+
target.omittedProps[type] = [...(target.omittedProps[type] ?? []), ...config.omittedProps];
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
if (config.
|
|
67
|
+
if (config.isLazy === true) {
|
|
69
68
|
target.lazyElements.push(type);
|
|
70
69
|
}
|
|
71
70
|
};
|
|
72
71
|
|
|
73
|
-
/**
|
|
74
|
-
* Reads the framework's built-in element config by importing the freshly linked `@gtkx/react` config
|
|
75
|
-
* entrypoints. These are reconciler-free, so importing them resolves `@gtkx/gi` but never `virtual:gtkx-config`;
|
|
76
|
-
* it must run only after the gi store has been linked.
|
|
77
|
-
*/
|
|
78
72
|
const collectBuiltinElements = (target: BuiltinElements, elements: Record<string, BuiltinElement>): void => {
|
|
79
73
|
for (const [type, config] of Object.entries(elements)) {
|
|
80
74
|
applyBuiltinElement(target, type, config);
|
|
81
75
|
}
|
|
82
76
|
};
|
|
83
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Reads the framework's built-in element config by importing the `config` entrypoints of the installed
|
|
80
|
+
* `@gtkx/react`, skipping the per-namespace ones whose namespace the gi store does not carry. Those
|
|
81
|
+
* entrypoints are reconciler-free, so importing them resolves `@gtkx/gi` but never `virtual:gtkx-config`,
|
|
82
|
+
* which means this must run only after the gi store has been written and linked.
|
|
83
|
+
*
|
|
84
|
+
* @param reactSubexports Subexport names of the installed `@gtkx/react`, as `resolveStore` reports them.
|
|
85
|
+
* @param giStoreDir The gi store directory, whose subdirectories name the generated namespaces.
|
|
86
|
+
*/
|
|
84
87
|
const readBuiltinElements = async (reactSubexports: string[], giStoreDir: string): Promise<BuiltinElements> => {
|
|
85
88
|
const present = presentNamespaceDirs(giStoreDir);
|
|
86
89
|
const entrypoints = configEntrypoints(reactSubexports, present);
|
|
87
|
-
const result: BuiltinElements = { components: {}, lazyElements: [], props: {},
|
|
90
|
+
const result: BuiltinElements = { components: {}, lazyElements: [], props: {}, omittedProps: {} };
|
|
88
91
|
|
|
89
92
|
for (const entrypoint of entrypoints) {
|
|
90
93
|
collectBuiltinElements(result, await importBuiltinElements(entrypoint));
|
|
@@ -93,5 +96,5 @@ const readBuiltinElements = async (reactSubexports: string[], giStoreDir: string
|
|
|
93
96
|
return result;
|
|
94
97
|
};
|
|
95
98
|
|
|
96
|
-
export {
|
|
97
|
-
export { readBuiltinElements, type
|
|
99
|
+
export type { ModuleExport } from "@gtkx/react/internal";
|
|
100
|
+
export { readBuiltinElements, type BuiltinElements };
|
package/src/runner.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import type { GiStoreOptions } from "./store/gi-store.js";
|
|
4
|
-
import type { JsxStoreOptions } from "./store/jsx-store.js";
|
|
5
3
|
import type { OmittedProps } from "./store/jsx/omitted-props.js";
|
|
4
|
+
import type { StoreOptions } from "./store/store-fs.js";
|
|
6
5
|
import { checkModules } from "./compile.js";
|
|
7
6
|
import { isGiStoreFresh } from "./fingerprint.js";
|
|
8
7
|
import { runGiCodegen } from "./gi.js";
|
|
9
8
|
import { Library } from "./gir/library.js";
|
|
10
9
|
import { generateGlModules, type GlGenerationReport } from "./khronos/pipeline.js";
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
/** A named export in a module, referenced as plain data (the module is never imported at runtime). */
|
|
12
|
+
type ModuleExport = {
|
|
13
|
+
/** Specifier the export is imported from. */
|
|
14
|
+
module: string;
|
|
15
|
+
/** Identifier the module exports it under. */
|
|
16
|
+
export: string;
|
|
17
|
+
};
|
|
13
18
|
|
|
14
19
|
type GlCodegenOptions = {
|
|
15
20
|
registryPath: string;
|
|
@@ -18,58 +23,71 @@ type GlCodegenOptions = {
|
|
|
18
23
|
resolveFrom: string;
|
|
19
24
|
};
|
|
20
25
|
|
|
26
|
+
/** What to generate and where to write it. */
|
|
21
27
|
type CodegenRunnerOptions = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
/** GIR library identifiers such as `"Gtk-4.0"`; a `"*"` selection must be expanded before it gets here. */
|
|
29
|
+
libraries: string[];
|
|
30
|
+
/** Directories to search for `.gir` files. */
|
|
31
|
+
girPath: string[];
|
|
32
|
+
/** Where to write and link the `@gtkx/gi` store. */
|
|
33
|
+
gi: StoreOptions;
|
|
34
|
+
/** Where to write and link the `@gtkx/jsx` store; omit to generate the gi store alone. */
|
|
35
|
+
jsx?: StoreOptions | undefined;
|
|
36
|
+
/** Subexport names of the installed `@gtkx/react`, whose element config shapes the jsx store. */
|
|
26
37
|
reactSubexports?: string[];
|
|
38
|
+
/** Component wrappers the project layers over the built-ins, keyed by GLib type name. */
|
|
27
39
|
userComponents?: Record<string, ModuleExport>;
|
|
40
|
+
/** GLib type names whose GObject their parent container creates, added to the framework's own. */
|
|
28
41
|
userLazyElements?: string[];
|
|
42
|
+
/** Base props interfaces the project's elements extend, keyed by GLib type name. */
|
|
29
43
|
userProps?: Record<string, ModuleExport>;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
44
|
+
/** Props the project drops from the generated element props, keyed by GLib type name. */
|
|
45
|
+
userOmittedProps?: OmittedProps;
|
|
46
|
+
/** Regenerates both stores even when their fingerprints are fresh. */
|
|
47
|
+
isForced?: boolean;
|
|
33
48
|
};
|
|
34
49
|
|
|
50
|
+
/** What a `runCodegen` run produced. */
|
|
35
51
|
type CodegenRunnerResult = {
|
|
36
|
-
|
|
52
|
+
/** Whether either store was rewritten; false means both were already fresh. */
|
|
53
|
+
isRegenerated: boolean;
|
|
54
|
+
/** How many namespaces the gi store was written with, zero when it was already fresh. */
|
|
37
55
|
namespaces: number;
|
|
56
|
+
/** How many JSX elements the jsx store binds, zero when no jsx store was requested. */
|
|
38
57
|
intrinsicElements: number;
|
|
58
|
+
/** Wall-clock duration of the run, in milliseconds. */
|
|
39
59
|
duration: number;
|
|
40
|
-
gl?: GlGenerationReport | undefined;
|
|
41
60
|
};
|
|
42
61
|
|
|
43
62
|
type StoreResult = {
|
|
44
|
-
|
|
63
|
+
isRegenerated: boolean;
|
|
45
64
|
namespaces: number;
|
|
46
65
|
intrinsicElements: number;
|
|
47
66
|
};
|
|
48
67
|
|
|
49
68
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
69
|
+
* Writes and links a project's `@gtkx/gi` and `@gtkx/jsx` stores from the given GObject-Introspection
|
|
70
|
+
* libraries. The gi store is rewritten only when its GIR inputs changed, and the jsx store only when the gi
|
|
71
|
+
* store or the React element config changed, unless `options.isForced` is set. Pass the spread of
|
|
72
|
+
* `resolveStore(projectRoot)` for everything but `libraries` and `girPath`.
|
|
54
73
|
*
|
|
55
|
-
* @param options
|
|
74
|
+
* @param options What to generate and where to write it.
|
|
56
75
|
* @returns A summary of what was regenerated and how long the run took.
|
|
76
|
+
* @throws If `girPath` is empty, which would otherwise generate nothing and report success.
|
|
57
77
|
*/
|
|
58
78
|
const runCodegen = async (options: CodegenRunnerOptions): Promise<CodegenRunnerResult> => {
|
|
59
79
|
const start = Date.now();
|
|
60
|
-
const gl = options.gl === undefined ? undefined : emitGlModules(options.gl);
|
|
61
80
|
const store = await emitStores(options);
|
|
62
81
|
|
|
63
82
|
return {
|
|
64
|
-
|
|
83
|
+
isRegenerated: store.isRegenerated,
|
|
65
84
|
namespaces: store.namespaces,
|
|
66
85
|
intrinsicElements: store.intrinsicElements,
|
|
67
86
|
duration: Date.now() - start,
|
|
68
|
-
gl,
|
|
69
87
|
};
|
|
70
88
|
};
|
|
71
89
|
|
|
72
|
-
const
|
|
90
|
+
const runGlCodegen = (options: GlCodegenOptions): GlGenerationReport => {
|
|
73
91
|
const { files, report } = generateGlModules({
|
|
74
92
|
registryPath: options.registryPath,
|
|
75
93
|
overrideExports: options.overrideExports,
|
|
@@ -97,24 +115,24 @@ const jsxUserOptions = (
|
|
|
97
115
|
userComponents: Record<string, ModuleExport>;
|
|
98
116
|
userLazyElements: string[];
|
|
99
117
|
userProps: Record<string, ModuleExport>;
|
|
100
|
-
|
|
118
|
+
userOmittedProps: OmittedProps;
|
|
101
119
|
} => ({
|
|
102
120
|
reactSubexports: options.reactSubexports ?? [],
|
|
103
121
|
userComponents: options.userComponents ?? {},
|
|
104
122
|
userLazyElements: options.userLazyElements ?? [],
|
|
105
123
|
userProps: options.userProps ?? {},
|
|
106
|
-
|
|
124
|
+
userOmittedProps: options.userOmittedProps ?? {},
|
|
107
125
|
});
|
|
108
126
|
|
|
109
127
|
const emitJsxStore = async (input: {
|
|
110
128
|
options: CodegenRunnerOptions;
|
|
111
|
-
jsx:
|
|
112
|
-
gi:
|
|
129
|
+
jsx: StoreOptions;
|
|
130
|
+
gi: StoreOptions;
|
|
113
131
|
loadLibrary: () => Library;
|
|
114
|
-
|
|
132
|
+
isGiRegenerated: boolean;
|
|
115
133
|
namespaces: number;
|
|
116
134
|
}): Promise<StoreResult> => {
|
|
117
|
-
const { options, jsx, gi, loadLibrary,
|
|
135
|
+
const { options, jsx, gi, loadLibrary, isGiRegenerated, namespaces } = input;
|
|
118
136
|
const { runJsxCodegen } = await import("./jsx.js");
|
|
119
137
|
|
|
120
138
|
const jsxResult = await runJsxCodegen({
|
|
@@ -122,12 +140,12 @@ const emitJsxStore = async (input: {
|
|
|
122
140
|
jsx,
|
|
123
141
|
giStoreDir: gi.storeDir,
|
|
124
142
|
...jsxUserOptions(options),
|
|
125
|
-
|
|
126
|
-
|
|
143
|
+
isGiRegenerated,
|
|
144
|
+
isForced: options.isForced === true,
|
|
127
145
|
});
|
|
128
146
|
|
|
129
147
|
return {
|
|
130
|
-
|
|
148
|
+
isRegenerated: isGiRegenerated || jsxResult.isRegenerated,
|
|
131
149
|
namespaces,
|
|
132
150
|
intrinsicElements: jsxResult.intrinsicElementCount,
|
|
133
151
|
};
|
|
@@ -135,35 +153,35 @@ const emitJsxStore = async (input: {
|
|
|
135
153
|
|
|
136
154
|
const emitStoresWithConfig = async (config: {
|
|
137
155
|
options: CodegenRunnerOptions;
|
|
138
|
-
gi:
|
|
139
|
-
jsx:
|
|
156
|
+
gi: StoreOptions;
|
|
157
|
+
jsx: StoreOptions | undefined;
|
|
140
158
|
libraries: string[];
|
|
141
159
|
girPath: string[];
|
|
142
160
|
}): Promise<StoreResult> => {
|
|
143
161
|
const { options, gi, jsx, libraries, girPath } = config;
|
|
144
162
|
let library: Library | undefined;
|
|
145
163
|
const loadLibrary = (): Library => (library ??= Library.load(libraries, girPath));
|
|
146
|
-
const isGiRegenerated = options.
|
|
164
|
+
const isGiRegenerated = options.isForced === true || !isGiStoreFresh(gi.storeDir, libraries, girPath);
|
|
147
165
|
|
|
148
166
|
const namespaces = isGiRegenerated
|
|
149
167
|
? runGiCodegen(loadLibrary(), { gi, libraries, girPath })
|
|
150
168
|
: 0;
|
|
151
169
|
|
|
152
170
|
if (jsx === undefined) {
|
|
153
|
-
return {
|
|
171
|
+
return { isRegenerated: isGiRegenerated, namespaces, intrinsicElements: 0 };
|
|
154
172
|
}
|
|
155
173
|
|
|
156
|
-
return emitJsxStore({ options, jsx, gi, loadLibrary,
|
|
174
|
+
return emitJsxStore({ options, jsx, gi, loadLibrary, isGiRegenerated, namespaces });
|
|
157
175
|
};
|
|
158
176
|
|
|
159
177
|
const emitStores = async (options: CodegenRunnerOptions): Promise<StoreResult> => {
|
|
160
178
|
const { gi, jsx, libraries, girPath } = options;
|
|
161
179
|
|
|
162
|
-
if (
|
|
163
|
-
|
|
180
|
+
if (girPath.length === 0) {
|
|
181
|
+
throw new Error("codegen needs at least one GIR search path; pass the result of resolveGirPath");
|
|
164
182
|
}
|
|
165
183
|
|
|
166
184
|
return emitStoresWithConfig({ options, gi, jsx, libraries, girPath });
|
|
167
185
|
};
|
|
168
186
|
|
|
169
|
-
export { runCodegen,
|
|
187
|
+
export { runCodegen, runGlCodegen, type CodegenRunnerOptions, type CodegenRunnerResult };
|
|
@@ -6,8 +6,7 @@ type CompileStoreParams = {
|
|
|
6
6
|
storeDir: string;
|
|
7
7
|
files: SourceModule[];
|
|
8
8
|
packageName: string;
|
|
9
|
-
|
|
10
|
-
configEnv?: boolean;
|
|
9
|
+
requiresEnvReference?: boolean;
|
|
11
10
|
};
|
|
12
11
|
|
|
13
12
|
const EMIT_OPTIONS = {
|
|
@@ -32,14 +31,14 @@ const writeEnvReference = (storeDir: string): (() => void) => {
|
|
|
32
31
|
const compileStore = (params: CompileStoreParams): void => {
|
|
33
32
|
const fileNames = params.files.map((file) => file.fileName);
|
|
34
33
|
|
|
35
|
-
const removeEnvReference = params.
|
|
34
|
+
const removeEnvReference = params.requiresEnvReference === true
|
|
36
35
|
? writeEnvReference(params.storeDir)
|
|
37
36
|
: (): void => undefined;
|
|
38
37
|
|
|
39
38
|
try {
|
|
40
39
|
compileProject({
|
|
41
40
|
projectDir: params.storeDir,
|
|
42
|
-
fileNames: params.
|
|
41
|
+
fileNames: params.requiresEnvReference === true ? [ENV_REFERENCE_FILE, ...fileNames] : fileNames,
|
|
43
42
|
compilerOptions: EMIT_OPTIONS,
|
|
44
43
|
label: `the generated ${params.packageName} store`,
|
|
45
44
|
});
|
|
@@ -34,7 +34,7 @@ type CallableMemberOptions = {
|
|
|
34
34
|
resolveName: (callable: GirFunction) => string | undefined;
|
|
35
35
|
isStatic: boolean;
|
|
36
36
|
returnTypeOverride?: string | undefined;
|
|
37
|
-
|
|
37
|
+
canUseRuntimeOverride?: boolean;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
type StaticEntryOptions = {
|
|
@@ -159,9 +159,9 @@ const runtimeOverrideMember = (
|
|
|
159
159
|
callable: GirFunction,
|
|
160
160
|
name: string,
|
|
161
161
|
doc: string,
|
|
162
|
-
|
|
162
|
+
canUseRuntimeOverride: boolean | undefined,
|
|
163
163
|
): string | undefined => {
|
|
164
|
-
if (
|
|
164
|
+
if (canUseRuntimeOverride !== true) {
|
|
165
165
|
return undefined;
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -183,7 +183,7 @@ const renderCallableMember = (
|
|
|
183
183
|
|
|
184
184
|
const { cIdentifier, name } = resolved;
|
|
185
185
|
const doc = renderJsDoc(callable.doc);
|
|
186
|
-
const override = runtimeOverrideMember(callable, name, doc, options.
|
|
186
|
+
const override = runtimeOverrideMember(callable, name, doc, options.canUseRuntimeOverride);
|
|
187
187
|
|
|
188
188
|
if (override !== undefined) {
|
|
189
189
|
return override;
|
|
@@ -240,7 +240,7 @@ const renderInstanceMethod = (
|
|
|
240
240
|
renderCallableMember(context, callable, {
|
|
241
241
|
resolveName: (member) => nameOverride ?? methodExportName(member),
|
|
242
242
|
isStatic: false,
|
|
243
|
-
|
|
243
|
+
canUseRuntimeOverride: true,
|
|
244
244
|
});
|
|
245
245
|
|
|
246
246
|
const resolveInstanceMember = (
|
package/src/store/gi/constant.ts
CHANGED
|
@@ -6,8 +6,6 @@ import type { ModuleContext } from "../../writer/context.js";
|
|
|
6
6
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
7
7
|
|
|
8
8
|
const TRUE_VALUES: Set<string> = new Set(["true", "1"]);
|
|
9
|
-
// A `gint64`/`guint64` constant is typed `bigint`, and its decimal text does not survive a double:
|
|
10
|
-
// G_MAXINT64 rounds to 2^63. The literal has to carry the BigInt suffix the type promises.
|
|
11
9
|
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["bigint64", "biguint64", "gtype"]);
|
|
12
10
|
|
|
13
11
|
const generateConstant = (context: ModuleContext, constant: GirConstant): void => {
|
package/src/store/gi/function.ts
CHANGED
|
@@ -32,13 +32,9 @@ const renderFnExpression = (context: ModuleContext, fn: GirFunction): string | u
|
|
|
32
32
|
const params = planCallArgs(context, fn).map((arg) => arg.paramLiteral);
|
|
33
33
|
const ret = renderReturnDescriptor(context, fn);
|
|
34
34
|
|
|
35
|
-
return tFn(library, fn.cIdentifier, { args: arrayLiteral(params), returns: ret,
|
|
35
|
+
return tFn(library, fn.cIdentifier, { args: arrayLiteral(params), returns: ret, canThrow: fn.throws });
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
// `moved-to` names the type member this function is also reachable as, so the namespace-level copy
|
|
39
|
-
// is a second export of one binding. Suppressing it is only right when that member is really
|
|
40
|
-
// emitted: 15 of Gtk-4.0's 28 `moved-to` targets are enum or error-domain members codegen emits no
|
|
41
|
-
// static for, and dropping those would delete API with nothing to replace it.
|
|
42
38
|
const isMovedOntoEmittedMember = (context: ModuleContext, fn: GirFunction): boolean => {
|
|
43
39
|
const [typeName, memberName] = fn.movedTo?.split(".") ?? [];
|
|
44
40
|
|
package/src/store/gi/method.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { hasUnknownArrayLength, type TypeId } from "../../gir/type-id.js";
|
|
|
23
23
|
import { itemComparatorArgDescriptors, itemComparatorTsType } from "./item-comparators.js";
|
|
24
24
|
import { isCollectibleCallerOut, isHandlePassedInPlace, isHandlePassing } from "./param-marshal.js";
|
|
25
25
|
|
|
26
|
-
type PromisifiedStep = {
|
|
26
|
+
type PromisifiedStep = { hasSeenOptional: boolean; expression: string | undefined };
|
|
27
27
|
|
|
28
28
|
type PromisifyContext = {
|
|
29
29
|
context: ModuleContext;
|
|
@@ -44,8 +44,8 @@ type CallArgPlan = {
|
|
|
44
44
|
|
|
45
45
|
type ParamDescriptorOptions = {
|
|
46
46
|
direction?: "out" | "inout";
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
isCallerAllocated?: boolean;
|
|
48
|
+
isConsumed?: boolean;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
type ArgIndexOptions = {
|
|
@@ -94,7 +94,7 @@ const renderInputParameters = (
|
|
|
94
94
|
isOptionalExtra: (parameter: GirParameter) => boolean,
|
|
95
95
|
): string => {
|
|
96
96
|
const parts: string[] = [];
|
|
97
|
-
let
|
|
97
|
+
let hasSeenOptional = false;
|
|
98
98
|
|
|
99
99
|
for (const { parameter, index } of inputParameters(context.library, fn)) {
|
|
100
100
|
if (shouldSkip(parameter)) {
|
|
@@ -104,10 +104,10 @@ const renderInputParameters = (
|
|
|
104
104
|
const name = parameterIdentifier(parameter, index);
|
|
105
105
|
|
|
106
106
|
if (isParameterOptional(parameter, isOptionalExtra)) {
|
|
107
|
-
|
|
107
|
+
hasSeenOptional = true;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
parts.push(formatParameterPart(name, parameterAnnotation(context, fn, parameter),
|
|
110
|
+
parts.push(formatParameterPart(name, parameterAnnotation(context, fn, parameter), hasSeenOptional));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
return parts.join(", ");
|
|
@@ -139,36 +139,36 @@ const classifyPromisifiedParameter = (
|
|
|
139
139
|
promisify: PromisifyContext,
|
|
140
140
|
parameter: GirParameter,
|
|
141
141
|
index: number,
|
|
142
|
-
state: { cancellableIndex: number;
|
|
142
|
+
state: { cancellableIndex: number; hasSeenOptional: boolean },
|
|
143
143
|
): PromisifiedStep => {
|
|
144
144
|
if (parameter.isVarargs) {
|
|
145
|
-
return {
|
|
145
|
+
return { hasSeenOptional: state.hasSeenOptional, expression: undefined };
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
if (index === state.cancellableIndex) {
|
|
149
|
-
return {
|
|
149
|
+
return { hasSeenOptional: true, expression: undefined };
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
if (shouldSkipPromisifiedParameter(promisify, parameter, index)) {
|
|
153
|
-
return {
|
|
153
|
+
return { hasSeenOptional: state.hasSeenOptional, expression: undefined };
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const
|
|
156
|
+
const hasSeenOptional = state.hasSeenOptional || parameter.optional;
|
|
157
157
|
|
|
158
|
-
return {
|
|
158
|
+
return { hasSeenOptional, expression: promisifiedArgument(promisify, parameter, index, hasSeenOptional) };
|
|
159
159
|
};
|
|
160
160
|
|
|
161
161
|
const collectPromisifiedArguments = (promisify: PromisifyContext, cancellableIndex: number): string[] => {
|
|
162
162
|
const expressions: string[] = [];
|
|
163
|
-
let
|
|
163
|
+
let hasSeenOptional = false;
|
|
164
164
|
|
|
165
165
|
for (const [index, parameter] of promisify.asyncFn.parameters.entries()) {
|
|
166
166
|
const step = classifyPromisifiedParameter(promisify, parameter, index, {
|
|
167
167
|
cancellableIndex,
|
|
168
|
-
|
|
168
|
+
hasSeenOptional,
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
hasSeenOptional = step.hasSeenOptional;
|
|
172
172
|
|
|
173
173
|
if (step.expression !== undefined) {
|
|
174
174
|
expressions.push(step.expression);
|
|
@@ -298,12 +298,12 @@ const paramDescriptorLiteral = (descriptor: string, options: ParamDescriptorOpti
|
|
|
298
298
|
parts.push(`direction: ${sourceStringLiteral(options.direction)}`);
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
if (options.
|
|
302
|
-
parts.push("
|
|
301
|
+
if (options.isCallerAllocated === true) {
|
|
302
|
+
parts.push("isCallerAllocated: true");
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
if (options.
|
|
306
|
-
parts.push("
|
|
305
|
+
if (options.isConsumed === true) {
|
|
306
|
+
parts.push("isConsumed: true");
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
return `{ ${parts.join(", ")} }`;
|
|
@@ -407,7 +407,7 @@ const planInoutArgument = (
|
|
|
407
407
|
return planInoutParam(context, parameter, {
|
|
408
408
|
index,
|
|
409
409
|
argIndex: planContext.argIndex,
|
|
410
|
-
|
|
410
|
+
isConsumed: folded.has(index),
|
|
411
411
|
lengthSource,
|
|
412
412
|
});
|
|
413
413
|
};
|
|
@@ -436,7 +436,7 @@ const planOutParam = (
|
|
|
436
436
|
const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, argIndex);
|
|
437
437
|
|
|
438
438
|
return {
|
|
439
|
-
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out",
|
|
439
|
+
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", isConsumed }),
|
|
440
440
|
inputExpr: undefined,
|
|
441
441
|
};
|
|
442
442
|
};
|
|
@@ -474,7 +474,7 @@ const planCallerOut = (
|
|
|
474
474
|
const classExpression = context.qualify(name.namespaceName, name.typeName);
|
|
475
475
|
|
|
476
476
|
return {
|
|
477
|
-
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out",
|
|
477
|
+
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "out", isCallerAllocated: true }),
|
|
478
478
|
inputExpr: `new ${classExpression}()`,
|
|
479
479
|
};
|
|
480
480
|
}
|
|
@@ -488,17 +488,21 @@ const planInoutParam = (
|
|
|
488
488
|
options: {
|
|
489
489
|
index: number;
|
|
490
490
|
argIndex: ArgIndexOptions;
|
|
491
|
-
|
|
491
|
+
isConsumed: boolean;
|
|
492
492
|
lengthSource?: { source: GirParameter; index: number } | undefined;
|
|
493
493
|
},
|
|
494
494
|
): CallArgPlan => {
|
|
495
|
-
const { index, argIndex,
|
|
495
|
+
const { index, argIndex, isConsumed, lengthSource } = options;
|
|
496
496
|
|
|
497
497
|
if (isHandlePassedInPlace(context, parameter)) {
|
|
498
498
|
const descriptor = renderDescriptor(context, parameter.type, "none", argIndex);
|
|
499
499
|
|
|
500
500
|
return {
|
|
501
|
-
paramLiteral: paramDescriptorLiteral(descriptor, {
|
|
501
|
+
paramLiteral: paramDescriptorLiteral(descriptor, {
|
|
502
|
+
direction: "inout",
|
|
503
|
+
isCallerAllocated: true,
|
|
504
|
+
isConsumed,
|
|
505
|
+
}),
|
|
502
506
|
inputExpr: parameterIdentifier(parameter, index),
|
|
503
507
|
};
|
|
504
508
|
}
|
|
@@ -506,7 +510,7 @@ const planInoutParam = (
|
|
|
506
510
|
const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, argIndex);
|
|
507
511
|
|
|
508
512
|
return {
|
|
509
|
-
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "inout",
|
|
513
|
+
paramLiteral: paramDescriptorLiteral(descriptor, { direction: "inout", isConsumed }),
|
|
510
514
|
inputExpr:
|
|
511
515
|
lengthSource === undefined
|
|
512
516
|
? parameterCallExpression(context, parameter, index)
|
|
@@ -588,8 +592,6 @@ const collectionArgument = (
|
|
|
588
592
|
return mapHandleExpression(name, isNullable);
|
|
589
593
|
};
|
|
590
594
|
|
|
591
|
-
// An array whose length nothing states is marshalled as the bare pointer it is, so there is nothing
|
|
592
|
-
// to map over.
|
|
593
595
|
const isMappableSequence = (context: ModuleContext, type: GirType | undefined): boolean => {
|
|
594
596
|
if (type?.kind === "carray") {
|
|
595
597
|
return !hasUnknownArrayLength(type) && isHandlePassing(context, type.element);
|
|
@@ -15,7 +15,7 @@ type ResolvedAccessor = {
|
|
|
15
15
|
jsName: string;
|
|
16
16
|
tsType: string;
|
|
17
17
|
hasGetter: boolean;
|
|
18
|
-
|
|
18
|
+
isWritable: boolean;
|
|
19
19
|
getterMember: string | undefined;
|
|
20
20
|
getterMethod: GirFunction | undefined;
|
|
21
21
|
setterMember: string | undefined;
|
|
@@ -136,8 +136,6 @@ const resolveAccessor = (args: PropertyAccessorArgs): ResolvedAccessor | undefin
|
|
|
136
136
|
return undefined;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
// `g_object_set_property` rejects a construct-only pspec with a critical and drops the write, so
|
|
140
|
-
// the property is settable at construction time only and must not advertise a setter.
|
|
141
139
|
const isWritable = isConstructableProperty(property) && !property.constructOnly;
|
|
142
140
|
const { member: getterMember, method: getterMethod } = resolveGetterDelegate(args, jsName);
|
|
143
141
|
const { member: setterMember, method: setterMethod } = resolveSetterDelegate(args, jsName, isWritable);
|
|
@@ -150,7 +148,7 @@ const resolveAccessor = (args: PropertyAccessorArgs): ResolvedAccessor | undefin
|
|
|
150
148
|
const ownType = resolveOwnType(context, property, getterMethod, setterMethod);
|
|
151
149
|
const tsType = resolveTsType(args.inheritedType, ownType);
|
|
152
150
|
|
|
153
|
-
return { jsName, tsType, hasGetter,
|
|
151
|
+
return { jsName, tsType, hasGetter, isWritable, getterMember, getterMethod, setterMember };
|
|
154
152
|
};
|
|
155
153
|
|
|
156
154
|
const resolveOwnerAccessor = (
|
|
@@ -197,7 +195,7 @@ const renderResolvedPropertyAccessor = (
|
|
|
197
195
|
property: GirProperty,
|
|
198
196
|
accessor: ResolvedAccessor,
|
|
199
197
|
): string => {
|
|
200
|
-
const { jsName, tsType, hasGetter,
|
|
198
|
+
const { jsName, tsType, hasGetter, isWritable, getterMember, getterMethod, setterMember } = accessor;
|
|
201
199
|
const blocks: string[] = [];
|
|
202
200
|
|
|
203
201
|
if (hasGetter) {
|
|
@@ -205,7 +203,7 @@ const renderResolvedPropertyAccessor = (
|
|
|
205
203
|
blocks.push(renderBlock(`get ${jsName}(): ${tsType}`, getterBody));
|
|
206
204
|
}
|
|
207
205
|
|
|
208
|
-
if (
|
|
206
|
+
if (isWritable) {
|
|
209
207
|
const setterBody =
|
|
210
208
|
setterMember === undefined ? renderGenericSetBody(context, property) : `this.${setterMember}(value);`;
|
|
211
209
|
|
|
@@ -219,10 +217,10 @@ const renderPropertyAccessor = (args: PropertyAccessorArgs): string | undefined
|
|
|
219
217
|
withAccessor(args, (accessor) => renderResolvedPropertyAccessor(args.context, args.property, accessor));
|
|
220
218
|
|
|
221
219
|
const renderPropertyAccessorSignature = (args: PropertyAccessorArgs): string | undefined =>
|
|
222
|
-
withAccessor(args, ({ jsName, tsType, hasGetter,
|
|
220
|
+
withAccessor(args, ({ jsName, tsType, hasGetter, isWritable }) => {
|
|
223
221
|
const doc = renderJsDoc(args.property.doc);
|
|
224
222
|
|
|
225
|
-
if (hasGetter &&
|
|
223
|
+
if (hasGetter && isWritable) {
|
|
226
224
|
return `${doc}${jsName}: ${tsType};`;
|
|
227
225
|
}
|
|
228
226
|
|