@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
package/src/docs/pipeline.ts
CHANGED
|
@@ -28,8 +28,8 @@ type DocsOptions = {
|
|
|
28
28
|
outDir: string;
|
|
29
29
|
basePath?: string;
|
|
30
30
|
props?: ElementProps;
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
omittedProps?: OmittedProps;
|
|
32
|
+
isForced?: boolean;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
type DocsManifest = {
|
|
@@ -45,7 +45,7 @@ type Page = { path: string; content: string };
|
|
|
45
45
|
type NamespacePages = { docs: DocsNamespace; pages: Page[] };
|
|
46
46
|
|
|
47
47
|
type DocsResult = {
|
|
48
|
-
|
|
48
|
+
isRegenerated: boolean;
|
|
49
49
|
namespaces: DocsNamespace[];
|
|
50
50
|
};
|
|
51
51
|
|
|
@@ -193,7 +193,7 @@ const generatePages = (options: DocsOptions, basePath: string, library: Library)
|
|
|
193
193
|
};
|
|
194
194
|
|
|
195
195
|
const cachedDocsResult = (options: DocsOptions, manifestPath: string): DocsResult | undefined => {
|
|
196
|
-
if (options.
|
|
196
|
+
if (options.isForced === true || !isGiStoreFresh(options.outDir, options.libraries, options.girPath)) {
|
|
197
197
|
return undefined;
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -203,7 +203,7 @@ const cachedDocsResult = (options: DocsOptions, manifestPath: string): DocsResul
|
|
|
203
203
|
|
|
204
204
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as DocsManifest;
|
|
205
205
|
|
|
206
|
-
return {
|
|
206
|
+
return { isRegenerated: false, namespaces: manifest.namespaces };
|
|
207
207
|
};
|
|
208
208
|
|
|
209
209
|
const writePages = (outDir: string, pages: Page[]): void => {
|
|
@@ -216,7 +216,7 @@ const writePages = (outDir: string, pages: Page[]): void => {
|
|
|
216
216
|
|
|
217
217
|
const writeDocs = (options: DocsOptions): DocsResult => {
|
|
218
218
|
setElementProps(options.props ?? {});
|
|
219
|
-
setOmittedProps(options.
|
|
219
|
+
setOmittedProps(options.omittedProps ?? {});
|
|
220
220
|
const basePath = options.basePath ?? "/reference";
|
|
221
221
|
const manifestPath = join(options.outDir, MANIFEST_FILENAME);
|
|
222
222
|
const cached = cachedDocsResult(options, manifestPath);
|
|
@@ -238,7 +238,7 @@ const writeDocs = (options: DocsOptions): DocsResult => {
|
|
|
238
238
|
JSON.stringify(computeGiFingerprint(library.girFiles, options.libraries, options.girPath)),
|
|
239
239
|
);
|
|
240
240
|
|
|
241
|
-
return {
|
|
241
|
+
return { isRegenerated: true, namespaces };
|
|
242
242
|
};
|
|
243
243
|
|
|
244
|
-
export { writeDocs
|
|
244
|
+
export { writeDocs };
|
package/src/docs/render.ts
CHANGED
|
@@ -45,8 +45,8 @@ const renderDocsHandlerResultType = (library: Library, signal: GirCallable): str
|
|
|
45
45
|
library,
|
|
46
46
|
signal,
|
|
47
47
|
renderType: (ref, nullable) => renderDocsType(library, ref, nullable),
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
shouldIncludeCallerAllocated: false,
|
|
49
|
+
isOptOut: true,
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
const renderDocsHandlerParameters = (library: Library, signal: GirCallable): string[] =>
|
|
@@ -69,16 +69,16 @@ const stripDocMedia = (markdown: string): string =>
|
|
|
69
69
|
.replaceAll(/<video[\s\S]*?(?:<\/video>|\/>)/g, "")
|
|
70
70
|
.replaceAll(/<img[^>]*>/g, "");
|
|
71
71
|
|
|
72
|
-
const demoteLine = (line: string, isInFence: boolean): { text: string;
|
|
72
|
+
const demoteLine = (line: string, isInFence: boolean): { text: string; isInFence: boolean } => {
|
|
73
73
|
if (FENCE_LINE.test(line)) {
|
|
74
|
-
return { text: line,
|
|
74
|
+
return { text: line, isInFence: !isInFence };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (isInFence) {
|
|
78
|
-
return { text: line,
|
|
78
|
+
return { text: line, isInFence };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
return { text: HEADING_LINE.test(line) ? `#${line}` : line,
|
|
81
|
+
return { text: HEADING_LINE.test(line) ? `#${line}` : line, isInFence };
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
const demoteHeadings = (markdown: string): string => {
|
|
@@ -87,7 +87,7 @@ const demoteHeadings = (markdown: string): string => {
|
|
|
87
87
|
|
|
88
88
|
for (const line of markdown.split("\n")) {
|
|
89
89
|
const result = demoteLine(line, isInFence);
|
|
90
|
-
isInFence = result.
|
|
90
|
+
isInFence = result.isInFence;
|
|
91
91
|
lines.push(result.text);
|
|
92
92
|
}
|
|
93
93
|
|
package/src/docs/symbol-page.ts
CHANGED
|
@@ -49,12 +49,17 @@ import {
|
|
|
49
49
|
type SignatureEntry,
|
|
50
50
|
} from "./render.js";
|
|
51
51
|
|
|
52
|
+
/** What every indexed GIR symbol carries, whatever its kind. */
|
|
52
53
|
type GiSymbolBase = {
|
|
54
|
+
/** GIR namespace declaring the symbol. */
|
|
53
55
|
namespace: GirNamespace;
|
|
56
|
+
/** Name the bindings export it under: camelCase for functions, PascalCase for classes, the GIR name otherwise. */
|
|
54
57
|
name: string;
|
|
58
|
+
/** Raw gtk-doc text from the GIR, undefined when the symbol is undocumented. */
|
|
55
59
|
doc: string | undefined;
|
|
56
60
|
};
|
|
57
61
|
|
|
62
|
+
/** A GIR symbol the reference indexes, discriminated by `kind` and carrying the GIR node its page renders from. */
|
|
58
63
|
type GiSymbolEntry =
|
|
59
64
|
| (GiSymbolBase & { kind: "class" | "interface"; klass: GirClass }) |
|
|
60
65
|
(GiSymbolBase & { kind: "record"; record: GirRecord }) |
|
|
@@ -270,7 +275,7 @@ const propertyMeta = (property: GirProperty, accessor: ResolvedAccessor, origin:
|
|
|
270
275
|
meta.push("construct-only");
|
|
271
276
|
}
|
|
272
277
|
|
|
273
|
-
if (!accessor.
|
|
278
|
+
if (!accessor.isWritable) {
|
|
274
279
|
meta.push("read-only");
|
|
275
280
|
} else if (!accessor.hasGetter) {
|
|
276
281
|
meta.push("write-only");
|
|
@@ -495,7 +500,7 @@ const recordPage = (entry: GiSymbolBase & { kind: "record"; record: GirRecord },
|
|
|
495
500
|
};
|
|
496
501
|
|
|
497
502
|
const fieldMeta = (field: ResolvedRecordField): string =>
|
|
498
|
-
[`\`${field.tsType}\``, ...(field.
|
|
503
|
+
[`\`${field.tsType}\``, ...(field.isWritable ? [] : ["read-only"])].join(" · ");
|
|
499
504
|
|
|
500
505
|
const fieldsSection = (record: GirRecord, context: ModuleContext, claimedNames: Set<string>): string[] => {
|
|
501
506
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
package/src/fingerprint.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { createRequire } from "node:module";
|
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
-
/** The freshness sentinel of the `@gtkx/gi` store, derived purely from the GIR inputs. */
|
|
9
8
|
type GiFingerprint = {
|
|
10
9
|
value: string;
|
|
11
10
|
girFiles: string[];
|
|
@@ -15,16 +14,14 @@ type GiFingerprint = {
|
|
|
15
14
|
|
|
16
15
|
type ModuleExport = { module: string; export: string };
|
|
17
16
|
|
|
18
|
-
/** The `@gtkx/react` element config that shapes the generated `@gtkx/jsx` store. */
|
|
19
17
|
type JsxFingerprintInput = {
|
|
20
18
|
reactVersion: string;
|
|
21
19
|
components: Record<string, ModuleExport>;
|
|
22
20
|
lazyElements: string[];
|
|
23
21
|
props: Record<string, ModuleExport>;
|
|
24
|
-
|
|
22
|
+
omittedProps: Record<string, string[]>;
|
|
25
23
|
};
|
|
26
24
|
|
|
27
|
-
/** The freshness sentinel of the `@gtkx/jsx` store, derived from the React element config. */
|
|
28
25
|
type JsxFingerprint = {
|
|
29
26
|
value: string;
|
|
30
27
|
intrinsicElementCount: number;
|
|
@@ -37,8 +34,6 @@ const OVERRIDES_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "o
|
|
|
37
34
|
|
|
38
35
|
const sortAlpha = (values: string[]): string => sortStrings(values).join(",");
|
|
39
36
|
|
|
40
|
-
// The overrides are copied verbatim into the store, so editing one changes the output even though no
|
|
41
|
-
// GIR file moved. Without them in the hash a stale override survives every non-forced run.
|
|
42
37
|
const overrideFiles = (): string[] => {
|
|
43
38
|
if (!existsSync(OVERRIDES_ROOT)) {
|
|
44
39
|
return [];
|
|
@@ -116,7 +111,7 @@ const hasMatchingRecordedInputs = (sentinel: GiFingerprint, libraries: string[],
|
|
|
116
111
|
const serializeModuleExports = (map: Record<string, ModuleExport>): [string, string, string][] =>
|
|
117
112
|
sortStrings(Object.keys(map)).map((type) => [type, map[type]?.module ?? "", map[type]?.export ?? ""]);
|
|
118
113
|
|
|
119
|
-
const
|
|
114
|
+
const serializeOmittedProps = (map: Record<string, string[]>): [string, string][] =>
|
|
120
115
|
sortStrings(Object.keys(map)).map((type) => [type, sortAlpha(map[type] ?? [])]);
|
|
121
116
|
|
|
122
117
|
const hashJsx = (input: JsxFingerprintInput): string =>
|
|
@@ -128,7 +123,7 @@ const hashJsx = (input: JsxFingerprintInput): string =>
|
|
|
128
123
|
serializeModuleExports(input.components),
|
|
129
124
|
sortStrings(input.lazyElements),
|
|
130
125
|
serializeModuleExports(input.props),
|
|
131
|
-
|
|
126
|
+
serializeOmittedProps(input.omittedProps),
|
|
132
127
|
]),
|
|
133
128
|
)
|
|
134
129
|
.digest("hex");
|
|
@@ -141,11 +136,11 @@ const computeJsxFingerprint = (input: JsxFingerprintInput, intrinsicElementCount
|
|
|
141
136
|
const jsxStoreFreshness = (
|
|
142
137
|
jsxStoreDir: string,
|
|
143
138
|
input: JsxFingerprintInput,
|
|
144
|
-
): {
|
|
139
|
+
): { isFresh: boolean; intrinsicElementCount: number } => {
|
|
145
140
|
const sentinelPath = join(jsxStoreDir, FINGERPRINT_FILENAME);
|
|
146
141
|
|
|
147
142
|
if (!existsSync(sentinelPath)) {
|
|
148
|
-
return {
|
|
143
|
+
return { isFresh: false, intrinsicElementCount: 0 };
|
|
149
144
|
}
|
|
150
145
|
|
|
151
146
|
let sentinel: JsxFingerprint;
|
|
@@ -153,12 +148,12 @@ const jsxStoreFreshness = (
|
|
|
153
148
|
try {
|
|
154
149
|
sentinel = JSON.parse(readFileSync(sentinelPath, "utf8")) as JsxFingerprint;
|
|
155
150
|
} catch {
|
|
156
|
-
return {
|
|
151
|
+
return { isFresh: false, intrinsicElementCount: 0 };
|
|
157
152
|
}
|
|
158
153
|
|
|
159
154
|
return sentinel.value === hashJsx(input)
|
|
160
|
-
? {
|
|
161
|
-
: {
|
|
155
|
+
? { isFresh: true, intrinsicElementCount: sentinel.intrinsicElementCount }
|
|
156
|
+
: { isFresh: false, intrinsicElementCount: 0 };
|
|
162
157
|
};
|
|
163
158
|
|
|
164
159
|
export {
|
package/src/gi.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import type { Library } from "./gir/library.js";
|
|
2
|
+
import type { StoreOptions } from "./store/store-fs.js";
|
|
2
3
|
import { computeGiFingerprint } from "./fingerprint.js";
|
|
3
4
|
import { namespaceDirectory } from "./gir/namespace.js";
|
|
4
|
-
import { type GiNamespaceInput,
|
|
5
|
+
import { type GiNamespaceInput, writeGiStore } from "./store/gi-store.js";
|
|
5
6
|
import { generateNamespaceModule } from "./store/gi/pipeline.js";
|
|
6
7
|
|
|
7
8
|
type GiCodegenOptions = {
|
|
8
|
-
gi:
|
|
9
|
+
gi: StoreOptions;
|
|
9
10
|
libraries: string[];
|
|
10
11
|
girPath: string[];
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* Generates the `@gtkx/gi` store from the loaded GIR library and links it into the project. This is the
|
|
15
|
-
* react-free half of codegen: it can run before `@gtkx/gi` (or `@gtkx/react`) exists, since it produces them.
|
|
16
|
-
*
|
|
17
|
-
* @returns The number of namespaces written.
|
|
18
|
-
*/
|
|
19
14
|
const runGiCodegen = (library: Library, options: GiCodegenOptions): number => {
|
|
20
15
|
const { gi, libraries, girPath } = options;
|
|
21
16
|
|
|
@@ -30,6 +25,4 @@ const runGiCodegen = (library: Library, options: GiCodegenOptions): number => {
|
|
|
30
25
|
return library.namespaces.size;
|
|
31
26
|
};
|
|
32
27
|
|
|
33
|
-
export {
|
|
34
|
-
export type { GiStoreOptions } from "./store/gi-store.js";
|
|
35
|
-
export { runGiCodegen, type GiCodegenOptions };
|
|
28
|
+
export { runGiCodegen };
|
package/src/gir/field.ts
CHANGED
|
@@ -11,7 +11,6 @@ type GirField = {
|
|
|
11
11
|
writable: boolean;
|
|
12
12
|
private: boolean;
|
|
13
13
|
bits: number | undefined;
|
|
14
|
-
/** Members of an anonymous nested `<union>`/`<record>`, which occupies a slot but has no type. */
|
|
15
14
|
inlineMembers: GirField[] | undefined;
|
|
16
15
|
inlineIsUnion: boolean;
|
|
17
16
|
};
|
|
@@ -29,9 +28,6 @@ const fieldFromNode = (node: RawNode, context: ParseContext): GirField => ({
|
|
|
29
28
|
inlineIsUnion: false,
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
// A record may embed an anonymous `<union>` or `<record>` instead of naming a type for it. The
|
|
33
|
-
// member occupies a real slot and contributes its own size and alignment, but carries no `<type>`,
|
|
34
|
-
// so it has to be admitted as a field whose layout comes from its own children.
|
|
35
31
|
const anonymousMemberFromNode = (node: RawNode, isUnion: boolean, context: ParseContext): GirField => ({
|
|
36
32
|
name: nameAttr(node),
|
|
37
33
|
doc: getDoc(node),
|
package/src/gir/gir-path.ts
CHANGED
|
@@ -4,6 +4,13 @@ import { existsSync } from "node:fs";
|
|
|
4
4
|
|
|
5
5
|
const SYSTEM_GIR_PATH = "/usr/share/gir-1.0";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* The directories to search for `.gir` files, in precedence order: the config's own `girPath`, then
|
|
9
|
+
* `GTKX_GIR_PATH`, then `/usr/share/gir-1.0`, then the girdir pkg-config reports for
|
|
10
|
+
* gobject-introspection-1.0. Duplicates are dropped, and the last two are included only when they exist.
|
|
11
|
+
*
|
|
12
|
+
* @throws If pkg-config is installed but fails while being queried.
|
|
13
|
+
*/
|
|
7
14
|
const resolveGirPath = (configGirPath: string[] | undefined): string[] => {
|
|
8
15
|
const paths: string[] = [];
|
|
9
16
|
|
package/src/gir/libraries.ts
CHANGED
|
@@ -2,13 +2,22 @@ import { sortStrings } from "@gtkx/utils";
|
|
|
2
2
|
import { readdirSync } from "node:fs";
|
|
3
3
|
|
|
4
4
|
type GirNamespace = { name: string; version: string; identifier: string };
|
|
5
|
+
/** A `libraries` config value: an explicit list, `"*"` for everything installed, or absent for the default. */
|
|
5
6
|
type LibrarySelection = typeof LIBRARIES_WILDCARD | string[] | undefined;
|
|
6
7
|
|
|
8
|
+
/** The `libraries` value that stands for every GIR library installed on the search path. */
|
|
7
9
|
const LIBRARIES_WILDCARD = "*";
|
|
8
10
|
const GIR_LIBRARY_PATTERN = /^[A-Za-z][A-Za-z0-9]*-\d+(?:\.\d+)*$/;
|
|
9
11
|
const DEFAULT_LIBRARIES: string[] = ["Gtk-4.0"];
|
|
10
12
|
const GIR_FILE_SUFFIX = ".gir";
|
|
11
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Expands a `libraries` config value into the GIR identifiers to generate from: `"Gtk-4.0"` alone when
|
|
16
|
+
* nothing is configured, everything installed for `"*"`, and otherwise the given list with `"Gtk-4.0"`
|
|
17
|
+
* prepended unless it already names a Gtk version.
|
|
18
|
+
*
|
|
19
|
+
* @throws If `"*"` matched no `.gir` file anywhere on the GIR path.
|
|
20
|
+
*/
|
|
12
21
|
const resolveLibraries = (libraries: LibrarySelection, girPath: string[]): string[] => {
|
|
13
22
|
if (libraries === undefined) {
|
|
14
23
|
return [...DEFAULT_LIBRARIES];
|
|
@@ -74,6 +83,10 @@ const collectDirNamespaces = (highestByName: Map<string, GirNamespace>, dir: str
|
|
|
74
83
|
}
|
|
75
84
|
};
|
|
76
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Every GIR library installed on the search path, as sorted `Name-Version` identifiers. A namespace found
|
|
88
|
+
* in more than one version contributes only its highest, and unreadable directories are skipped.
|
|
89
|
+
*/
|
|
77
90
|
const discoverGirNamespaces = (girPath: string[]): string[] => {
|
|
78
91
|
const highestByName: Map<string, GirNamespace> = new Map();
|
|
79
92
|
|
package/src/gir/parameter.ts
CHANGED
|
@@ -53,10 +53,6 @@ const SCOPES: Set<CallbackScope> = new Set(["call", "notified", "async", "foreve
|
|
|
53
53
|
const transferOwnership = (node: RawNode): ParameterTransfer =>
|
|
54
54
|
parseEnumAttr(attr(node, "transfer-ownership"), TRANSFERS, "none", "transfer-ownership");
|
|
55
55
|
|
|
56
|
-
// `allow-none` is the legacy spelling of two different attributes: on an in-parameter it means the
|
|
57
|
-
// value may be NULL (`nullable`), but on an out-parameter it means the caller may pass a NULL
|
|
58
|
-
// location (`optional`). Folding it into `nullable` for an out-parameter would claim the returned
|
|
59
|
-
// value can be null for the 494 out-parameters across the installed GIRs that only say `allow-none`.
|
|
60
56
|
const isInDirection = (node: RawNode): boolean =>
|
|
61
57
|
parseEnumAttr(attr(node, "direction"), DIRECTIONS, "in", "direction") === "in";
|
|
62
58
|
|
package/src/gir/size.ts
CHANGED
|
@@ -59,9 +59,6 @@ const pushPlainField = (state: StructLayoutState, slots: FieldSlot[], field: Fie
|
|
|
59
59
|
state.bitCursor = (byteOffset + field.layout.size) * 8;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
// SysV AMD64 places a bit-field at the current bit offset whenever it still fits inside a storage
|
|
63
|
-
// unit of its declared type aligned to that type's alignment, so the unit the cursor already sits in
|
|
64
|
-
// may have room even though the cursor is not on a unit boundary.
|
|
65
62
|
const pushBitfield = (input: {
|
|
66
63
|
state: StructLayoutState;
|
|
67
64
|
slots: FieldSlot[];
|
package/src/gir/type-id.ts
CHANGED
|
@@ -12,7 +12,7 @@ type CArrayType = {
|
|
|
12
12
|
elementCType: string | undefined;
|
|
13
13
|
lengthParameterIndex: number | undefined;
|
|
14
14
|
fixedSize: number | undefined;
|
|
15
|
-
|
|
15
|
+
isZeroTerminated: boolean;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
type ListType = {
|
|
@@ -46,10 +46,8 @@ const LIST_FLAVOR_BY_NAME = {
|
|
|
46
46
|
"GLib.ByteArray": "gbytearray",
|
|
47
47
|
} as const;
|
|
48
48
|
|
|
49
|
-
// An array with no length parameter, no fixed size and an explicit `zero-terminated="0"` carries no
|
|
50
|
-
// way to recover its length, so it is a bare pointer rather than something that can be walked.
|
|
51
49
|
const hasUnknownArrayLength = (ref: CArrayType): boolean =>
|
|
52
|
-
!ref.
|
|
50
|
+
!ref.isZeroTerminated && ref.lengthParameterIndex === undefined && ref.fixedSize === undefined;
|
|
53
51
|
|
|
54
52
|
export {
|
|
55
53
|
hasUnknownArrayLength,
|
package/src/gir/type-ref.ts
CHANGED
|
@@ -90,7 +90,7 @@ const arrayTypeRefFromNode = (arrayNode: RawNode, context: ParseContext): TypeId
|
|
|
90
90
|
elementCType: elementNode === undefined ? undefined : attr(elementNode, "c:type"),
|
|
91
91
|
lengthParameterIndex: intAttr(arrayNode, "length"),
|
|
92
92
|
fixedSize: intAttr(arrayNode, "fixed-size"),
|
|
93
|
-
|
|
93
|
+
isZeroTerminated: isAttrTrue(arrayNode, "zero-terminated", true),
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
return context.addContainer(carray);
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @public */
|
|
1
2
|
export {
|
|
2
3
|
API_SYMBOL_KINDS,
|
|
3
4
|
type ApiLookupResult,
|
|
@@ -7,23 +8,24 @@ export {
|
|
|
7
8
|
type ApiSearchOptions,
|
|
8
9
|
type ApiSymbol,
|
|
9
10
|
type ApiSymbolKind,
|
|
11
|
+
type ApiSymbolQuery,
|
|
10
12
|
loadApiReference,
|
|
11
13
|
} from "./docs/api-reference.js";
|
|
12
|
-
|
|
13
|
-
type DocsElementLink,
|
|
14
|
-
type DocsNamespace,
|
|
15
|
-
type DocsOptions,
|
|
16
|
-
type DocsResult,
|
|
17
|
-
writeDocs,
|
|
18
|
-
} from "./docs/pipeline.js";
|
|
14
|
+
/** @public */
|
|
19
15
|
export { resolveGirPath } from "./gir/gir-path.js";
|
|
20
|
-
|
|
21
|
-
export {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export { runCodegen } from "./runner.js";
|
|
16
|
+
/** @public */
|
|
17
|
+
export { discoverGirNamespaces, type LibrarySelection, resolveLibraries } from "./gir/libraries.js";
|
|
18
|
+
/** @public */
|
|
19
|
+
export { type BuiltinElements, type ModuleExport, readBuiltinElements } from "./react/element-config.js";
|
|
20
|
+
/** @public */
|
|
21
|
+
export { type CodegenRunnerOptions, type CodegenRunnerResult, runCodegen } from "./runner.js";
|
|
22
|
+
/** @public */
|
|
28
23
|
export type { ElementProps } from "./store/jsx/element-prop-imports.js";
|
|
29
|
-
|
|
24
|
+
/** @public */
|
|
25
|
+
export { type GeneratedElement, readGeneratedElements } from "./store/jsx/generated-elements.js";
|
|
26
|
+
/** @public */
|
|
27
|
+
export { mergeOmittedProps, type OmittedProps } from "./store/jsx/omitted-props.js";
|
|
28
|
+
/** @public */
|
|
29
|
+
export { type ResolvedStore, resolveStore } from "./store/resolve-store.js";
|
|
30
|
+
/** @public */
|
|
31
|
+
export type { StoreOptions } from "./store/store-fs.js";
|
package/src/internal.ts
ADDED
package/src/jsx.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Library } from "./gir/library.js";
|
|
2
|
+
import type { StoreOptions } from "./store/store-fs.js";
|
|
2
3
|
import {
|
|
3
4
|
computeJsxFingerprint,
|
|
4
5
|
FINGERPRINT_FILENAME,
|
|
@@ -6,70 +7,69 @@ import {
|
|
|
6
7
|
jsxStoreFreshness,
|
|
7
8
|
} from "./fingerprint.js";
|
|
8
9
|
import { type ModuleExport, readBuiltinElements } from "./react/element-config.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
10
|
+
import { writeJsxStore } from "./store/jsx-store.js";
|
|
11
|
+
import { ELEMENTS_FILENAME, renderGeneratedElements } from "./store/jsx/generated-elements.js";
|
|
12
|
+
import { mergeOmittedProps, type OmittedProps } from "./store/jsx/omitted-props.js";
|
|
11
13
|
import { generateJsxFiles } from "./store/jsx/pipeline.js";
|
|
12
14
|
|
|
13
15
|
type RunJsxCodegenOptions = {
|
|
14
16
|
getLibrary: () => Library;
|
|
15
|
-
jsx:
|
|
17
|
+
jsx: StoreOptions;
|
|
16
18
|
giStoreDir: string;
|
|
17
19
|
reactSubexports: string[];
|
|
18
20
|
userComponents: Record<string, ModuleExport>;
|
|
19
21
|
userLazyElements: string[];
|
|
20
22
|
userProps: Record<string, ModuleExport>;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
userOmittedProps: OmittedProps;
|
|
24
|
+
isGiRegenerated: boolean;
|
|
25
|
+
isForced: boolean;
|
|
24
26
|
};
|
|
25
27
|
|
|
26
28
|
type RunJsxCodegenResult = {
|
|
27
|
-
|
|
29
|
+
isRegenerated: boolean;
|
|
28
30
|
intrinsicElementCount: number;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
/**
|
|
32
|
-
* Generates the `@gtkx/jsx` store, reading the framework's built-in element config from the freshly
|
|
33
|
-
* linked `@gtkx/react` and layering the project's own element config over it. This is the react-importing
|
|
34
|
-
* half of codegen: it must run only after the gi store has been written and linked.
|
|
35
|
-
*/
|
|
36
33
|
const runJsxCodegen = async (options: RunJsxCodegenOptions): Promise<RunJsxCodegenResult> => {
|
|
37
34
|
const builtin = await readBuiltinElements(options.reactSubexports, options.giStoreDir);
|
|
38
35
|
const components = { ...builtin.components, ...options.userComponents };
|
|
39
36
|
const lazyElements = [...builtin.lazyElements, ...options.userLazyElements];
|
|
40
37
|
const props = { ...builtin.props, ...options.userProps };
|
|
41
|
-
const
|
|
38
|
+
const omittedProps = mergeOmittedProps(builtin.omittedProps, options.userOmittedProps);
|
|
42
39
|
|
|
43
40
|
const fingerprintInput: JsxFingerprintInput = {
|
|
44
41
|
reactVersion: options.jsx.version,
|
|
45
42
|
components,
|
|
46
43
|
lazyElements,
|
|
47
44
|
props,
|
|
48
|
-
|
|
45
|
+
omittedProps,
|
|
49
46
|
};
|
|
50
47
|
|
|
51
|
-
if (!options.
|
|
52
|
-
const {
|
|
48
|
+
if (!options.isForced && !options.isGiRegenerated) {
|
|
49
|
+
const { isFresh, intrinsicElementCount } = jsxStoreFreshness(options.jsx.storeDir, fingerprintInput);
|
|
53
50
|
|
|
54
|
-
if (
|
|
55
|
-
return {
|
|
51
|
+
if (isFresh) {
|
|
52
|
+
return { isRegenerated: false, intrinsicElementCount };
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
const { namespaces, metadata, intrinsicElementCount } = generateJsxFiles(options.getLibrary(), {
|
|
56
|
+
const { namespaces, metadata, intrinsicElementCount, elements } = generateJsxFiles(options.getLibrary(), {
|
|
60
57
|
reactSubexports: options.reactSubexports,
|
|
61
58
|
components,
|
|
62
59
|
lazyElements,
|
|
63
60
|
props,
|
|
64
|
-
|
|
61
|
+
omittedProps,
|
|
65
62
|
});
|
|
66
63
|
|
|
67
|
-
writeJsxStore(options.jsx, namespaces, metadata,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
writeJsxStore(options.jsx, namespaces, metadata, [
|
|
65
|
+
{
|
|
66
|
+
relativePath: FINGERPRINT_FILENAME,
|
|
67
|
+
content: `${JSON.stringify(computeJsxFingerprint(fingerprintInput, intrinsicElementCount), null, 2)}\n`,
|
|
68
|
+
},
|
|
69
|
+
{ relativePath: ELEMENTS_FILENAME, content: renderGeneratedElements(elements) },
|
|
70
|
+
]);
|
|
71
71
|
|
|
72
|
-
return {
|
|
72
|
+
return { isRegenerated: true, intrinsicElementCount };
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
export { runJsxCodegen
|
|
75
|
+
export { runJsxCodegen };
|
package/src/khronos/args.ts
CHANGED
|
@@ -52,7 +52,7 @@ type BuildArgOptions = {
|
|
|
52
52
|
const OUT_PLAN_KINDS: Set<string> = new Set(["ref-out", "ref-array-out", "ref-fixed-out", "string-out"]);
|
|
53
53
|
|
|
54
54
|
const scalarAliasOrGroup = (scalar: GlScalar, group: string | undefined): string =>
|
|
55
|
-
group !== undefined && scalar.
|
|
55
|
+
group !== undefined && scalar.isGroupBearing === true ? group : scalar.tsAlias;
|
|
56
56
|
|
|
57
57
|
const paramIndexByName = (command: GlCommand, name: string): number => {
|
|
58
58
|
const index = command.params.findIndex((param) => param.name === name);
|
package/src/khronos/pipeline.ts
CHANGED
package/src/khronos/plan.ts
CHANGED
|
@@ -5,13 +5,13 @@ type GlScalar = {
|
|
|
5
5
|
descriptor: string;
|
|
6
6
|
tsAlias: string;
|
|
7
7
|
viewType?: string;
|
|
8
|
-
|
|
8
|
+
isGroupBearing?: boolean;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
type ParsedCType = {
|
|
12
12
|
base: string;
|
|
13
13
|
pointers: number;
|
|
14
|
-
|
|
14
|
+
isConstData: boolean;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
type ParamPlan =
|
|
@@ -61,10 +61,10 @@ type CommandPlan =
|
|
|
61
61
|
type ParamOutcome = { plan: ParamPlan } | { reason: GlExclusionReason };
|
|
62
62
|
|
|
63
63
|
const GL_SCALARS: Map<string, GlScalar> = new Map([
|
|
64
|
-
["GLenum", { descriptor: tScalar("uint32"), tsAlias: "GLenum", viewType: "Uint32Array",
|
|
64
|
+
["GLenum", { descriptor: tScalar("uint32"), tsAlias: "GLenum", viewType: "Uint32Array", isGroupBearing: true }],
|
|
65
65
|
[
|
|
66
66
|
"GLbitfield",
|
|
67
|
-
{ descriptor: tScalar("uint32"), tsAlias: "GLbitfield", viewType: "Uint32Array",
|
|
67
|
+
{ descriptor: tScalar("uint32"), tsAlias: "GLbitfield", viewType: "Uint32Array", isGroupBearing: true },
|
|
68
68
|
],
|
|
69
69
|
["GLuint", { descriptor: tScalar("uint32"), tsAlias: "GLuint", viewType: "Uint32Array" }],
|
|
70
70
|
["GLint", { descriptor: tScalar("int32"), tsAlias: "GLint", viewType: "Int32Array" }],
|
|
@@ -96,7 +96,7 @@ const parseCType = (cType: string): ParsedCType => {
|
|
|
96
96
|
.filter((token) => token.length > 0 && token !== "const" && token !== "struct")
|
|
97
97
|
.join(" ");
|
|
98
98
|
|
|
99
|
-
return { base, pointers,
|
|
99
|
+
return { base, pointers, isConstData };
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
const isCompsize = (len: string): boolean => len.includes("COMPSIZE(");
|
|
@@ -158,11 +158,11 @@ const charStringOutLen = (command: GlCommand, param: GlParam, parsed: ParsedCTyp
|
|
|
158
158
|
};
|
|
159
159
|
|
|
160
160
|
const planCharParam = (command: GlCommand, param: GlParam, parsed: ParsedCType): ParamOutcome => {
|
|
161
|
-
if (parsed.pointers === 1 && parsed.
|
|
161
|
+
if (parsed.pointers === 1 && parsed.isConstData) {
|
|
162
162
|
return { plan: { kind: "string-in" } };
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
if (parsed.pointers === 2 && parsed.
|
|
165
|
+
if (parsed.pointers === 2 && parsed.isConstData) {
|
|
166
166
|
return { plan: { kind: "string-array-in" } };
|
|
167
167
|
}
|
|
168
168
|
|
|
@@ -191,7 +191,7 @@ const planScalarParam = (
|
|
|
191
191
|
return { plan: { kind: "scalar", scalar } };
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
if (parsed.pointers === 1 && parsed.
|
|
194
|
+
if (parsed.pointers === 1 && parsed.isConstData) {
|
|
195
195
|
return { plan: { kind: "array-in", scalar } };
|
|
196
196
|
}
|
|
197
197
|
|