@gtkx/codegen 1.0.0-rc.2 → 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 +2 -2
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +30 -32
- 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 +7 -13
- 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 +66 -8
- 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 -4
- package/dist/docs/element-page.js.map +1 -1
- package/dist/docs/pipeline.d.ts +5 -3
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +5 -3
- 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 -4
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +7 -6
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +7 -10
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +4 -9
- 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 +17 -3
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +14 -1
- 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 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- 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 +8 -11
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +18 -15
- 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 +18 -9
- package/dist/react/element-config.d.ts.map +1 -1
- package/dist/react/element-config.js +23 -13
- package/dist/react/element-config.js.map +1 -1
- package/dist/runner.d.ts +36 -16
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +22 -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.d.ts.map +1 -1
- package/dist/store/gi/callables.js +4 -9
- 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 -7
- 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 +26 -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-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +5 -4
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +3 -2
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +21 -11
- 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/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +0 -7
- package/dist/store/gi/record.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 +7 -0
- package/dist/store/gi/value-marshalable.d.ts.map +1 -0
- package/dist/store/gi/value-marshalable.js +57 -0
- package/dist/store/gi/value-marshalable.js.map +1 -0
- 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/intrinsic-elements.d.ts +1 -2
- package/dist/store/jsx/intrinsic-elements.d.ts.map +1 -1
- package/dist/store/jsx/intrinsic-elements.js +1 -2
- package/dist/store/jsx/intrinsic-elements.js.map +1 -1
- 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 +8 -0
- package/dist/store/jsx/omitted-props.d.ts.map +1 -0
- package/dist/store/jsx/omitted-props.js +20 -0
- package/dist/store/jsx/omitted-props.js.map +1 -0
- package/dist/store/jsx/pipeline.d.ts +4 -0
- package/dist/store/jsx/pipeline.d.ts.map +1 -1
- package/dist/store/jsx/pipeline.js +4 -1
- package/dist/store/jsx/pipeline.js.map +1 -1
- package/dist/store/jsx/props.d.ts +1 -1
- package/dist/store/jsx/props.d.ts.map +1 -1
- package/dist/store/jsx/props.js +8 -13
- 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 -11
- package/src/analysis/descriptor-render.ts +45 -38
- package/src/analysis/descriptor.ts +13 -13
- package/src/analysis/param-structure.ts +8 -10
- package/src/analysis/ts-type.ts +8 -17
- package/src/compile.ts +2 -1
- package/src/docs/api-reference.ts +131 -13
- package/src/docs/element-page.ts +5 -9
- package/src/docs/pipeline.ts +9 -6
- package/src/docs/render.ts +7 -7
- package/src/docs/symbol-page.ts +7 -2
- package/src/fingerprint.ts +21 -12
- package/src/gi.ts +13 -11
- package/src/gir/field.ts +0 -4
- package/src/gir/gir-path.ts +7 -0
- package/src/gir/libraries.ts +18 -4
- 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 -15
- package/src/internal.ts +2 -0
- package/src/jsx.ts +26 -21
- 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 +25 -16
- package/src/runner.ts +62 -37
- package/src/store/compile-store.ts +3 -4
- package/src/store/gi/callables.ts +5 -11
- package/src/store/gi/constant.ts +0 -2
- package/src/store/gi/function.ts +1 -7
- package/src/store/gi/method.ts +31 -28
- package/src/store/gi/property-accessor.ts +6 -8
- package/src/store/gi/record-constructor.ts +9 -4
- package/src/store/gi/record-field-accessor.ts +41 -12
- package/src/store/gi/record-layout.ts +0 -4
- package/src/store/gi/record.ts +0 -9
- package/src/store/gi/return-wrap.ts +5 -5
- package/src/store/gi/signal.ts +17 -17
- package/src/store/gi/value-marshalable.ts +87 -0
- 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/intrinsic-elements.ts +0 -9
- package/src/store/jsx/jsx.ts +7 -7
- package/src/store/jsx/metadata.ts +8 -8
- package/src/store/jsx/omitted-props.ts +30 -0
- package/src/store/jsx/pipeline.ts +6 -1
- package/src/store/jsx/props.ts +8 -20
- 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/dist/store/gi/class-struct-record.d.ts +0 -10
- package/dist/store/gi/class-struct-record.d.ts.map +0 -1
- package/dist/store/gi/class-struct-record.js +0 -52
- package/dist/store/gi/class-struct-record.js.map +0 -1
- package/src/store/gi/class-struct-record.ts +0 -72
package/src/store/gi/signal.ts
CHANGED
|
@@ -28,7 +28,7 @@ type SignalMapSpec = {
|
|
|
28
28
|
context: ModuleContext;
|
|
29
29
|
klass: GirClass;
|
|
30
30
|
className: string;
|
|
31
|
-
|
|
31
|
+
isParentlessObjectSubclass: boolean;
|
|
32
32
|
suffix: string;
|
|
33
33
|
renderEntry: (context: ModuleContext, signal: GirCallable) => string;
|
|
34
34
|
};
|
|
@@ -66,7 +66,7 @@ const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[]
|
|
|
66
66
|
|
|
67
67
|
const connectDefault = isRootObject
|
|
68
68
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + signal + \"'\");"
|
|
69
|
-
: "default:\n return super.connect(signal, handler,
|
|
69
|
+
: "default:\n return super.connect(signal, handler, isAfter);";
|
|
70
70
|
|
|
71
71
|
const emitDefault = isRootObject
|
|
72
72
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + sigName + \"'\");"
|
|
@@ -78,7 +78,10 @@ const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[]
|
|
|
78
78
|
const emitSwitch = `switch (getSignalBaseName(sigName)) {\n${emitBody}\n}`;
|
|
79
79
|
|
|
80
80
|
return [
|
|
81
|
-
renderBlock(
|
|
81
|
+
renderBlock(
|
|
82
|
+
`connect(signal: string, handler: ${SIGNAL_HANDLER_TYPE}, isAfter?: boolean): number`,
|
|
83
|
+
connectSwitch,
|
|
84
|
+
),
|
|
82
85
|
renderBlock("emit(sigName: string, ...args: unknown[]): unknown", emitSwitch),
|
|
83
86
|
];
|
|
84
87
|
};
|
|
@@ -89,7 +92,7 @@ const renderSignalDeclarations = (
|
|
|
89
92
|
className: string,
|
|
90
93
|
isParentlessObjectSubclass: boolean,
|
|
91
94
|
): string[] => {
|
|
92
|
-
const base = { context, klass, className,
|
|
95
|
+
const base = { context, klass, className, isParentlessObjectSubclass };
|
|
93
96
|
|
|
94
97
|
const declarations = [
|
|
95
98
|
renderSignalMap({ ...base, suffix: SIGNALS_SUFFIX, renderEntry: renderSignalHandlerType }),
|
|
@@ -110,8 +113,8 @@ const renderSignalDeclarations = (
|
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
113
|
-
const { context, klass, className,
|
|
114
|
-
const extendsRefs = signalMapParentRefs(context, klass,
|
|
116
|
+
const { context, klass, className, isParentlessObjectSubclass, suffix, renderEntry } = spec;
|
|
117
|
+
const extendsRefs = signalMapParentRefs(context, klass, isParentlessObjectSubclass, suffix);
|
|
115
118
|
const extendsClause = extendsRefs.length === 0 ? "" : ` extends ${extendsRefs.join(", ")}`;
|
|
116
119
|
|
|
117
120
|
const signalEntries = collectClassSignals(context, klass).map((signal) => {
|
|
@@ -177,8 +180,8 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
177
180
|
|
|
178
181
|
const lines = [
|
|
179
182
|
`__signals__?: ${map};`,
|
|
180
|
-
`connect<K extends keyof ${map}>(signal: K, handler: ${map}[K],
|
|
181
|
-
`connect(signal: string, handler: ${SIGNAL_HANDLER_TYPE},
|
|
183
|
+
`connect<K extends keyof ${map}>(signal: K, handler: ${map}[K], isAfter?: boolean): number;`,
|
|
184
|
+
`connect(signal: string, handler: ${SIGNAL_HANDLER_TYPE}, isAfter?: boolean): number;`,
|
|
182
185
|
`emit<K extends keyof ${emitMap}>(sigName: K, ...args: ${emitMap}[K]["args"]): ${emitMap}[K]["result"];`,
|
|
183
186
|
"emit(sigName: string, ...args: unknown[]): unknown;",
|
|
184
187
|
];
|
|
@@ -193,7 +196,7 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
193
196
|
}
|
|
194
197
|
};
|
|
195
198
|
|
|
196
|
-
chainable(["on", "once", "addEventListener"], ",
|
|
199
|
+
chainable(["on", "once", "addEventListener"], ", isAfter?: boolean");
|
|
197
200
|
chainable(["off", "removeEventListener"], "");
|
|
198
201
|
}
|
|
199
202
|
|
|
@@ -216,8 +219,8 @@ const renderResultType = (
|
|
|
216
219
|
library: context.library,
|
|
217
220
|
signal,
|
|
218
221
|
renderType: (ref, nullable) => renderTsType(context, ref, nullable),
|
|
219
|
-
|
|
220
|
-
|
|
222
|
+
shouldIncludeCallerAllocated,
|
|
223
|
+
isOptOut,
|
|
221
224
|
});
|
|
222
225
|
|
|
223
226
|
const renderSignalEmitEntry = (context: ModuleContext, signal: GirCallable): string => {
|
|
@@ -237,7 +240,7 @@ const nonVarargParameters = (signal: GirCallable): GirParameter[] =>
|
|
|
237
240
|
|
|
238
241
|
const renderConnectCase = (context: ModuleContext, signal: GirCallable): string => {
|
|
239
242
|
const callback = renderCallback(context, signal);
|
|
240
|
-
const body = `return connectSignal(this, signal, { callback: ${callback}, handler,
|
|
243
|
+
const body = `return connectSignal(this, signal, { callback: ${callback}, handler, isAfter: isAfter ?? false });`;
|
|
241
244
|
|
|
242
245
|
return renderBlock(`case ${sourceStringLiteral(signal.name)}:`, body);
|
|
243
246
|
};
|
|
@@ -260,7 +263,7 @@ const renderEmitArgLiteral = (options: EmitArgOptions): { literal: string; nextA
|
|
|
260
263
|
const value = renderCallerOutAllocation(context, parameter);
|
|
261
264
|
|
|
262
265
|
return {
|
|
263
|
-
literal: `{ type: ${descriptor}, direction: "out",
|
|
266
|
+
literal: `{ type: ${descriptor}, direction: "out", isCallerAllocated: true, value: ${value} }`,
|
|
264
267
|
nextArgIndex: argIndex,
|
|
265
268
|
};
|
|
266
269
|
}
|
|
@@ -268,7 +271,7 @@ const renderEmitArgLiteral = (options: EmitArgOptions): { literal: string; nextA
|
|
|
268
271
|
if (isRecordInout(context, parameter)) {
|
|
269
272
|
return {
|
|
270
273
|
literal:
|
|
271
|
-
`{ type: ${descriptor}, direction: "inout",
|
|
274
|
+
`{ type: ${descriptor}, direction: "inout", isCallerAllocated: true, ` +
|
|
272
275
|
`value: args[${String(argIndex)}] }`,
|
|
273
276
|
nextArgIndex: argIndex + 1,
|
|
274
277
|
};
|
|
@@ -328,9 +331,6 @@ const renderCallerOutAllocation = (context: ModuleContext, parameter: GirParamet
|
|
|
328
331
|
const renderCallback = (context: ModuleContext, signal: GirCallable): string => {
|
|
329
332
|
const params = nonVarargParameters(signal);
|
|
330
333
|
|
|
331
|
-
// The emitted argument list prepends the instance the signal was raised on, so every index a
|
|
332
|
-
// parameter descriptor carries (an array's `sizeParamIndex`, above all) sits one slot further
|
|
333
|
-
// right than the position GIR assigned it.
|
|
334
334
|
const callbackParamDescriptors = params.map((parameter) =>
|
|
335
335
|
renderParamDescriptor(context, parameter, parameter.type, { argIndexOffset: 1 }),
|
|
336
336
|
);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { GirField } from "../../gir/field.js";
|
|
2
|
+
import type { PrimitiveCategory } from "../../gir/primitives.js";
|
|
3
|
+
import type { GirRecord } from "../../gir/record.js";
|
|
4
|
+
import type { TypeId } from "../../gir/type-id.js";
|
|
5
|
+
import type { GirType } from "../../gir/type.js";
|
|
6
|
+
import type { ModuleContext } from "../../writer/context.js";
|
|
7
|
+
|
|
8
|
+
type Scope = { context: ModuleContext; seen: Set<string> };
|
|
9
|
+
|
|
10
|
+
const POINTER_CATEGORIES: Set<PrimitiveCategory> = new Set<PrimitiveCategory>(["string", "pointer"]);
|
|
11
|
+
|
|
12
|
+
const recordKey = (namespaceName: string, record: GirRecord): string => `${namespaceName}.${record.name}`;
|
|
13
|
+
|
|
14
|
+
const hasOwnCopySemantics = (record: GirRecord): boolean =>
|
|
15
|
+
record.glibGetType !== undefined ||
|
|
16
|
+
((record.glibRefFunc ?? record.copyFunc) !== undefined && (record.glibUnrefFunc ?? record.freeFunc) !== undefined);
|
|
17
|
+
|
|
18
|
+
const isValueSafeArray = (scope: Scope, type: Extract<GirType, { kind: "carray" }>): boolean =>
|
|
19
|
+
type.fixedSize !== undefined && isValueSafeRef(scope, type.element, type.elementCType);
|
|
20
|
+
|
|
21
|
+
const isValueSafeAlias = (scope: Scope, type: Extract<GirType, { kind: "alias" }>): boolean =>
|
|
22
|
+
isValueSafeRef(scope, type.value.target, type.value.targetCType);
|
|
23
|
+
|
|
24
|
+
function isValueSafeType(scope: Scope, type: GirType): boolean {
|
|
25
|
+
switch (type.kind) {
|
|
26
|
+
case "primitive": {
|
|
27
|
+
return !POINTER_CATEGORIES.has(type.category);
|
|
28
|
+
}
|
|
29
|
+
case "enum": {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
case "record": {
|
|
33
|
+
return isValueSafeRecord(scope, type.namespace.name, type.value);
|
|
34
|
+
}
|
|
35
|
+
case "carray": {
|
|
36
|
+
return isValueSafeArray(scope, type);
|
|
37
|
+
}
|
|
38
|
+
case "alias": {
|
|
39
|
+
return isValueSafeAlias(scope, type);
|
|
40
|
+
}
|
|
41
|
+
case "callback":
|
|
42
|
+
case "class":
|
|
43
|
+
case "hashtable":
|
|
44
|
+
case "interface":
|
|
45
|
+
case "list":
|
|
46
|
+
case "varargs": {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isValueSafeRef(scope: Scope, ref: TypeId | undefined, cType: string | undefined): boolean {
|
|
53
|
+
if (ref === undefined || cType?.endsWith("*") === true) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const type = scope.context.library.typeFor(ref);
|
|
58
|
+
|
|
59
|
+
return type === undefined ? false : isValueSafeType(scope, type);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const isValueSafeField = (scope: Scope, field: GirField): boolean =>
|
|
63
|
+
field.inlineMembers === undefined
|
|
64
|
+
? isValueSafeRef(scope, field.type, field.cType)
|
|
65
|
+
: field.inlineMembers.every((member) => isValueSafeField(scope, member));
|
|
66
|
+
|
|
67
|
+
function isValueSafeRecord(scope: Scope, namespaceName: string, record: GirRecord): boolean {
|
|
68
|
+
const key = recordKey(namespaceName, record);
|
|
69
|
+
|
|
70
|
+
if (scope.seen.has(key) || record.fields.length === 0) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
scope.seen.add(key);
|
|
75
|
+
const isSafe = record.fields.every((field) => isValueSafeField(scope, field));
|
|
76
|
+
scope.seen.delete(key);
|
|
77
|
+
|
|
78
|
+
return isSafe;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const isValueMarshalable = (context: ModuleContext, namespaceName: string, record: GirRecord): boolean =>
|
|
82
|
+
isValueSafeRecord({ context, seen: new Set<string>() }, namespaceName, record);
|
|
83
|
+
|
|
84
|
+
const isConstructibleRecord = (context: ModuleContext, namespaceName: string, record: GirRecord): boolean =>
|
|
85
|
+
hasOwnCopySemantics(record) || isValueMarshalable(context, namespaceName, record);
|
|
86
|
+
|
|
87
|
+
export { hasOwnCopySemantics, isConstructibleRecord, isValueMarshalable };
|
package/src/store/gi-store.ts
CHANGED
|
@@ -4,8 +4,6 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import { FINGERPRINT_FILENAME, type GiFingerprint } from "../fingerprint.js";
|
|
5
5
|
import { buildManifest, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
6
6
|
|
|
7
|
-
type GiStoreOptions = StoreOptions;
|
|
8
|
-
|
|
9
7
|
type GiNamespaceInput = {
|
|
10
8
|
directory: string;
|
|
11
9
|
rawSource: string;
|
|
@@ -69,7 +67,7 @@ const collectStoreSources = (
|
|
|
69
67
|
};
|
|
70
68
|
|
|
71
69
|
const writeGiStore = (
|
|
72
|
-
options:
|
|
70
|
+
options: StoreOptions,
|
|
73
71
|
namespaces: GiNamespaceInput[],
|
|
74
72
|
fingerprint: GiFingerprint,
|
|
75
73
|
): void => {
|
|
@@ -89,4 +87,4 @@ const writeGiStore = (
|
|
|
89
87
|
});
|
|
90
88
|
};
|
|
91
89
|
|
|
92
|
-
export { writeGiStore, type
|
|
90
|
+
export { writeGiStore, type GiNamespaceInput };
|
|
@@ -6,9 +6,7 @@ import type { LazyElementSpec } from "./element-prop-types.js";
|
|
|
6
6
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
7
7
|
import { ancestorGlibNames, type GlibNamedClass } from "./intrinsic-elements.js";
|
|
8
8
|
|
|
9
|
-
/** A component that wraps a generated element, keyed by GLib type name (built-in or user-provided). */
|
|
10
9
|
type ElementComponent = { module: string; export: string };
|
|
11
|
-
/** Component wrappers keyed by GLib type name; the framework's built-ins merged with the project's own. */
|
|
12
10
|
type ElementComponentOverrides = Record<string, ElementComponent>;
|
|
13
11
|
|
|
14
12
|
type ExportCollector = {
|
|
@@ -73,9 +71,6 @@ const appendCandidateExport = (
|
|
|
73
71
|
collector.exportedNames.add(candidate.glibName);
|
|
74
72
|
};
|
|
75
73
|
|
|
76
|
-
// An abstract GType cannot be instantiated: `g_object_new` on one is a fatal GObject error rather
|
|
77
|
-
// than a NULL return. Its props interface and metadata still have to be emitted, since every
|
|
78
|
-
// concrete subclass extends them, so only the constructible component export is withheld.
|
|
79
74
|
const collectCandidateExports = (collector: ExportCollector, options: CandidateExportOptions): void => {
|
|
80
75
|
for (const candidate of options.intrinsicElements) {
|
|
81
76
|
if (candidate.klass.isAbstract) {
|
|
@@ -121,7 +116,6 @@ const renderCandidateExport = (
|
|
|
121
116
|
return `${renderJsDoc(klass.doc)}${renderElementComponentExport(glibName, component)}`;
|
|
122
117
|
};
|
|
123
118
|
|
|
124
|
-
/** The component for the nearest ancestry match, most-derived first; user overrides win on their exact type. */
|
|
125
119
|
const resolveElementComponent = (
|
|
126
120
|
ancestry: string[],
|
|
127
121
|
components: Record<string, ElementComponent>,
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
/** Props interface a generated element's props extend, declared by hand in `@gtkx/react`. */
|
|
2
1
|
type ElementPropTypeRef = { type: string; module: string; export: string };
|
|
2
|
+
|
|
3
3
|
/** Base props interface each element extends, keyed by GLib type name (the module exports it). */
|
|
4
|
-
type ElementProps = Record<string, {
|
|
4
|
+
type ElementProps = Record<string, {
|
|
5
|
+
/** Specifier the props interface is imported from. */
|
|
6
|
+
module: string;
|
|
7
|
+
/** Identifier the module exports it under. */
|
|
8
|
+
export: string;
|
|
9
|
+
}>;
|
|
5
10
|
|
|
6
11
|
const elementProps: Map<string, { module: string; export: string }> = new Map();
|
|
7
12
|
|
|
8
|
-
/** Installs the base props each element extends (GLib type name → `{ module, export }`); set once per run. */
|
|
9
13
|
const setElementProps = (props: ElementProps): void => {
|
|
10
14
|
elementProps.clear();
|
|
11
15
|
|
|
@@ -14,7 +18,6 @@ const setElementProps = (props: ElementProps): void => {
|
|
|
14
18
|
}
|
|
15
19
|
};
|
|
16
20
|
|
|
17
|
-
/** The base props interface an element extends, when its element config declares one. */
|
|
18
21
|
const elementPropTypeFor = (glibName: string): ElementPropTypeRef | undefined => {
|
|
19
22
|
const ref = elementProps.get(glibName);
|
|
20
23
|
|
|
@@ -37,7 +37,6 @@ const createLazyElementSpec = (context: GirIndex, element: string, entry: GirTyp
|
|
|
37
37
|
return { element, typeName, typeSource: `export type ${typeName} = ${base} & { children?: ReactNode };` };
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
/** Lazy element prop types to emit, grouped by the namespace declaring each element. */
|
|
41
40
|
const lazyElementSpecs = (context: GirIndex, lazyElements: string[]): Map<string, LazyElementSpec[]> => {
|
|
42
41
|
const specs: Map<string, LazyElementSpec[]> = new Map();
|
|
43
42
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { GlibNamedClass } from "./intrinsic-elements.js";
|
|
4
|
+
import { namespaceDirectory } from "../../gir/namespace.js";
|
|
5
|
+
|
|
6
|
+
/** One element the `@gtkx/jsx` store binds. */
|
|
7
|
+
type GeneratedElement = {
|
|
8
|
+
/** GIR namespace name, such as `"Gtk"`. */
|
|
9
|
+
namespace: string;
|
|
10
|
+
/** Subexport the element is reachable through, such as `"gtk"` in `@gtkx/jsx/gtk`. */
|
|
11
|
+
directory: string;
|
|
12
|
+
/** GLib type name, which is also the JSX tag name, such as `"GtkButton"`. */
|
|
13
|
+
glibName: string;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the element can be rendered. An abstract GType is bound for its props and metadata but
|
|
16
|
+
* exports no component, because `g_object_new` on one is a fatal GObject error.
|
|
17
|
+
*/
|
|
18
|
+
isMountable: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ELEMENTS_FILENAME = "elements.json";
|
|
22
|
+
|
|
23
|
+
const collectGeneratedElements = (intrinsicElements: GlibNamedClass[]): GeneratedElement[] =>
|
|
24
|
+
intrinsicElements
|
|
25
|
+
.map((entry) => ({
|
|
26
|
+
namespace: entry.namespace.name,
|
|
27
|
+
directory: namespaceDirectory(entry.namespace),
|
|
28
|
+
glibName: entry.glibName,
|
|
29
|
+
isMountable: !entry.klass.isAbstract,
|
|
30
|
+
}))
|
|
31
|
+
.toSorted((a, b) => a.glibName.localeCompare(b.glibName));
|
|
32
|
+
|
|
33
|
+
const renderGeneratedElements = (elements: GeneratedElement[]): string =>
|
|
34
|
+
`${JSON.stringify(elements, null, 2)}\n`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Reads the inventory of elements the `@gtkx/jsx` store binds, written into the store by codegen. Answers
|
|
38
|
+
* "what does this project's JSX layer cover" without loading the store, which resolves `virtual:` specifiers
|
|
39
|
+
* that only exist inside a Vite or Vitest build.
|
|
40
|
+
*
|
|
41
|
+
* @param jsxStoreDir The jsx store directory, as given by `resolveStore(projectRoot).jsx.storeDir`.
|
|
42
|
+
* @returns Every bound element, sorted by GLib type name, or an empty array when the store has no inventory.
|
|
43
|
+
*/
|
|
44
|
+
const readGeneratedElements = (jsxStoreDir: string): GeneratedElement[] => {
|
|
45
|
+
const path = join(jsxStoreDir, ELEMENTS_FILENAME);
|
|
46
|
+
|
|
47
|
+
if (!existsSync(path)) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return JSON.parse(readFileSync(path, "utf8")) as GeneratedElement[];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
ELEMENTS_FILENAME,
|
|
56
|
+
collectGeneratedElements,
|
|
57
|
+
readGeneratedElements,
|
|
58
|
+
renderGeneratedElements,
|
|
59
|
+
type GeneratedElement,
|
|
60
|
+
};
|
|
@@ -214,14 +214,6 @@ const hasMatchingAncestorName = (
|
|
|
214
214
|
isMatch: (glibName: string) => boolean,
|
|
215
215
|
): boolean => hasMatchingAncestor(klass, namespace, library, (_klass, glibName) => isMatch(glibName));
|
|
216
216
|
|
|
217
|
-
const hasExposedMethod = (
|
|
218
|
-
klass: GirClass,
|
|
219
|
-
namespace: GirNamespace,
|
|
220
|
-
library: Library,
|
|
221
|
-
methodName: string,
|
|
222
|
-
): boolean =>
|
|
223
|
-
hasMatchingAncestor(klass, namespace, library, (current) => current.methods.some((m) => m.name === methodName));
|
|
224
|
-
|
|
225
217
|
const isIntrinsicElementClass = (klass: GirClass, namespace: GirNamespace, library: Library): boolean =>
|
|
226
218
|
hasMatchingAncestorName(klass, namespace, library, (glibName) => glibName === "GObject");
|
|
227
219
|
|
|
@@ -253,7 +245,6 @@ export {
|
|
|
253
245
|
newlyImplementedInterfaces,
|
|
254
246
|
collectInterfacePropsClasses,
|
|
255
247
|
ancestorGlibNames,
|
|
256
|
-
hasExposedMethod,
|
|
257
248
|
isIntrinsicElementClass,
|
|
258
249
|
collectIntrinsicElementClasses,
|
|
259
250
|
type GlibNamedClass,
|
package/src/store/jsx/jsx.ts
CHANGED
|
@@ -109,7 +109,7 @@ const generateJsxSection = (
|
|
|
109
109
|
addReactBuiltin(imports, "ReactNode");
|
|
110
110
|
addReactBuiltin(imports, "Ref");
|
|
111
111
|
const interfaceResult = renderInterfacePropBlocks(library, targetNamespace.name, options);
|
|
112
|
-
let
|
|
112
|
+
let requiresReactElement = interfaceResult.requiresReactElement;
|
|
113
113
|
const propBlocks: string[] = [...interfaceResult.blocks];
|
|
114
114
|
|
|
115
115
|
const blockContext: RenderPropBlockContext = {
|
|
@@ -124,13 +124,13 @@ const generateJsxSection = (
|
|
|
124
124
|
const { block, objectPropNames } = renderPropBlock(library, entry, blockContext);
|
|
125
125
|
|
|
126
126
|
if (objectPropNames.length > 0) {
|
|
127
|
-
|
|
127
|
+
requiresReactElement = true;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
propBlocks.push(block);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
if (
|
|
133
|
+
if (requiresReactElement) {
|
|
134
134
|
addReactBuiltin(imports, "ReactElement");
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -152,11 +152,11 @@ const renderInterfacePropBlocks = (
|
|
|
152
152
|
library: Library,
|
|
153
153
|
targetNamespaceName: string,
|
|
154
154
|
options: GenerateJsxOptions,
|
|
155
|
-
): { blocks: string[];
|
|
155
|
+
): { blocks: string[]; requiresReactElement: boolean; hasContainerProps: HasContainerProps } => {
|
|
156
156
|
const { imports, intrinsicElements } = options;
|
|
157
157
|
const context: InterfaceBlockContext = { library, targetNamespaceName, imports, hasContainerProps };
|
|
158
158
|
const blocks: string[] = [];
|
|
159
|
-
let
|
|
159
|
+
let requiresReactElement = false;
|
|
160
160
|
|
|
161
161
|
for (const iface of collectInterfacePropsClasses(
|
|
162
162
|
library,
|
|
@@ -173,13 +173,13 @@ const renderInterfacePropBlocks = (
|
|
|
173
173
|
const { block, objectPropNames } = renderInterfacePropsBlock(iface, glibName, context);
|
|
174
174
|
|
|
175
175
|
if (objectPropNames.length > 0) {
|
|
176
|
-
|
|
176
|
+
requiresReactElement = true;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
blocks.push(block);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
return { blocks,
|
|
182
|
+
return { blocks, requiresReactElement, hasContainerProps };
|
|
183
183
|
};
|
|
184
184
|
|
|
185
185
|
const registerCrossNsProps = (
|
|
@@ -23,7 +23,7 @@ type IntrinsicElementEntry = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
type PropNameCollector = {
|
|
26
|
-
|
|
26
|
+
shouldKeep: (property: GirProperty) => boolean;
|
|
27
27
|
seen: Set<string>;
|
|
28
28
|
names: string[];
|
|
29
29
|
};
|
|
@@ -57,10 +57,10 @@ const generateMetadata = (library: Library): string => {
|
|
|
57
57
|
.map(({ glibName, defaults }) => ` "${glibName}": ${renderDefaultsObject(defaults)},`);
|
|
58
58
|
|
|
59
59
|
return `${[
|
|
60
|
-
`export const
|
|
61
|
-
`export const
|
|
62
|
-
`export const
|
|
63
|
-
`export const
|
|
60
|
+
`export const signals: Record<string, Record<string, string>> = {\n${signalsEntries.join("\n")}\n};`,
|
|
61
|
+
`export const constructOnlyProps: Record<string, Set<string>> = {\n${constructOnlyEntries.join("\n")}\n};`,
|
|
62
|
+
`export const constructProps: Record<string, Set<string>> = {\n${constructableEntries.join("\n")}\n};`,
|
|
63
|
+
`export const defaultProps: Record<string, Record<string, unknown>> = {\n${defaultsEntries.join("\n")}\n};`,
|
|
64
64
|
].join("\n\n")}\n`;
|
|
65
65
|
};
|
|
66
66
|
|
|
@@ -114,10 +114,10 @@ const collectSignals = (sources: GirClass[]): [string, string][] => {
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
const collectPropNamesFromSource = (source: GirClass, collector: PropNameCollector): void => {
|
|
117
|
-
const {
|
|
117
|
+
const { shouldKeep, seen, names } = collector;
|
|
118
118
|
|
|
119
119
|
for (const property of source.properties) {
|
|
120
|
-
if (!
|
|
120
|
+
if (!shouldKeep(property)) {
|
|
121
121
|
continue;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -133,7 +133,7 @@ const collectPropNamesFromSource = (source: GirClass, collector: PropNameCollect
|
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
const collectPropNames = (sources: GirClass[], shouldKeep: (property: GirProperty) => boolean): string[] => {
|
|
136
|
-
const collector: PropNameCollector = {
|
|
136
|
+
const collector: PropNameCollector = { shouldKeep, seen: new Set<string>(), names: [] };
|
|
137
137
|
|
|
138
138
|
for (const source of sources) {
|
|
139
139
|
collectPropNamesFromSource(source, collector);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Props left out of the generated element props, keyed by GLib type name. */
|
|
2
|
+
type OmittedProps = Record<string, string[]>;
|
|
3
|
+
|
|
4
|
+
const omittedProps: Map<string, Set<string>> = new Map();
|
|
5
|
+
|
|
6
|
+
const setOmittedProps = (props: OmittedProps): void => {
|
|
7
|
+
omittedProps.clear();
|
|
8
|
+
|
|
9
|
+
for (const [glibName, names] of Object.entries(props)) {
|
|
10
|
+
omittedProps.set(glibName, new Set(names));
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const isOmittedProp = (glibName: string | undefined, jsName: string): boolean =>
|
|
15
|
+
glibName !== undefined && omittedProps.get(glibName)?.has(jsName) === true;
|
|
16
|
+
|
|
17
|
+
/** Merges omitted-prop maps keyed by GLib type name, concatenating the names each map contributes. */
|
|
18
|
+
const mergeOmittedProps = (...maps: OmittedProps[]): OmittedProps => {
|
|
19
|
+
const merged: OmittedProps = {};
|
|
20
|
+
|
|
21
|
+
for (const map of maps) {
|
|
22
|
+
for (const [glibName, names] of Object.entries(map)) {
|
|
23
|
+
merged[glibName] = [...(merged[glibName] ?? []), ...names];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return merged;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { setOmittedProps, isOmittedProp, mergeOmittedProps, type OmittedProps };
|
|
@@ -5,10 +5,12 @@ import { ImportsBuilder } from "../../writer/imports.js";
|
|
|
5
5
|
import { type ElementComponentOverrides, generateElementComponentsSection } from "./element-components.js";
|
|
6
6
|
import { type ElementProps, setElementProps } from "./element-prop-imports.js";
|
|
7
7
|
import { type LazyElementSpec, lazyElementSpecs } from "./element-prop-types.js";
|
|
8
|
+
import { collectGeneratedElements, type GeneratedElement } from "./generated-elements.js";
|
|
8
9
|
import { buildGirIndex } from "./gir-index.js";
|
|
9
10
|
import { collectIntrinsicElementClasses, type GlibNamedClass } from "./intrinsic-elements.js";
|
|
10
11
|
import { generateJsxSection } from "./jsx.js";
|
|
11
12
|
import { generateMetadata } from "./metadata.js";
|
|
13
|
+
import { type OmittedProps, setOmittedProps } from "./omitted-props.js";
|
|
12
14
|
|
|
13
15
|
type JsxNamespaceFile = {
|
|
14
16
|
directory: string;
|
|
@@ -19,12 +21,14 @@ type JsxFiles = {
|
|
|
19
21
|
namespaces: JsxNamespaceFile[];
|
|
20
22
|
metadata: string;
|
|
21
23
|
intrinsicElementCount: number;
|
|
24
|
+
elements: GeneratedElement[];
|
|
22
25
|
};
|
|
23
26
|
|
|
24
27
|
type JsxGenerationOptions = {
|
|
25
28
|
reactSubexports?: string[];
|
|
26
29
|
components?: ElementComponentOverrides;
|
|
27
30
|
props?: ElementProps;
|
|
31
|
+
omittedProps?: OmittedProps;
|
|
28
32
|
lazyElements?: string[];
|
|
29
33
|
};
|
|
30
34
|
|
|
@@ -47,6 +51,7 @@ type JsxNamespaceContext = {
|
|
|
47
51
|
|
|
48
52
|
const generateJsxFiles = (library: Library, options: JsxGenerationOptions = {}): JsxFiles => {
|
|
49
53
|
setElementProps(options.props ?? {});
|
|
54
|
+
setOmittedProps(options.omittedProps ?? {});
|
|
50
55
|
const intrinsicElements = collectIntrinsicElementClasses(library);
|
|
51
56
|
const intrinsicElementByGlibName = new Map(intrinsicElements.map((entry) => [entry.glibName, entry]));
|
|
52
57
|
const girIndex = buildGirIndex(library);
|
|
@@ -63,7 +68,7 @@ const generateJsxFiles = (library: Library, options: JsxGenerationOptions = {}):
|
|
|
63
68
|
|
|
64
69
|
const metadata = generateMetadata(library);
|
|
65
70
|
|
|
66
|
-
return { namespaces, metadata, intrinsicElementCount };
|
|
71
|
+
return { namespaces, metadata, intrinsicElementCount, elements: collectGeneratedElements(intrinsicElements) };
|
|
67
72
|
};
|
|
68
73
|
|
|
69
74
|
const orderedIntrinsicNamespaces = (intrinsicElements: GlibNamedClass[]): GirNamespace[] => {
|
package/src/store/jsx/props.ts
CHANGED
|
@@ -9,12 +9,8 @@ import { renderHandlerParameters, renderHandlerResultType } from "../../analysis
|
|
|
9
9
|
import { recordTypeTarget, renderBaseType, type TsTypeTarget } from "../../analysis/ts-type.js";
|
|
10
10
|
import { type GirProperty, isConstructableProperty } from "../../gir/property.js";
|
|
11
11
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
hasExposedMethod,
|
|
15
|
-
isIntrinsicElementClass,
|
|
16
|
-
signalHandlerName,
|
|
17
|
-
} from "./intrinsic-elements.js";
|
|
12
|
+
import { getGlibName, giNamespaceAlias, isIntrinsicElementClass, signalHandlerName } from "./intrinsic-elements.js";
|
|
13
|
+
import { isOmittedProp } from "./omitted-props.js";
|
|
18
14
|
|
|
19
15
|
type IntrinsicElementPropsEntries = {
|
|
20
16
|
propLines: string[];
|
|
@@ -75,7 +71,7 @@ const appendPropertyLines = (state: PropCollectorState, property: GirProperty, j
|
|
|
75
71
|
const tsType = renderReactPropType(state.types, property.type, false);
|
|
76
72
|
const doc = renderJsDoc(property.doc);
|
|
77
73
|
|
|
78
|
-
if (isObjectProp(state.owner, property
|
|
74
|
+
if (isObjectProp(state.owner.library, property)) {
|
|
79
75
|
state.propLines.push(`${doc}${jsName}?: ${tsType} | ReactElement | null | undefined;`);
|
|
80
76
|
state.objectPropNames.push(jsName);
|
|
81
77
|
|
|
@@ -99,7 +95,7 @@ const acceptCollectorProperty = (state: PropCollectorState, property: GirPropert
|
|
|
99
95
|
|
|
100
96
|
const jsName = toCamelIdentifier(property.name);
|
|
101
97
|
|
|
102
|
-
if (state.seen.has(jsName)) {
|
|
98
|
+
if (state.seen.has(jsName) || isOmittedProp(getGlibName(state.owner.klass), jsName)) {
|
|
103
99
|
return;
|
|
104
100
|
}
|
|
105
101
|
|
|
@@ -215,20 +211,12 @@ const isGObjectType = (library: Library, ref: TypeId | undefined): boolean => {
|
|
|
215
211
|
return isIntrinsicElementClass(resolved.value, resolved.namespace, library);
|
|
216
212
|
};
|
|
217
213
|
|
|
218
|
-
const isObjectProp = (
|
|
214
|
+
const isObjectProp = (library: Library, property: GirProperty): boolean => {
|
|
219
215
|
if (!property.writable || property.constructOnly) {
|
|
220
216
|
return false;
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (jsName === "child" && hasExposedMethod(owner.klass, owner.namespace, owner.library, "set_child")) {
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return true;
|
|
219
|
+
return isGObjectType(library, property.type);
|
|
232
220
|
};
|
|
233
221
|
|
|
234
222
|
const renderSignalHandler = (options: SignalRenderOptions): string => {
|
|
@@ -243,8 +231,8 @@ const renderSignalHandler = (options: SignalRenderOptions): string => {
|
|
|
243
231
|
library: types.library,
|
|
244
232
|
signal,
|
|
245
233
|
renderType: (ref, nullable) => renderReactPropType(types, ref, nullable),
|
|
246
|
-
|
|
247
|
-
|
|
234
|
+
shouldIncludeCallerAllocated: false,
|
|
235
|
+
isOptOut: true,
|
|
248
236
|
});
|
|
249
237
|
|
|
250
238
|
return `(${params.join(", ")}) => ${result}`;
|
package/src/store/jsx-store.ts
CHANGED
|
@@ -2,13 +2,11 @@ import type { JsxNamespaceFile } from "./jsx/pipeline.js";
|
|
|
2
2
|
import type { RawFile } from "./store-fs.js";
|
|
3
3
|
import { buildManifest, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
4
4
|
|
|
5
|
-
type JsxStoreOptions = StoreOptions;
|
|
6
|
-
|
|
7
5
|
const writeJsxStore = (
|
|
8
|
-
options:
|
|
6
|
+
options: StoreOptions,
|
|
9
7
|
namespaces: JsxNamespaceFile[],
|
|
10
8
|
metadata: string,
|
|
11
|
-
|
|
9
|
+
rawFiles: RawFile[],
|
|
12
10
|
): void => {
|
|
13
11
|
const exportsMap: Record<string, unknown> = {
|
|
14
12
|
"./metadata": subpathExport("metadata"),
|
|
@@ -31,9 +29,9 @@ const writeJsxStore = (
|
|
|
31
29
|
exports: exportsMap,
|
|
32
30
|
peerDependencies: { "@gtkx/gi": "*", "@gtkx/react": "*", react: "*" },
|
|
33
31
|
}),
|
|
34
|
-
rawFiles
|
|
35
|
-
|
|
32
|
+
rawFiles,
|
|
33
|
+
requiresEnvReference: true,
|
|
36
34
|
});
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
export { writeJsxStore
|
|
37
|
+
export { writeJsxStore };
|