@gtkx/codegen 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/analysis/descriptor-render.d.ts +7 -1
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +36 -15
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +4 -1
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +11 -2
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/param-capability.d.ts +5 -2
- package/dist/analysis/param-capability.d.ts.map +1 -1
- package/dist/analysis/param-capability.js +36 -4
- package/dist/analysis/param-capability.js.map +1 -1
- package/dist/analysis/param-structure.d.ts +1 -1
- package/dist/analysis/param-structure.d.ts.map +1 -1
- 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 +28 -10
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/compile.js +1 -1
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +6 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +11 -2
- 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 +10 -1
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/fingerprint.d.ts +5 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +107 -15
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +3 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +29 -7
- package/dist/gi.js.map +1 -1
- package/dist/gir/external-namespaces.d.ts +8 -0
- package/dist/gir/external-namespaces.d.ts.map +1 -0
- package/dist/gir/external-namespaces.js +4 -0
- package/dist/gir/external-namespaces.js.map +1 -0
- package/dist/gir/finish-overrides.d.ts +3 -0
- package/dist/gir/finish-overrides.d.ts.map +1 -0
- package/dist/gir/finish-overrides.js +5 -0
- package/dist/gir/finish-overrides.js.map +1 -0
- package/dist/gir/function.d.ts +5 -2
- package/dist/gir/function.d.ts.map +1 -1
- package/dist/gir/function.js +34 -5
- package/dist/gir/function.js.map +1 -1
- package/dist/gir/hidden-symbols.d.ts +3 -0
- package/dist/gir/hidden-symbols.d.ts.map +1 -0
- package/dist/gir/hidden-symbols.js +39 -0
- package/dist/gir/hidden-symbols.js.map +1 -0
- package/dist/gir/library.d.ts +22 -2
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +21 -3
- package/dist/gir/library.js.map +1 -1
- package/dist/gir/ucs4-overrides.d.ts +3 -0
- package/dist/gir/ucs4-overrides.d.ts.map +1 -0
- package/dist/gir/ucs4-overrides.js +7 -0
- package/dist/gir/ucs4-overrides.js.map +1 -0
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +27 -8
- package/dist/jsx.js.map +1 -1
- package/dist/runner.d.ts +8 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +9 -3
- package/dist/runner.js.map +1 -1
- package/dist/store/external-package-links.d.ts +6 -0
- package/dist/store/external-package-links.d.ts.map +1 -0
- package/dist/store/external-package-links.js +158 -0
- package/dist/store/external-package-links.js.map +1 -0
- package/dist/store/gi/callable-doc.d.ts.map +1 -1
- package/dist/store/gi/callable-doc.js +4 -4
- package/dist/store/gi/callable-doc.js.map +1 -1
- package/dist/store/gi/callables.js +1 -1
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +17 -0
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/constructor-props.js +1 -1
- package/dist/store/gi/constructor-props.js.map +1 -1
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +2 -1
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/gtype-binding.d.ts +2 -1
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +6 -1
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/method.d.ts +7 -2
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +126 -30
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/param-marshal.d.ts +8 -1
- package/dist/store/gi/param-marshal.d.ts.map +1 -1
- package/dist/store/gi/param-marshal.js +52 -4
- package/dist/store/gi/param-marshal.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +2 -3
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +2 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +9 -3
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/runtime-override.js +1 -1
- package/dist/store/gi/runtime-override.js.map +1 -1
- package/dist/store/gi/signal.js +2 -2
- 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 +82 -12
- package/dist/store/gi/vtable.js.map +1 -1
- package/dist/store/gi-store.d.ts +7 -2
- package/dist/store/gi-store.d.ts.map +1 -1
- package/dist/store/gi-store.js +19 -4
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/jsx.d.ts.map +1 -1
- package/dist/store/jsx/jsx.js +3 -1
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx-store.d.ts +8 -1
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +9 -2
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts +2 -1
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +2 -1
- package/dist/store/resolve-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 +8 -3
- package/dist/store/store-fs.js.map +1 -1
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +8 -0
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/gtk-doc.d.ts.map +1 -1
- package/dist/writer/gtk-doc.js +27 -1
- package/dist/writer/gtk-doc.js.map +1 -1
- package/overrides/gdk/rgba.ts.ejs +15 -1
- package/overrides/glib/index.ts.ejs +3 -0
- package/overrides/glib/regex.ts.ejs +66 -0
- package/overrides/gobject/index.ts.ejs +3 -0
- package/overrides/gobject/object-class.ts.ejs +27 -0
- package/overrides/gobject/param-spec-getters.ts.ejs +57 -0
- package/overrides/gobject/param-spec.ts.ejs +21 -0
- package/overrides/gobject/value.ts.ejs +6 -1
- package/overrides/graphene/structs.ts.ejs +38 -3
- package/overrides/gtk/index.ts.ejs +2 -0
- package/overrides/gtk/widget-class.ts.ejs +28 -0
- package/package.json +6 -5
- package/src/analysis/descriptor-render.ts +59 -16
- package/src/analysis/descriptor.ts +15 -3
- package/src/analysis/param-capability.ts +68 -5
- package/src/analysis/param-structure.ts +1 -1
- package/src/analysis/ts-type.ts +45 -11
- package/src/compile.ts +1 -1
- package/src/docs/api-reference.ts +20 -2
- package/src/docs/pipeline.ts +15 -1
- package/src/fingerprint.ts +144 -16
- package/src/gi.ts +44 -9
- package/src/gir/external-namespaces.ts +8 -0
- package/src/gir/finish-overrides.ts +5 -0
- package/src/gir/function.ts +52 -14
- package/src/gir/hidden-symbols.ts +39 -0
- package/src/gir/library.ts +36 -3
- package/src/gir/ucs4-overrides.ts +7 -0
- package/src/jsx.ts +33 -8
- package/src/runner.ts +17 -3
- package/src/store/external-package-links.ts +226 -0
- package/src/store/gi/callable-doc.ts +8 -4
- package/src/store/gi/callables.ts +1 -1
- package/src/store/gi/class.ts +29 -0
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/function.ts +2 -1
- package/src/store/gi/gtype-binding.ts +8 -1
- package/src/store/gi/method.ts +189 -36
- package/src/store/gi/param-marshal.ts +67 -4
- package/src/store/gi/record-constructor.ts +8 -3
- package/src/store/gi/record-field-accessor.ts +11 -2
- package/src/store/gi/runtime-override.ts +1 -1
- package/src/store/gi/signal.ts +2 -2
- package/src/store/gi/vtable.ts +118 -11
- package/src/store/gi-store.ts +33 -3
- package/src/store/jsx/jsx.ts +3 -1
- package/src/store/jsx-store.ts +23 -7
- package/src/store/resolve-store.ts +2 -1
- package/src/store/store-fs.ts +10 -2
- package/src/writer/context.ts +11 -0
- package/src/writer/gtk-doc.ts +38 -1
- package/overrides/cairo/context.ts.ejs +0 -1269
- package/overrides/cairo/font-face.ts.ejs +0 -151
- package/overrides/cairo/font-options.ts.ejs +0 -199
- package/overrides/cairo/image-surface.ts.ejs +0 -132
- package/overrides/cairo/index.ts.ejs +0 -22
- package/overrides/cairo/matrix.ts.ejs +0 -171
- package/overrides/cairo/pattern.ts.ejs +0 -476
- package/overrides/cairo/recording-surface.ts.ejs +0 -102
- package/overrides/cairo/region.ts.ejs +0 -237
- package/overrides/cairo/scaled-font.ts.ejs +0 -330
- package/overrides/cairo/surface.ts.ejs +0 -296
package/src/store/gi/vtable.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { JsDocSpec } from "../../writer/doc.js";
|
|
|
11
11
|
import {
|
|
12
12
|
isInlineCallbackRef,
|
|
13
13
|
isScalarRef,
|
|
14
|
+
renderCallbackType,
|
|
14
15
|
renderDescriptor,
|
|
15
16
|
renderParamDescriptor,
|
|
16
17
|
} from "../../analysis/descriptor-render.js";
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
handlerParameters,
|
|
20
21
|
parameterIdentifier,
|
|
21
22
|
renamesWithInstance,
|
|
22
|
-
renderHandlerParameters,
|
|
23
23
|
renderHandlerResultType,
|
|
24
24
|
} from "../../analysis/param-structure.js";
|
|
25
25
|
import { renderTsType } from "../../analysis/ts-type.js";
|
|
@@ -74,6 +74,12 @@ type Vtable = {
|
|
|
74
74
|
slots: VtableSlot[];
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
type SlotParamPlan = {
|
|
78
|
+
parameters: GirParameter[];
|
|
79
|
+
argIndexMap: Map<number, number>;
|
|
80
|
+
decoded: Set<GirParameter>;
|
|
81
|
+
};
|
|
82
|
+
|
|
77
83
|
const PADDING_FIELD_NAME = /^(?:reserved|padding)\d*$/i;
|
|
78
84
|
|
|
79
85
|
const UNCALLABLE_SLOT_KEYS: Set<string> = new Set([
|
|
@@ -86,6 +92,7 @@ const UNCALLABLE_SLOT_KEYS: Set<string> = new Set([
|
|
|
86
92
|
const VTABLE_CACHE: WeakMap<GirClass, Vtable> = new WeakMap();
|
|
87
93
|
const PROTECTED_SLOT_NOTE = "It is `protected`, so only a subclass chaining up reaches it.";
|
|
88
94
|
const PUBLIC_SLOT_NOTE = "Calling it from anywhere else re-enters the slot on a live instance.";
|
|
95
|
+
const OPAQUE_CALLBACK_NOTE = "Received as the raw address of the C function pointer.";
|
|
89
96
|
|
|
90
97
|
const vfuncMemberName = (fieldName: string): string => `vfunc${pascalCase(fieldName)}`;
|
|
91
98
|
|
|
@@ -125,6 +132,79 @@ const vtableCallbackType = (context: ModuleContext, field: GirField): GirCallbac
|
|
|
125
132
|
return type.value;
|
|
126
133
|
};
|
|
127
134
|
|
|
135
|
+
const isCallbackParam = (context: ModuleContext, parameter: GirParameter): boolean =>
|
|
136
|
+
parameter.type !== undefined && context.library.typeFor(parameter.type)?.kind === "callback";
|
|
137
|
+
|
|
138
|
+
const isDecodedCallbackParam = (context: ModuleContext, parameter: GirParameter, index: number): boolean =>
|
|
139
|
+
isCallbackParam(context, parameter) &&
|
|
140
|
+
parameter.closureIndex === index + 1 &&
|
|
141
|
+
parameter.destroyIndex === undefined;
|
|
142
|
+
|
|
143
|
+
const decodedSlotParams = (context: ModuleContext, callback: GirCallback): Set<GirParameter> => {
|
|
144
|
+
const decoded: Set<GirParameter> = new Set();
|
|
145
|
+
|
|
146
|
+
for (const [index, parameter] of callback.parameters.entries()) {
|
|
147
|
+
if (isDecodedCallbackParam(context, parameter, index)) {
|
|
148
|
+
decoded.add(parameter);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return decoded;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const companionIndices = (decoded: Set<GirParameter>): Set<number> => {
|
|
156
|
+
const companions: Set<number> = new Set();
|
|
157
|
+
|
|
158
|
+
for (const parameter of decoded) {
|
|
159
|
+
if (parameter.closureIndex !== undefined) {
|
|
160
|
+
companions.add(parameter.closureIndex);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return companions;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const slotParamPlan = (context: ModuleContext, callback: GirCallback): SlotParamPlan => {
|
|
168
|
+
const decoded = decodedSlotParams(context, callback);
|
|
169
|
+
const companions = companionIndices(decoded);
|
|
170
|
+
const parameters: GirParameter[] = [];
|
|
171
|
+
const argIndexMap: Map<number, number> = new Map();
|
|
172
|
+
|
|
173
|
+
for (const [index, parameter] of callback.parameters.entries()) {
|
|
174
|
+
if (companions.has(index)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
argIndexMap.set(index, parameters.length);
|
|
179
|
+
parameters.push(parameter);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { parameters, argIndexMap, decoded };
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const isOpaqueCallbackParam = (context: ModuleContext, plan: SlotParamPlan, parameter: GirParameter): boolean =>
|
|
186
|
+
isCallbackParam(context, parameter) && !plan.decoded.has(parameter);
|
|
187
|
+
|
|
188
|
+
const renderSlotParamDescriptor = (context: ModuleContext, parameter: GirParameter, plan: SlotParamPlan): string => {
|
|
189
|
+
if (plan.decoded.has(parameter)) {
|
|
190
|
+
const callbackDescriptor = renderCallbackType(context, parameter.type, parameter);
|
|
191
|
+
|
|
192
|
+
if (callbackDescriptor !== undefined) {
|
|
193
|
+
return callbackDescriptor;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return renderParamDescriptor(context, parameter, parameter.type, { argIndexMap: plan.argIndexMap });
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const renderSlotParamTsType = (context: ModuleContext, plan: SlotParamPlan, parameter: GirParameter): string => {
|
|
201
|
+
if (isOpaqueCallbackParam(context, plan, parameter)) {
|
|
202
|
+
return parameter.nullable ? "bigint | null" : "bigint";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return renderTsType(context, parameter.type, parameter.nullable);
|
|
206
|
+
};
|
|
207
|
+
|
|
128
208
|
const vtableSlotEntry = (
|
|
129
209
|
context: ModuleContext,
|
|
130
210
|
field: GirField,
|
|
@@ -387,15 +467,35 @@ const hasCallableVfuncSlots = (context: ModuleContext, namespaceName: string, kl
|
|
|
387
467
|
|
|
388
468
|
const slotDoc = (slot: VtableSlot): string | undefined => slot.vfunc?.doc ?? slot.field.doc ?? slot.callback.doc;
|
|
389
469
|
|
|
390
|
-
const
|
|
470
|
+
const slotParamDoc = (
|
|
471
|
+
context: ModuleContext,
|
|
472
|
+
plan: SlotParamPlan,
|
|
473
|
+
parameter: GirParameter,
|
|
474
|
+
doc: string | undefined,
|
|
475
|
+
): string | undefined => {
|
|
476
|
+
if (!isOpaqueCallbackParam(context, plan, parameter)) {
|
|
477
|
+
return doc;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return doc === undefined ? OPAQUE_CALLBACK_NOTE : `${doc} ${OPAQUE_CALLBACK_NOTE}`;
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const slotDocParameters = (context: ModuleContext, slot: VtableSlot): GirParameter[] => {
|
|
484
|
+
const plan = slotParamPlan(context, slot.callback);
|
|
391
485
|
const [, ...parameters] = slot.callback.parameters;
|
|
392
486
|
const vfuncParameters = slot.vfunc?.parameters ?? [];
|
|
393
487
|
|
|
394
|
-
return parameters
|
|
488
|
+
return parameters
|
|
489
|
+
.map((parameter, index) => ({ parameter, index }))
|
|
490
|
+
.filter(({ index }) => plan.argIndexMap.has(index + 1))
|
|
491
|
+
.map(({ parameter, index }) => ({
|
|
492
|
+
...parameter,
|
|
493
|
+
doc: slotParamDoc(context, plan, parameter, vfuncParameters[index]?.doc ?? parameter.doc),
|
|
494
|
+
}));
|
|
395
495
|
};
|
|
396
496
|
|
|
397
|
-
const slotDocSpec = (slot: VtableSlot): JsDocSpec => {
|
|
398
|
-
const parameters = slotDocParameters(slot);
|
|
497
|
+
const slotDocSpec = (context: ModuleContext, slot: VtableSlot): JsDocSpec => {
|
|
498
|
+
const parameters = slotDocParameters(context, slot);
|
|
399
499
|
const source = slot.vfunc ?? slot.callback;
|
|
400
500
|
|
|
401
501
|
return {
|
|
@@ -446,12 +546,18 @@ const isCallableSlot = (context: ModuleContext, slot: VtableSlot): boolean =>
|
|
|
446
546
|
!UNCALLABLE_SLOT_KEYS.has(slot.key) && !hasUnannotatedPointerParam(context, slot);
|
|
447
547
|
|
|
448
548
|
const vfuncSlotSignature = (context: ModuleContext, slot: VtableSlot, isOptional = false): VfuncSignature => {
|
|
449
|
-
const
|
|
549
|
+
const plan = slotParamPlan(context, slot.callback);
|
|
550
|
+
const [, ...parameters] = plan.parameters;
|
|
450
551
|
|
|
451
552
|
const renderType = (ref: TypeId | undefined, isNullable: boolean): string =>
|
|
452
553
|
renderTsType(context, ref, isNullable);
|
|
453
554
|
|
|
454
|
-
const signature =
|
|
555
|
+
const signature = handlerParameters(parameters)
|
|
556
|
+
.map(
|
|
557
|
+
(parameter, index) =>
|
|
558
|
+
`${parameterIdentifier(parameter, index)}: ${renderSlotParamTsType(context, plan, parameter)}`)
|
|
559
|
+
.join(", ");
|
|
560
|
+
|
|
455
561
|
const folded = foldedLengthParameters(context.library, slot.callback);
|
|
456
562
|
|
|
457
563
|
const returnType = renderHandlerResultType({
|
|
@@ -470,13 +576,13 @@ const renderVfuncMember = (options: VfuncMemberOptions): string => {
|
|
|
470
576
|
const { context, ownerRef, slot, mode, isProtected } = options;
|
|
471
577
|
const { header, returnType } = vfuncSlotSignature(context, slot, mode === "requirement");
|
|
472
578
|
const declaration = `${isProtected ? "protected " : ""}${header}`;
|
|
473
|
-
const doc = renderJsDoc(slotDoc(slot), vfuncMemberNote(options), slotDocSpec(slot));
|
|
579
|
+
const doc = renderJsDoc(slotDoc(slot), vfuncMemberNote(options), slotDocSpec(context, slot));
|
|
474
580
|
|
|
475
581
|
if (mode !== "implementation") {
|
|
476
582
|
return `${doc}${declaration};`;
|
|
477
583
|
}
|
|
478
584
|
|
|
479
|
-
const [, ...parameters] = slot.callback.parameters;
|
|
585
|
+
const [, ...parameters] = slotParamPlan(context, slot.callback).parameters;
|
|
480
586
|
|
|
481
587
|
const inputs = handlerParameters(parameters).map((parameter, index) =>
|
|
482
588
|
parameterIdentifier(parameter, index));
|
|
@@ -511,9 +617,10 @@ const isVtableSlotEligible = (context: ModuleContext, callback: GirCallback): bo
|
|
|
511
617
|
|
|
512
618
|
const renderVtableSlotDescriptor = (context: ModuleContext, vtable: Vtable, slot: VtableSlot): string => {
|
|
513
619
|
const { key, field, callback, byteOffset } = slot;
|
|
620
|
+
const plan = slotParamPlan(context, callback);
|
|
514
621
|
|
|
515
|
-
const argDescriptors =
|
|
516
|
-
.map((param) =>
|
|
622
|
+
const argDescriptors = plan.parameters
|
|
623
|
+
.map((param) => renderSlotParamDescriptor(context, param, plan))
|
|
517
624
|
.join(", ");
|
|
518
625
|
|
|
519
626
|
const returnDescriptor = renderDescriptor(
|
package/src/store/gi-store.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sortStrings } from "@gtkx/utils";
|
|
1
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
3
|
import { dirname, join, resolve } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -11,6 +12,12 @@ type GiNamespaceInput = {
|
|
|
11
12
|
girFile: string;
|
|
12
13
|
};
|
|
13
14
|
|
|
15
|
+
type GiExternalNamespaceInput = {
|
|
16
|
+
directory: string;
|
|
17
|
+
packageName: string;
|
|
18
|
+
girFile: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
14
21
|
const OVERRIDES_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "overrides");
|
|
15
22
|
|
|
16
23
|
const overrideFiles = (directory: string): SourceModule[] => {
|
|
@@ -42,8 +49,17 @@ const barrelFile = (directory: string, girFile: string): SourceModule => {
|
|
|
42
49
|
return overrideModule(barrel.fileName, overrideIndex);
|
|
43
50
|
};
|
|
44
51
|
|
|
52
|
+
const externalShimModule = ({ directory, packageName, girFile }: GiExternalNamespaceInput): SourceModule => ({
|
|
53
|
+
fileName: `${directory}/index.ts`,
|
|
54
|
+
source:
|
|
55
|
+
`/** @deprecated Import from "${packageName}" instead; this alias is removed in GTKX 2.0. */\n` +
|
|
56
|
+
`export * from "${packageName}";\n`,
|
|
57
|
+
origin: girFile,
|
|
58
|
+
});
|
|
59
|
+
|
|
45
60
|
const collectStoreSources = (
|
|
46
61
|
namespaces: GiNamespaceInput[],
|
|
62
|
+
externalNamespaces: GiExternalNamespaceInput[],
|
|
47
63
|
): { collected: SourceModule[]; exportsMap: Record<string, unknown> } => {
|
|
48
64
|
const exportsMap: Record<string, unknown> = {};
|
|
49
65
|
const collected: SourceModule[] = [];
|
|
@@ -58,15 +74,29 @@ const collectStoreSources = (
|
|
|
58
74
|
exportsMap[`./${directory}`] = subpathExport(`${directory}/index`);
|
|
59
75
|
}
|
|
60
76
|
|
|
77
|
+
for (const external of externalNamespaces) {
|
|
78
|
+
collected.push(externalShimModule(external));
|
|
79
|
+
exportsMap[`./${external.directory}`] = subpathExport(`${external.directory}/index`);
|
|
80
|
+
}
|
|
81
|
+
|
|
61
82
|
return { collected, exportsMap };
|
|
62
83
|
};
|
|
63
84
|
|
|
85
|
+
const storePeerDependencies = (externalNamespaces: GiExternalNamespaceInput[]): Record<string, string> =>
|
|
86
|
+
Object.fromEntries(
|
|
87
|
+
sortStrings(["@gtkx/runtime", ...externalNamespaces.map((entry) => entry.packageName)]).map((name) => [
|
|
88
|
+
name,
|
|
89
|
+
"*",
|
|
90
|
+
]),
|
|
91
|
+
);
|
|
92
|
+
|
|
64
93
|
const writeGiStore = (
|
|
65
94
|
options: StoreOptions,
|
|
66
95
|
namespaces: GiNamespaceInput[],
|
|
96
|
+
externalNamespaces: GiExternalNamespaceInput[],
|
|
67
97
|
fingerprint: GiFingerprint,
|
|
68
98
|
): void => {
|
|
69
|
-
const { collected, exportsMap } = collectStoreSources(namespaces);
|
|
99
|
+
const { collected, exportsMap } = collectStoreSources(namespaces, externalNamespaces);
|
|
70
100
|
|
|
71
101
|
writeStore({
|
|
72
102
|
storeDir: options.storeDir,
|
|
@@ -76,10 +106,10 @@ const writeGiStore = (
|
|
|
76
106
|
name: "@gtkx/gi",
|
|
77
107
|
version: options.version,
|
|
78
108
|
exports: exportsMap,
|
|
79
|
-
peerDependencies:
|
|
109
|
+
peerDependencies: storePeerDependencies(externalNamespaces),
|
|
80
110
|
}),
|
|
81
111
|
rawFiles: [{ relativePath: FINGERPRINT_FILENAME, content: `${JSON.stringify(fingerprint, null, 2)}\n` }],
|
|
82
112
|
});
|
|
83
113
|
};
|
|
84
114
|
|
|
85
|
-
export { writeGiStore, type GiNamespaceInput };
|
|
115
|
+
export { writeGiStore, type GiExternalNamespaceInput, type GiNamespaceInput };
|
package/src/store/jsx/jsx.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { GirClass } from "../../gir/class.js";
|
|
|
3
3
|
import type { Library } from "../../gir/library.js";
|
|
4
4
|
import type { GirNamespace } from "../../gir/namespace.js";
|
|
5
5
|
import type { ImportsBuilder } from "../../writer/imports.js";
|
|
6
|
+
import { externalPackageFor } from "../../gir/external-namespaces.js";
|
|
6
7
|
import { renderBlock } from "../../writer/emit.js";
|
|
7
8
|
import { getDoc } from "../gi/doc-spec.js";
|
|
8
9
|
import { elementPropTypeFor } from "./element-prop-imports.js";
|
|
@@ -48,7 +49,8 @@ const addGiNamespace = (imports: ImportsBuilder, namespaceName: string, alias: s
|
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
const specifier = externalPackageFor(namespaceName) ?? `@gtkx/gi/${namespaceName.toLowerCase()}`;
|
|
53
|
+
imports.addNamespace(specifier, alias, true);
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
const addReactBuiltin = (imports: ImportsBuilder, name: string): void => {
|
package/src/store/jsx-store.ts
CHANGED
|
@@ -1,24 +1,40 @@
|
|
|
1
|
+
import { sortStrings } from "@gtkx/utils";
|
|
1
2
|
import type { JsxNamespaceFile } from "./jsx/pipeline.js";
|
|
2
3
|
import type { RawFile } from "./store-fs.js";
|
|
3
4
|
import { buildManifest, namespaceBarrel, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
options: StoreOptions
|
|
7
|
-
namespaces: JsxNamespaceFile[]
|
|
8
|
-
metadata: string
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
type WriteJsxStoreParams = {
|
|
7
|
+
options: StoreOptions;
|
|
8
|
+
namespaces: JsxNamespaceFile[];
|
|
9
|
+
metadata: string;
|
|
10
|
+
externalPackages: string[];
|
|
11
|
+
rawFiles: RawFile[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const jsxPeerDependencies = (externalPackages: string[]): Record<string, string> =>
|
|
15
|
+
Object.fromEntries(
|
|
16
|
+
sortStrings(["@gtkx/gi", "@gtkx/react", "react", ...externalPackages]).map((name) => [name, "*"]),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const writeJsxStore = (params: WriteJsxStoreParams): void => {
|
|
20
|
+
const { options, namespaces, metadata, externalPackages, rawFiles } = params;
|
|
21
|
+
|
|
11
22
|
const exportsMap: Record<string, unknown> = {
|
|
23
|
+
".": subpathExport("index"),
|
|
12
24
|
"./metadata": subpathExport("metadata"),
|
|
13
25
|
};
|
|
14
26
|
|
|
15
27
|
const files = [{ fileName: "metadata.ts", source: metadata }];
|
|
28
|
+
const indexExports: string[] = [];
|
|
16
29
|
|
|
17
30
|
for (const { directory, source } of namespaces) {
|
|
18
31
|
files.push({ fileName: `${directory}/${directory}.tsx`, source }, namespaceBarrel(directory));
|
|
19
32
|
exportsMap[`./${directory}`] = subpathExport(`${directory}/index`);
|
|
33
|
+
indexExports.push(`export * from "./${directory}/index.js";`);
|
|
20
34
|
}
|
|
21
35
|
|
|
36
|
+
files.push({ fileName: "index.ts", source: `${indexExports.join("\n")}\n` });
|
|
37
|
+
|
|
22
38
|
writeStore({
|
|
23
39
|
storeDir: options.storeDir,
|
|
24
40
|
linkDir: options.linkDir,
|
|
@@ -27,7 +43,7 @@ const writeJsxStore = (
|
|
|
27
43
|
name: "@gtkx/jsx",
|
|
28
44
|
version: options.version,
|
|
29
45
|
exports: exportsMap,
|
|
30
|
-
peerDependencies:
|
|
46
|
+
peerDependencies: jsxPeerDependencies(externalPackages),
|
|
31
47
|
}),
|
|
32
48
|
rawFiles,
|
|
33
49
|
});
|
|
@@ -24,6 +24,7 @@ const SCOPE = "@gtkx";
|
|
|
24
24
|
const STORE_NAMES: string[] = ["gi", "jsx"];
|
|
25
25
|
|
|
26
26
|
const STORE_CONSUMERS: string[] = [
|
|
27
|
+
"@gtkx/animated",
|
|
27
28
|
"@gtkx/cli",
|
|
28
29
|
"@gtkx/components",
|
|
29
30
|
"@gtkx/css",
|
|
@@ -213,4 +214,4 @@ const resolveStore = (projectRoot: string): ResolvedStore => {
|
|
|
213
214
|
};
|
|
214
215
|
};
|
|
215
216
|
|
|
216
|
-
export { getShadowingStorePaths, resolveStore, sweepProjectStaging, type ResolvedStore };
|
|
217
|
+
export { getShadowingStorePaths, nodeModulesChain, resolveStore, sweepProjectStaging, type ResolvedStore };
|
package/src/store/store-fs.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { dirname, join, relative } from "node:path";
|
|
|
13
13
|
import { keepFailedProject, type SourceModule } from "../compile.js";
|
|
14
14
|
import { createStagingDir } from "../staging.js";
|
|
15
15
|
import { compileStore } from "./compile-store.js";
|
|
16
|
+
import { ensureExternalPackageLinks, resetExternalPackageLinks } from "./external-package-links.js";
|
|
16
17
|
|
|
17
18
|
/** Where one generated store is written and how it is reached. */
|
|
18
19
|
type StoreOptions = {
|
|
@@ -88,6 +89,7 @@ const writeStore = (params: WriteStoreParams): void => {
|
|
|
88
89
|
try {
|
|
89
90
|
buildTempStore(tmp, params);
|
|
90
91
|
swapStore(tmp, params.storeDir);
|
|
92
|
+
resetExternalPackageLinks(params.storeDir);
|
|
91
93
|
ensureStoreLink(params);
|
|
92
94
|
} catch (error) {
|
|
93
95
|
throw keepFailedProject({ projectDir: tmp, keepAt, error });
|
|
@@ -148,11 +150,15 @@ const isStoreLinked = (link: StoreLink): boolean => {
|
|
|
148
150
|
};
|
|
149
151
|
|
|
150
152
|
const ensureStoreLink = (link: StoreLink): void => {
|
|
151
|
-
if (!existsSync(join(link.storeDir, "package.json"))
|
|
153
|
+
if (!existsSync(join(link.storeDir, "package.json"))) {
|
|
152
154
|
return;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
|
-
|
|
157
|
+
if (!isStoreLinked(link)) {
|
|
158
|
+
symlinkRelative(link.linkDir, link.storeDir);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ensureExternalPackageLinks(link);
|
|
156
162
|
};
|
|
157
163
|
|
|
158
164
|
const storeWriteMessage = (storeDir: string, error: unknown): string =>
|
|
@@ -176,7 +182,9 @@ export {
|
|
|
176
182
|
buildManifest,
|
|
177
183
|
ensureStoreLink,
|
|
178
184
|
namespaceBarrel,
|
|
185
|
+
symlinkRelative,
|
|
179
186
|
writeStore,
|
|
187
|
+
type StoreLink,
|
|
180
188
|
type StoreOptions,
|
|
181
189
|
type RawFile,
|
|
182
190
|
};
|
package/src/writer/context.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Library } from "../gir/library.js";
|
|
2
2
|
import type { GirNamespace } from "../gir/namespace.js";
|
|
3
|
+
import { externalPackageFor } from "../gir/external-namespaces.js";
|
|
3
4
|
import { type Declaration, ModuleBuilder } from "./module.js";
|
|
4
5
|
|
|
5
6
|
class ModuleContext {
|
|
@@ -34,6 +35,7 @@ class ModuleContext {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
this.module.imports.addSideEffect("../gobject/overrides/object.js");
|
|
38
|
+
this.module.imports.addSideEffect("../gobject/overrides/param-spec-getters.js");
|
|
37
39
|
this.module.imports.addSideEffect("../gobject/overrides/value.js");
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -42,6 +44,15 @@ class ModuleContext {
|
|
|
42
44
|
return namespaceName;
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
const packageName = externalPackageFor(namespaceName);
|
|
48
|
+
|
|
49
|
+
if (packageName !== undefined) {
|
|
50
|
+
this.module.imports.addSideEffect(packageName);
|
|
51
|
+
this.module.imports.addNamespace(packageName, namespaceName);
|
|
52
|
+
|
|
53
|
+
return namespaceName;
|
|
54
|
+
}
|
|
55
|
+
|
|
45
56
|
const directory = namespaceName.toLowerCase();
|
|
46
57
|
const isFoundational = directory === "gobject" || directory === "glib";
|
|
47
58
|
const path = isFoundational ? `../${directory}/${directory}.js` : `../${directory}/index.js`;
|
package/src/writer/gtk-doc.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { camelCase } from "@gtkx/utils";
|
|
1
|
+
import { camelCase, kebabCase } from "@gtkx/utils";
|
|
2
|
+
import { HIDDEN_SYMBOLS } from "../gir/hidden-symbols.js";
|
|
2
3
|
|
|
3
4
|
const CONSTANT_MAP: Record<string, string> = { TRUE: "true", FALSE: "false", NULL: "null" };
|
|
5
|
+
|
|
6
|
+
const HIDDEN_LINK_PREFIXES: Map<string, string> = new Map([
|
|
7
|
+
["GLib", "g"],
|
|
8
|
+
["GObject", "g"],
|
|
9
|
+
["Gio", "g"],
|
|
10
|
+
]);
|
|
11
|
+
|
|
4
12
|
const CALLABLE_LINK_KINDS: Set<string> = new Set(["method", "func", "ctor", "vfunc", "id"]);
|
|
5
13
|
const SENTINEL = String.fromCodePoint(0xE0_00);
|
|
6
14
|
const CODE_BLOCK_OPEN = "|[";
|
|
@@ -27,8 +35,37 @@ const DOCBOOK_LIST_PATTERN = /<\/?itemizedlist>\s*/g;
|
|
|
27
35
|
const DOCBOOK_PARA_PATTERN = /<\/?para>\s*/g;
|
|
28
36
|
const BLANK_LINE_RUN_PATTERN = /\n{3,}/g;
|
|
29
37
|
|
|
38
|
+
const cSymbolSegment = (segment: string): string => kebabCase(segment).replaceAll("-", "_");
|
|
39
|
+
|
|
40
|
+
const hiddenLinkCandidate = (segments: string[]): string | undefined => {
|
|
41
|
+
const [namespace, ...rest] = segments;
|
|
42
|
+
const prefix = namespace === undefined ? undefined : HIDDEN_LINK_PREFIXES.get(namespace);
|
|
43
|
+
|
|
44
|
+
if (prefix === undefined || rest.length === 0) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return [prefix, ...rest.map((segment) => cSymbolSegment(segment))].join("_");
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const hiddenCIdentifier = (kind: string, target: string, segments: string[]): string | undefined => {
|
|
52
|
+
if (!CALLABLE_LINK_KINDS.has(kind)) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const candidate = kind === "id" ? target : hiddenLinkCandidate(segments);
|
|
57
|
+
|
|
58
|
+
return candidate !== undefined && HIDDEN_SYMBOLS.has(candidate) ? candidate : undefined;
|
|
59
|
+
};
|
|
60
|
+
|
|
30
61
|
const renderLink = (kind: string, target: string): string => {
|
|
31
62
|
const segments = target.split(/::|[.:]/);
|
|
63
|
+
const hidden = hiddenCIdentifier(kind, target, segments);
|
|
64
|
+
|
|
65
|
+
if (hidden !== undefined) {
|
|
66
|
+
return `\`${hidden}()\``;
|
|
67
|
+
}
|
|
68
|
+
|
|
32
69
|
const lastIndex = segments.length - 1;
|
|
33
70
|
|
|
34
71
|
if (kind === "property" || CALLABLE_LINK_KINDS.has(kind)) {
|