@gtkx/codegen 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/descriptor-render.d.ts +1 -0
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +56 -28
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +3 -1
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +10 -9
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +24 -3
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +2 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +2 -1
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/pipeline.d.ts +3 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +44 -12
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/fingerprint.d.ts +3 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +4 -0
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +1 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +4 -1
- package/dist/gi.js.map +1 -1
- package/dist/gir/libraries.d.ts +12 -5
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +50 -14
- package/dist/gir/libraries.js.map +1 -1
- package/dist/gir/library.d.ts +5 -0
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +6 -0
- package/dist/gir/library.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/jsx.d.ts +1 -0
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +2 -0
- package/dist/jsx.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +3 -1
- package/dist/runner.js.map +1 -1
- package/dist/store/gi/bootstrap.d.ts +4 -0
- package/dist/store/gi/bootstrap.d.ts.map +1 -0
- package/dist/store/gi/bootstrap.js +48 -0
- package/dist/store/gi/bootstrap.js.map +1 -0
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +75 -28
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/constructor-props.d.ts.map +1 -1
- package/dist/store/gi/constructor-props.js +2 -1
- package/dist/store/gi/constructor-props.js.map +1 -1
- package/dist/store/gi/enum.js +3 -3
- package/dist/store/gi/enum.js.map +1 -1
- package/dist/store/gi/folded.d.ts +14 -0
- package/dist/store/gi/folded.d.ts.map +1 -0
- package/dist/store/gi/folded.js +35 -0
- package/dist/store/gi/folded.js.map +1 -0
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +22 -3
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +11 -1
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/interface.d.ts.map +1 -1
- package/dist/store/gi/interface.js +43 -4
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +2 -0
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/pipeline.d.ts +5 -1
- package/dist/store/gi/pipeline.d.ts.map +1 -1
- package/dist/store/gi/pipeline.js +13 -1
- package/dist/store/gi/pipeline.js.map +1 -1
- package/dist/store/gi/property-accessor.js +1 -1
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +3 -3
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +44 -12
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/registration.js +2 -2
- package/dist/store/gi/registration.js.map +1 -1
- package/dist/store/gi/return-wrap.js +1 -1
- package/dist/store/gi/return-wrap.js.map +1 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +7 -3
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/vtable.d.ts.map +1 -1
- package/dist/store/gi/vtable.js +1 -1
- package/dist/store/gi/vtable.js.map +1 -1
- package/dist/store/gi-store.d.ts +1 -0
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js +16 -7
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/element-components.d.ts.map +1 -1
- package/dist/store/jsx/element-components.js +64 -10
- package/dist/store/jsx/element-components.js.map +1 -1
- package/dist/store/jsx/element-prop-types.d.ts +2 -0
- package/dist/store/jsx/element-prop-types.d.ts.map +1 -1
- package/dist/store/jsx/element-prop-types.js +2 -0
- package/dist/store/jsx/element-prop-types.js.map +1 -1
- package/dist/store/jsx/metadata.d.ts.map +1 -1
- package/dist/store/jsx/metadata.js +28 -1
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx-store.d.ts +1 -0
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +7 -2
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +2 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +1 -1
- package/dist/store/store-fs.js.map +1 -1
- package/dist/writer/context.d.ts +17 -0
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +83 -11
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/emit.d.ts +2 -1
- package/dist/writer/emit.d.ts.map +1 -1
- package/dist/writer/emit.js +2 -1
- package/dist/writer/emit.js.map +1 -1
- package/dist/writer/imports.d.ts.map +1 -1
- package/dist/writer/imports.js +6 -1
- package/dist/writer/imports.js.map +1 -1
- package/dist/writer/module.d.ts +1 -0
- package/dist/writer/module.d.ts.map +1 -1
- package/dist/writer/module.js +6 -1
- package/dist/writer/module.js.map +1 -1
- package/overrides/glib/regex.ts.ejs +2 -0
- package/package.json +4 -4
- package/src/analysis/descriptor-render.ts +79 -30
- package/src/analysis/descriptor.ts +19 -11
- package/src/compile.ts +42 -3
- package/src/docs/api-reference.ts +4 -1
- package/src/docs/pipeline.ts +64 -13
- package/src/fingerprint.ts +7 -0
- package/src/gi.ts +6 -1
- package/src/gir/libraries.ts +64 -16
- package/src/gir/library.ts +9 -0
- package/src/internal.ts +1 -0
- package/src/jsx.ts +3 -0
- package/src/runner.ts +5 -1
- package/src/store/gi/bootstrap.ts +64 -0
- package/src/store/gi/class.ts +100 -29
- package/src/store/gi/constructor-props.ts +2 -1
- package/src/store/gi/enum.ts +4 -4
- package/src/store/gi/folded.ts +57 -0
- package/src/store/gi/function.ts +22 -3
- package/src/store/gi/gtype-binding.ts +15 -2
- package/src/store/gi/interface.ts +64 -7
- package/src/store/gi/method.ts +2 -0
- package/src/store/gi/pipeline.ts +21 -2
- package/src/store/gi/property-accessor.ts +1 -1
- package/src/store/gi/record-field-accessor.ts +5 -3
- package/src/store/gi/record.ts +61 -14
- package/src/store/gi/registration.ts +2 -2
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +8 -3
- package/src/store/gi/vtable.ts +1 -0
- package/src/store/gi-store.ts +19 -7
- package/src/store/jsx/element-components.ts +107 -10
- package/src/store/jsx/element-prop-types.ts +4 -0
- package/src/store/jsx/metadata.ts +41 -0
- package/src/store/jsx-store.ts +10 -4
- package/src/store/store-fs.ts +3 -2
- package/src/writer/context.ts +109 -16
- package/src/writer/emit.ts +3 -1
- package/src/writer/imports.ts +9 -1
- package/src/writer/module.ts +9 -1
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
renderStaticHead,
|
|
22
22
|
} from "./callables.js";
|
|
23
23
|
import { annotationSpec, getDoc } from "./doc-spec.js";
|
|
24
|
+
import { declareFoldedClass, localClassName } from "./folded.js";
|
|
24
25
|
import { gtypeMemberDeclaration, renderSourceGtype } from "./gtype-binding.js";
|
|
25
26
|
import { methodExportName } from "./method.js";
|
|
26
27
|
import {
|
|
@@ -89,8 +90,15 @@ const generateInterface = (context: ModuleContext, iface: GirClass): void => {
|
|
|
89
90
|
generateBindings(context, callables);
|
|
90
91
|
const gtypeExpr = renderSourceGtype(context, iface);
|
|
91
92
|
const implRef = appendInterfaceTypes(context, iface, className, callables) ?? "unknown";
|
|
93
|
+
|
|
94
|
+
if (gtypeExpr !== undefined && context.isTreeShaken) {
|
|
95
|
+
declareTreeShakenInterface(context, { iface, className, callables, gtypeExpr, implRef });
|
|
96
|
+
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
92
100
|
const classCode = renderInterfaceClass(context, { iface, className, callables, gtypeExpr, implRef });
|
|
93
|
-
context.declare({ name: className, code: classCode
|
|
101
|
+
context.declare({ name: className, code: `${getDoc(iface)}${classCode}`, owner: iface.name });
|
|
94
102
|
|
|
95
103
|
for (const declaration of renderSignalDeclarations(context, iface, className, true)) {
|
|
96
104
|
context.declare(declaration);
|
|
@@ -109,6 +117,53 @@ const generateInterface = (context: ModuleContext, iface: GirClass): void => {
|
|
|
109
117
|
});
|
|
110
118
|
};
|
|
111
119
|
|
|
120
|
+
const declareTreeShakenInterface = (
|
|
121
|
+
context: ModuleContext,
|
|
122
|
+
options: Omit<InterfaceClassOptions, "gtypeExpr"> & { gtypeExpr: string },
|
|
123
|
+
): void => {
|
|
124
|
+
const { iface, className, callables } = options;
|
|
125
|
+
|
|
126
|
+
for (const declaration of renderSignalDeclarations(context, iface, className, true)) {
|
|
127
|
+
context.declare(declaration);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
context.declare({
|
|
131
|
+
name: makerName(className),
|
|
132
|
+
code: renderInterfaceMaker(context, iface, className, callables),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
generateFoldedInterface(context, options);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const generateFoldedInterface = (
|
|
139
|
+
context: ModuleContext,
|
|
140
|
+
options: Omit<InterfaceClassOptions, "gtypeExpr"> & { gtypeExpr: string },
|
|
141
|
+
): void => {
|
|
142
|
+
const { iface, className, callables, gtypeExpr, implRef } = options;
|
|
143
|
+
const localName = localClassName(className);
|
|
144
|
+
context.beginRegistrations();
|
|
145
|
+
|
|
146
|
+
appendInterfaceRegistration(context, {
|
|
147
|
+
className: localName,
|
|
148
|
+
makerName: makerName(className),
|
|
149
|
+
gtypeExpr,
|
|
150
|
+
layout: renderInterfaceLayout(context, iface, callables),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const registrations = context.takeRegistrations();
|
|
154
|
+
const classCode = renderInterfaceClass(context, { iface, className, callables, gtypeExpr, implRef }, localName);
|
|
155
|
+
|
|
156
|
+
declareFoldedClass({
|
|
157
|
+
context,
|
|
158
|
+
className,
|
|
159
|
+
doc: getDoc(iface),
|
|
160
|
+
owner: iface.name,
|
|
161
|
+
localDeclaration: classCode,
|
|
162
|
+
registrations,
|
|
163
|
+
hasInstanceInterface: false,
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
112
167
|
const makerName = (className: string): string => `make${className}`;
|
|
113
168
|
|
|
114
169
|
const renderInterfaceLayout = (
|
|
@@ -373,8 +428,12 @@ const renderInterfaceTypeMembers = (context: ModuleContext, iface: GirClass, cal
|
|
|
373
428
|
...interfaceVfuncMembers(context, iface, "signature"),
|
|
374
429
|
];
|
|
375
430
|
|
|
376
|
-
const renderInterfaceClass = (
|
|
377
|
-
|
|
431
|
+
const renderInterfaceClass = (
|
|
432
|
+
context: ModuleContext,
|
|
433
|
+
options: InterfaceClassOptions,
|
|
434
|
+
localName?: string,
|
|
435
|
+
): string => {
|
|
436
|
+
const { className, callables, gtypeExpr, implRef } = options;
|
|
378
437
|
const members: string[] = [];
|
|
379
438
|
|
|
380
439
|
if (gtypeExpr !== undefined) {
|
|
@@ -382,11 +441,9 @@ const renderInterfaceClass = (context: ModuleContext, options: InterfaceClassOpt
|
|
|
382
441
|
}
|
|
383
442
|
|
|
384
443
|
members.push(...renderStaticHead(context, callables, className), renderInterfaceBrand(context, implRef));
|
|
444
|
+
const head = localName === undefined ? `export abstract class ${className}` : `abstract class ${localName}`;
|
|
385
445
|
|
|
386
|
-
return
|
|
387
|
-
`export abstract class ${className}`,
|
|
388
|
-
members.join("\n\n"),
|
|
389
|
-
)}`;
|
|
446
|
+
return renderBracedOrEmpty(head, members.join("\n\n"));
|
|
390
447
|
};
|
|
391
448
|
|
|
392
449
|
const renderInterfaceBrand = (context: ModuleContext, implRef: string): string => {
|
package/src/store/gi/method.ts
CHANGED
|
@@ -438,6 +438,7 @@ const renderReturnDescriptor = (context: ModuleContext, fn: GirFunction): Return
|
|
|
438
438
|
argIndexOffset: instanceOffset,
|
|
439
439
|
argIndexMap: emittedArgIndices(fn, instanceOffset),
|
|
440
440
|
isNewlyCreated: fn.instance === undefined,
|
|
441
|
+
isReceived: true,
|
|
441
442
|
});
|
|
442
443
|
|
|
443
444
|
return {
|
|
@@ -568,6 +569,7 @@ const planOutParam = (
|
|
|
568
569
|
...argIndex,
|
|
569
570
|
cursor: parameter.cursor,
|
|
570
571
|
hasOutIndirection: true,
|
|
572
|
+
isReceived: true,
|
|
571
573
|
});
|
|
572
574
|
|
|
573
575
|
return {
|
package/src/store/gi/pipeline.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { getParentRef } from "../../gir/ancestry.js";
|
|
|
7
7
|
import { isEmittableEntity } from "../../gir/emittable.js";
|
|
8
8
|
import { PRIMITIVE_TS_TYPE, primitiveCategory } from "../../gir/primitives.js";
|
|
9
9
|
import { ModuleContext } from "../../writer/context.js";
|
|
10
|
+
import { renderBootstrapModule } from "./bootstrap.js";
|
|
10
11
|
import { generateCallback } from "./callback.js";
|
|
11
12
|
import { generateClass } from "./class.js";
|
|
12
13
|
import { generateConstant } from "./constant.js";
|
|
@@ -24,7 +25,12 @@ type TopologicalState = {
|
|
|
24
25
|
result: GirClass[];
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
type NamespaceModule = {
|
|
29
|
+
source: string;
|
|
30
|
+
bootstrapSource: string | undefined;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const generateNamespaceModule = (namespace: GirNamespace, library: Library): NamespaceModule => {
|
|
28
34
|
const context = new ModuleContext(namespace, library);
|
|
29
35
|
context.addGObjectBootstrapImports();
|
|
30
36
|
generateNamespaceTypes(context, namespace);
|
|
@@ -38,7 +44,10 @@ const generateNamespaceModule = (namespace: GirNamespace, library: Library): str
|
|
|
38
44
|
);
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
return
|
|
47
|
+
return {
|
|
48
|
+
source: context.module.toSource(),
|
|
49
|
+
bootstrapSource: library.isTreeShaken ? renderBootstrapModule(context) : undefined,
|
|
50
|
+
};
|
|
42
51
|
};
|
|
43
52
|
|
|
44
53
|
const generateNamespaceTypes = (context: ModuleContext, namespace: GirNamespace): void => {
|
|
@@ -50,10 +59,20 @@ const generateNamespaceTypes = (context: ModuleContext, namespace: GirNamespace)
|
|
|
50
59
|
generateRecord(context, record);
|
|
51
60
|
}
|
|
52
61
|
|
|
62
|
+
if (context.isTreeShaken) {
|
|
63
|
+
generateInterfaces(context, namespace);
|
|
64
|
+
}
|
|
65
|
+
|
|
53
66
|
for (const klass of topologicalClassOrder(namespace.classes, namespace.name)) {
|
|
54
67
|
generateClass(context, klass);
|
|
55
68
|
}
|
|
56
69
|
|
|
70
|
+
if (!context.isTreeShaken) {
|
|
71
|
+
generateInterfaces(context, namespace);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const generateInterfaces = (context: ModuleContext, namespace: GirNamespace): void => {
|
|
57
76
|
for (const iface of namespace.interfaces) {
|
|
58
77
|
generateInterface(context, iface);
|
|
59
78
|
}
|
|
@@ -185,7 +185,7 @@ const renderPropertyAccessorSignature = (args: PropertyAccessorArgs): string | u
|
|
|
185
185
|
withAccessor(args, (accessor) => `${propertyDoc(args.property)}${renderAccessorPairSignature(accessor)}`);
|
|
186
186
|
|
|
187
187
|
const renderPropertyDescriptor = (context: ModuleContext, property: GirProperty): string =>
|
|
188
|
-
renderDescriptor(context, property.type, property.transferOwnership);
|
|
188
|
+
renderDescriptor(context, property.type, property.transferOwnership, { isReceived: true });
|
|
189
189
|
|
|
190
190
|
const renderGenericGetBody = (context: ModuleContext, property: GirProperty, tsType: string): string => {
|
|
191
191
|
context.addRuntimeImport("getObjectProperty");
|
|
@@ -285,7 +285,7 @@ const renderRecordFieldAccessor = (
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
const descriptor = context.hoistDescriptor(
|
|
288
|
-
renderDescriptor(context, field.type, "none", { isInline: isInlineField(context, field) }),
|
|
288
|
+
renderDescriptor(context, field.type, "none", { isInline: isInlineField(context, field), isReceived: true }),
|
|
289
289
|
);
|
|
290
290
|
|
|
291
291
|
const tsType = fieldTsType(context, field.type);
|
|
@@ -501,7 +501,7 @@ const visitInlineStructSlot = (
|
|
|
501
501
|
return;
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
-
const descriptor = context.hoistDescriptor(renderDescriptor(context, field.type, "none"));
|
|
504
|
+
const descriptor = context.hoistDescriptor(renderDescriptor(context, field.type, "none", { isReceived: true }));
|
|
505
505
|
visitors.leaf({ jsName, descriptor, offset, slot, type: field.type });
|
|
506
506
|
};
|
|
507
507
|
|
|
@@ -778,7 +778,9 @@ const renderInlineArrayAccessor = (context: ModuleContext, target: StructArrayTa
|
|
|
778
778
|
context,
|
|
779
779
|
jsName,
|
|
780
780
|
tsType: renderTsType(context, field.type, false),
|
|
781
|
-
descriptor: context.hoistDescriptor(
|
|
781
|
+
descriptor: context.hoistDescriptor(
|
|
782
|
+
renderDescriptor(context, resolution.element, "none", { isInline: true, isReceived: true }),
|
|
783
|
+
),
|
|
782
784
|
offset: slot.byteOffset,
|
|
783
785
|
resolution,
|
|
784
786
|
};
|
package/src/store/gi/record.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { isEmittableEntity } from "../../gir/emittable.js";
|
|
|
5
5
|
import { indentMembers } from "../../writer/emit.js";
|
|
6
6
|
import { type Callables, dedupeCallables, generateBindings, renderPlainTypeMembers } from "./callables.js";
|
|
7
7
|
import { getDoc } from "./doc-spec.js";
|
|
8
|
+
import { declareFoldedClass, localClassName } from "./folded.js";
|
|
8
9
|
import { renderSourceGtype } from "./gtype-binding.js";
|
|
9
10
|
import { renderRecordConstructor, renderRecordConstructorPropsInterface } from "./record-constructor.js";
|
|
10
11
|
import { renderRecordFieldAccessor } from "./record-field-accessor.js";
|
|
@@ -12,9 +13,52 @@ import { computeRecordFieldSlots } from "./record-layout.js";
|
|
|
12
13
|
import { appendWrapperClassRegistration } from "./registration.js";
|
|
13
14
|
import { isConstructibleRecord } from "./value-marshalable.js";
|
|
14
15
|
|
|
16
|
+
type FoldedRecordOptions = {
|
|
17
|
+
record: GirRecord;
|
|
18
|
+
className: string;
|
|
19
|
+
doc: string;
|
|
20
|
+
modifier: string;
|
|
21
|
+
heritage: string;
|
|
22
|
+
body: string;
|
|
23
|
+
gtypeExpr: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
15
26
|
const isGErrorRecord = (context: ModuleContext, record: GirRecord): boolean =>
|
|
16
27
|
context.namespace.name === "GLib" && record.glibGetType === "g_error_get_type";
|
|
17
28
|
|
|
29
|
+
const recordHeritage = (context: ModuleContext, isErrorSubclass: boolean): string => {
|
|
30
|
+
if (!isErrorSubclass) {
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const base = context.isTreeShaken ? context.hoistBaseRef("globalThis.Error") : "globalThis.Error";
|
|
35
|
+
|
|
36
|
+
return ` extends ${base}`;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const recordModifier = (isConstructible: boolean): string => (isConstructible ? "" : "abstract ");
|
|
40
|
+
|
|
41
|
+
const declareFoldedRecord = (context: ModuleContext, options: FoldedRecordOptions): void => {
|
|
42
|
+
const { record, className, doc, modifier, heritage, body, gtypeExpr } = options;
|
|
43
|
+
const localName = localClassName(className);
|
|
44
|
+
context.beginRegistrations();
|
|
45
|
+
|
|
46
|
+
appendWrapperClassRegistration(context, {
|
|
47
|
+
className: localName,
|
|
48
|
+
gtypeExpr,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
declareFoldedClass({
|
|
52
|
+
context,
|
|
53
|
+
className,
|
|
54
|
+
doc,
|
|
55
|
+
owner: record.name,
|
|
56
|
+
localDeclaration: `${modifier}class ${localName}${heritage} {\n${body}\n}`,
|
|
57
|
+
registrations: context.takeRegistrations(),
|
|
58
|
+
hasInstanceInterface: true,
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
|
|
18
62
|
const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
19
63
|
if (!isEmittableEntity(record)) {
|
|
20
64
|
return;
|
|
@@ -32,16 +76,26 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
32
76
|
generateBindings(context, callables);
|
|
33
77
|
const members = renderRecordMembers(context, record, className, callables);
|
|
34
78
|
const body = indentMembers(members);
|
|
35
|
-
const heritage = isErrorSubclass
|
|
79
|
+
const heritage = recordHeritage(context, isErrorSubclass);
|
|
36
80
|
const doc = getDoc(record);
|
|
37
81
|
const isConstructible = isConstructibleRecord(context, context.namespace.name, record);
|
|
38
|
-
const modifier = isConstructible
|
|
82
|
+
const modifier = recordModifier(isConstructible);
|
|
83
|
+
const gtypeExpr = renderSourceGtype(context, record);
|
|
39
84
|
|
|
40
|
-
context.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
85
|
+
if (gtypeExpr !== undefined && context.isTreeShaken) {
|
|
86
|
+
declareFoldedRecord(context, { record, className, doc, modifier, heritage, body, gtypeExpr });
|
|
87
|
+
} else {
|
|
88
|
+
context.declare({
|
|
89
|
+
name: className,
|
|
90
|
+
code: `${doc}export ${modifier}class ${className}${heritage} {\n${body}\n}`,
|
|
91
|
+
owner: record.name,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
appendWrapperClassRegistration(context, {
|
|
95
|
+
className,
|
|
96
|
+
gtypeExpr,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
45
99
|
|
|
46
100
|
if (isConstructible) {
|
|
47
101
|
context.declare({
|
|
@@ -49,13 +103,6 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
49
103
|
code: renderRecordConstructorPropsInterface(context, record, className),
|
|
50
104
|
});
|
|
51
105
|
}
|
|
52
|
-
|
|
53
|
-
const gtypeExpr = renderSourceGtype(context, record);
|
|
54
|
-
|
|
55
|
-
appendWrapperClassRegistration(context, {
|
|
56
|
-
className,
|
|
57
|
-
gtypeExpr,
|
|
58
|
-
});
|
|
59
106
|
};
|
|
60
107
|
|
|
61
108
|
const renderRecordMembers = (
|
|
@@ -25,7 +25,7 @@ const appendWrapperClassRegistration = (
|
|
|
25
25
|
|
|
26
26
|
context.addRuntimeImport("registerWrapperClass");
|
|
27
27
|
const args = vfuncs === undefined ? gtypeExpr : `${gtypeExpr}, ${vfuncs}`;
|
|
28
|
-
context.
|
|
28
|
+
context.collectRegistration(`registerWrapperClass(${className}, ${args});`, [className]);
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const appendInterfaceRegistration = (context: ModuleContext, registration: InterfaceRegistration): void => {
|
|
@@ -38,7 +38,7 @@ const appendInterfaceRegistration = (context: ModuleContext, registration: Inter
|
|
|
38
38
|
context.addRuntimeImport("registerInterface");
|
|
39
39
|
const base = `${className}, ${gtypeExpr}, ${makerName}`;
|
|
40
40
|
const args = layout === undefined ? base : `${base}, ${layout}`;
|
|
41
|
-
context.
|
|
41
|
+
context.collectRegistration(`registerInterface(${args});`, [className, makerName]);
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
export { appendWrapperClassRegistration, appendInterfaceRegistration };
|
|
@@ -69,7 +69,7 @@ const wrapAlias = (
|
|
|
69
69
|
|
|
70
70
|
const wrapValue = (context: ModuleContext, ref: TypeId, valueExpression: string): string => {
|
|
71
71
|
context.addRuntimeImport("fromNative");
|
|
72
|
-
const descriptor = context.hoistDescriptor(renderDescriptor(context, ref, "none"));
|
|
72
|
+
const descriptor = context.hoistDescriptor(renderDescriptor(context, ref, "none", { isReceived: true }));
|
|
73
73
|
|
|
74
74
|
return `(fromNative(${descriptor}, ${valueExpression}) as ${renderTsType(context, ref, false)})`;
|
|
75
75
|
};
|
package/src/store/gi/signal.ts
CHANGED
|
@@ -318,7 +318,7 @@ const renderEmitReturnArg = (context: ModuleContext, returnValue: GirReturnValue
|
|
|
318
318
|
return "";
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
return `, ${renderDescriptor(context, returnValue.type, returnValue.transferOwnership)}`;
|
|
321
|
+
return `, ${renderDescriptor(context, returnValue.type, returnValue.transferOwnership, { isReceived: true })}`;
|
|
322
322
|
};
|
|
323
323
|
|
|
324
324
|
const renderEmitCase = (context: ModuleContext, signal: GirCallable): string => {
|
|
@@ -332,7 +332,10 @@ const renderEmitCase = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
332
332
|
let argIndex = 0;
|
|
333
333
|
|
|
334
334
|
const argLiterals = params.map((parameter) => {
|
|
335
|
-
const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership
|
|
335
|
+
const descriptor = renderDescriptor(context, parameter.type, parameter.transferOwnership, {
|
|
336
|
+
isReceived: true,
|
|
337
|
+
});
|
|
338
|
+
|
|
336
339
|
const rendered = renderEmitArgLiteral({ context, parameter, descriptor, argIndex });
|
|
337
340
|
argIndex = rendered.nextArgIndex;
|
|
338
341
|
|
|
@@ -366,7 +369,9 @@ const renderCallback = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
366
369
|
|
|
367
370
|
return tCallback({
|
|
368
371
|
argTypes: callbackArgs,
|
|
369
|
-
returns: renderDescriptor(context, signal.returnValue.type, signal.returnValue.transferOwnership
|
|
372
|
+
returns: renderDescriptor(context, signal.returnValue.type, signal.returnValue.transferOwnership, {
|
|
373
|
+
isReceived: true,
|
|
374
|
+
}),
|
|
370
375
|
options: [
|
|
371
376
|
"hasDestroy: true",
|
|
372
377
|
"destroyKind: \"closureNotify\"",
|
package/src/store/gi/vtable.ts
CHANGED
package/src/store/gi-store.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { buildManifest, namespaceBarrel, type StoreOptions, subpathExport, write
|
|
|
14
14
|
type GiNamespaceInput = {
|
|
15
15
|
directory: string;
|
|
16
16
|
rawSource: string;
|
|
17
|
+
rawBootstrapSource?: string | undefined;
|
|
17
18
|
girFile: string;
|
|
18
19
|
};
|
|
19
20
|
|
|
@@ -29,6 +30,7 @@ type GiStoreRecords = {
|
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
const OVERRIDES_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "overrides");
|
|
33
|
+
const TREE_SHAKEN_SIDE_EFFECTS = ["**/bootstrap.js", "**/overrides/*.js", "**/index.js"];
|
|
32
34
|
|
|
33
35
|
const overrideFiles = (directory: string): SourceModule[] => {
|
|
34
36
|
const dir = join(OVERRIDES_ROOT, directory);
|
|
@@ -48,21 +50,25 @@ const overrideModule = (fileName: string, overridePath: string): SourceModule =>
|
|
|
48
50
|
origin: overridePath,
|
|
49
51
|
});
|
|
50
52
|
|
|
51
|
-
const barrelFile = (directory: string, girFile: string): SourceModule => {
|
|
53
|
+
const barrelFile = (directory: string, girFile: string, hasBootstrap: boolean): SourceModule => {
|
|
52
54
|
const barrel = namespaceBarrel(directory);
|
|
53
55
|
const overrideIndex = join(OVERRIDES_ROOT, directory, "index.ts.ejs");
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
const file = existsSync(overrideIndex)
|
|
58
|
+
? overrideModule(barrel.fileName, overrideIndex)
|
|
59
|
+
: { ...barrel, origin: girFile };
|
|
60
|
+
|
|
61
|
+
if (!hasBootstrap) {
|
|
62
|
+
return file;
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
return
|
|
65
|
+
return { ...file, source: `import "./bootstrap.js";\n${file.source}` };
|
|
60
66
|
};
|
|
61
67
|
|
|
62
68
|
const externalShimModule = ({ directory, packageName, girFile }: GiExternalNamespaceInput): SourceModule => ({
|
|
63
69
|
fileName: `${directory}/index.ts`,
|
|
64
70
|
source:
|
|
65
|
-
`/** @deprecated Import from "${packageName}" instead
|
|
71
|
+
`/** @deprecated Since 1.3. Import from "${packageName}" instead. Removed in v2. */\n` +
|
|
66
72
|
`export * from "${packageName}";\n`,
|
|
67
73
|
origin: girFile,
|
|
68
74
|
});
|
|
@@ -74,13 +80,17 @@ const collectStoreSources = (
|
|
|
74
80
|
const exportsMap: Record<string, unknown> = {};
|
|
75
81
|
const collected: SourceModule[] = [];
|
|
76
82
|
|
|
77
|
-
for (const { directory, rawSource, girFile } of namespaces) {
|
|
83
|
+
for (const { directory, rawSource, rawBootstrapSource, girFile } of namespaces) {
|
|
78
84
|
collected.push(
|
|
79
85
|
{ fileName: `${directory}/${directory}.ts`, source: rawSource, origin: girFile },
|
|
80
86
|
...overrideFiles(directory),
|
|
81
|
-
barrelFile(directory, girFile),
|
|
87
|
+
barrelFile(directory, girFile, rawBootstrapSource !== undefined),
|
|
82
88
|
);
|
|
83
89
|
|
|
90
|
+
if (rawBootstrapSource !== undefined) {
|
|
91
|
+
collected.push({ fileName: `${directory}/bootstrap.ts`, source: rawBootstrapSource, origin: girFile });
|
|
92
|
+
}
|
|
93
|
+
|
|
84
94
|
exportsMap[`./${directory}`] = subpathExport(`${directory}/index`);
|
|
85
95
|
}
|
|
86
96
|
|
|
@@ -107,6 +117,7 @@ const writeGiStore = (
|
|
|
107
117
|
records: GiStoreRecords,
|
|
108
118
|
): void => {
|
|
109
119
|
const { collected, exportsMap } = collectStoreSources(namespaces, externalNamespaces);
|
|
120
|
+
const isTreeShaken = namespaces.some((namespace) => namespace.rawBootstrapSource !== undefined);
|
|
110
121
|
|
|
111
122
|
writeStore({
|
|
112
123
|
storeDir: options.storeDir,
|
|
@@ -116,6 +127,7 @@ const writeGiStore = (
|
|
|
116
127
|
name: "@gtkx/gi",
|
|
117
128
|
version: options.version,
|
|
118
129
|
exports: exportsMap,
|
|
130
|
+
sideEffects: isTreeShaken ? TREE_SHAKEN_SIDE_EFFECTS : true,
|
|
119
131
|
peerDependencies: storePeerDependencies(externalNamespaces),
|
|
120
132
|
}),
|
|
121
133
|
rawFiles: [
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sanitizeTypeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { Library } from "../../gir/library.js";
|
|
3
3
|
import type { GirNamespace } from "../../gir/namespace.js";
|
|
4
4
|
import type { ImportsBuilder } from "../../writer/imports.js";
|
|
5
5
|
import type { LazyElementSpec } from "./element-prop-types.js";
|
|
6
|
+
import { externalPackageFor } from "../../gir/external-namespaces.js";
|
|
6
7
|
import { getDoc } from "../gi/doc-spec.js";
|
|
7
8
|
import { ancestorGlibNames, type GlibNamedClass } from "./intrinsic-elements.js";
|
|
8
9
|
|
|
@@ -23,6 +24,13 @@ type CandidateExportOptions = {
|
|
|
23
24
|
components: Record<string, ElementComponent>;
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
type LazyMetadataOptions = {
|
|
28
|
+
isTreeShaken: boolean;
|
|
29
|
+
intrinsicNames: Set<string>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const METADATA_ALIAS = "Metadata$";
|
|
33
|
+
|
|
26
34
|
const generateElementComponentsSection = (
|
|
27
35
|
targetNamespace: GirNamespace,
|
|
28
36
|
library: Library,
|
|
@@ -45,7 +53,11 @@ const generateElementComponentsSection = (
|
|
|
45
53
|
components: options.components,
|
|
46
54
|
});
|
|
47
55
|
|
|
48
|
-
collectLazyElementExports(collector, lazyElements
|
|
56
|
+
collectLazyElementExports(collector, lazyElements, {
|
|
57
|
+
isTreeShaken: library.isTreeShaken,
|
|
58
|
+
intrinsicNames: new Set(options.intrinsicElements.map((entry) => entry.glibName)),
|
|
59
|
+
});
|
|
60
|
+
|
|
49
61
|
const source = collector.exportLines.join("\n\n");
|
|
50
62
|
|
|
51
63
|
return { source, exportedNames: collector.exportedNames };
|
|
@@ -81,18 +93,75 @@ const collectCandidateExports = (collector: ExportCollector, options: CandidateE
|
|
|
81
93
|
}
|
|
82
94
|
};
|
|
83
95
|
|
|
84
|
-
const collectLazyElementExports = (
|
|
96
|
+
const collectLazyElementExports = (
|
|
97
|
+
collector: ExportCollector,
|
|
98
|
+
lazyElements: LazyElementSpec[],
|
|
99
|
+
options: LazyMetadataOptions,
|
|
100
|
+
): void => {
|
|
85
101
|
for (const spec of lazyElements) {
|
|
86
102
|
collector.imports.addNamed("@gtkx/react/internal", "createElementComponent", false);
|
|
87
103
|
collector.imports.addNamed("react", "ReactNode", true);
|
|
88
|
-
|
|
104
|
+
|
|
105
|
+
const refs = {
|
|
106
|
+
classRef: lazyClassRef(collector, spec, options),
|
|
107
|
+
metadataRef: lazyMetadataRef(collector, spec, options),
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
collector.exportLines.push(renderLazyElementExport(spec, refs, options));
|
|
89
111
|
collector.exportedNames.add(spec.element);
|
|
90
112
|
}
|
|
91
113
|
};
|
|
92
114
|
|
|
93
|
-
const
|
|
115
|
+
const lazyMetadataRef = (
|
|
116
|
+
collector: ExportCollector,
|
|
117
|
+
spec: LazyElementSpec,
|
|
118
|
+
options: LazyMetadataOptions,
|
|
119
|
+
): string | undefined => {
|
|
120
|
+
if (!options.isTreeShaken || !options.intrinsicNames.has(spec.element)) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
collector.imports.addNamespace("../metadata.js", METADATA_ALIAS, false);
|
|
125
|
+
|
|
126
|
+
return `${METADATA_ALIAS}.${spec.element}`;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const lazyClassRef = (
|
|
130
|
+
collector: ExportCollector,
|
|
131
|
+
spec: LazyElementSpec,
|
|
132
|
+
options: LazyMetadataOptions,
|
|
133
|
+
): string | undefined => {
|
|
134
|
+
if (!options.isTreeShaken) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const alias = `${spec.namespaceName}$`;
|
|
139
|
+
const specifier = externalPackageFor(spec.namespaceName) ?? `@gtkx/gi/${spec.namespaceName.toLowerCase()}`;
|
|
140
|
+
collector.imports.addNamespace(specifier, alias, false);
|
|
141
|
+
|
|
142
|
+
return `${alias}.${sanitizeTypeIdentifier(spec.className)}`;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const renderLazyElementExport = (
|
|
146
|
+
spec: LazyElementSpec,
|
|
147
|
+
refs: { classRef: string | undefined; metadataRef: string | undefined },
|
|
148
|
+
options: LazyMetadataOptions,
|
|
149
|
+
): string => {
|
|
94
150
|
const doc = getDoc(spec);
|
|
95
|
-
const
|
|
151
|
+
const args = [sourceStringLiteral(spec.element)];
|
|
152
|
+
|
|
153
|
+
if (refs.classRef !== undefined) {
|
|
154
|
+
args.push(refs.classRef);
|
|
155
|
+
} else if (refs.metadataRef !== undefined) {
|
|
156
|
+
args.push("undefined");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (refs.metadataRef !== undefined) {
|
|
160
|
+
args.push(refs.metadataRef);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const pure = options.isTreeShaken ? "/* @__PURE__ */ " : "";
|
|
164
|
+
const factory = `${pure}createElementComponent(${args.join(", ")})`;
|
|
96
165
|
const component = `${doc}export const ${spec.element}: (props: ${spec.typeName}) => ReactNode = ${factory};`;
|
|
97
166
|
|
|
98
167
|
return `${doc}${spec.typeSource}\n\n${component}`;
|
|
@@ -114,9 +183,21 @@ const renderCandidateExport = (
|
|
|
114
183
|
imports.addNamed(component.module, component.export, false);
|
|
115
184
|
}
|
|
116
185
|
|
|
186
|
+
let classRef: string | undefined;
|
|
187
|
+
let metadataRef: string | undefined;
|
|
188
|
+
|
|
189
|
+
if (library.isTreeShaken) {
|
|
190
|
+
const alias = `${namespace.name}$`;
|
|
191
|
+
const specifier = externalPackageFor(namespace.name) ?? `@gtkx/gi/${namespace.name.toLowerCase()}`;
|
|
192
|
+
imports.addNamespace(specifier, alias, false);
|
|
193
|
+
imports.addNamespace("../metadata.js", METADATA_ALIAS, false);
|
|
194
|
+
classRef = `${alias}.${sanitizeTypeIdentifier(klass.name)}`;
|
|
195
|
+
metadataRef = `${METADATA_ALIAS}.${glibName}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
117
198
|
const doc = getDoc(klass);
|
|
118
199
|
|
|
119
|
-
return `${doc}${renderElementComponentExport(glibName, component)}`;
|
|
200
|
+
return `${doc}${renderElementComponentExport(glibName, component, classRef, metadataRef)}`;
|
|
120
201
|
};
|
|
121
202
|
|
|
122
203
|
const resolveElementComponent = (
|
|
@@ -134,16 +215,32 @@ const resolveElementComponent = (
|
|
|
134
215
|
return undefined;
|
|
135
216
|
};
|
|
136
217
|
|
|
137
|
-
const renderElementComponentExport = (
|
|
218
|
+
const renderElementComponentExport = (
|
|
219
|
+
glibName: string,
|
|
220
|
+
component: ElementComponent | undefined,
|
|
221
|
+
classRef: string | undefined,
|
|
222
|
+
metadataRef: string | undefined,
|
|
223
|
+
): string => {
|
|
138
224
|
const propsType = `${glibName}Props`;
|
|
139
225
|
const annotation = `(props: ${propsType}) => ReactNode`;
|
|
140
|
-
const
|
|
226
|
+
const args = [sourceStringLiteral(glibName)];
|
|
227
|
+
|
|
228
|
+
if (classRef !== undefined) {
|
|
229
|
+
args.push(classRef);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (metadataRef !== undefined) {
|
|
233
|
+
args.push(metadataRef);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const pure = classRef === undefined ? "" : "/* @__PURE__ */ ";
|
|
237
|
+
const factoryCall = `${pure}createElementComponent(${args.join(", ")})`;
|
|
141
238
|
|
|
142
239
|
if (component === undefined) {
|
|
143
240
|
return `export const ${glibName}: ${annotation} = ${factoryCall};`;
|
|
144
241
|
}
|
|
145
242
|
|
|
146
|
-
return `export const ${glibName}: ${annotation} = ${component.export}(${factoryCall});`;
|
|
243
|
+
return `export const ${glibName}: ${annotation} = ${pure}${component.export}(${factoryCall});`;
|
|
147
244
|
};
|
|
148
245
|
|
|
149
246
|
export { generateElementComponentsSection, type ElementComponentOverrides };
|
|
@@ -10,6 +10,8 @@ type LazyElementSpec = {
|
|
|
10
10
|
typeSource: string;
|
|
11
11
|
doc: string | undefined;
|
|
12
12
|
annotations: GirAnnotations;
|
|
13
|
+
namespaceName: string;
|
|
14
|
+
className: string;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
const appendConstructOnlyNames = (klass: GirClass, names: string[]): void => {
|
|
@@ -43,6 +45,8 @@ const createLazyElementSpec = (context: GirIndex, element: string, entry: GirTyp
|
|
|
43
45
|
typeSource: `export type ${typeName} = ${base} & { children?: ReactNode };`,
|
|
44
46
|
doc: entry.klass.doc,
|
|
45
47
|
annotations: entry.klass.annotations,
|
|
48
|
+
namespaceName: entry.namespace.name,
|
|
49
|
+
className: entry.klass.name,
|
|
46
50
|
};
|
|
47
51
|
};
|
|
48
52
|
|