@gtkx/codegen 1.4.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/README.md +1 -1
- 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/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +2 -0
- 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 +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/resolve-store.ts +2 -0
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/codegen",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Generates typed GTK bindings and API docs from GIR and GL registries.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gtkx",
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"fast-xml-parser": "^5.11.0",
|
|
59
59
|
"fast-xml-validator": "^1.4.2",
|
|
60
60
|
"typescript": "^6.0.3",
|
|
61
|
-
"@gtkx/
|
|
62
|
-
"@gtkx/utils": "1.
|
|
63
|
-
"@gtkx/
|
|
61
|
+
"@gtkx/react": "1.6.0",
|
|
62
|
+
"@gtkx/utils": "1.6.0",
|
|
63
|
+
"@gtkx/cairo": "1.6.0"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"release": "tsx ../../scripts/release-package.ts"
|
|
@@ -62,6 +62,7 @@ type ArgIndexOptions = {
|
|
|
62
62
|
argIndexMap: Map<number, number> | undefined;
|
|
63
63
|
cursor: GirCursorBounds | undefined;
|
|
64
64
|
hasOutIndirection: boolean;
|
|
65
|
+
isReceived: boolean;
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
type CursorArgIndexOptions = ArgIndexOptions & { cursor: GirCursorBounds };
|
|
@@ -76,11 +77,13 @@ type RenderDescriptorOptions = Partial<ArgIndexOptions> & {
|
|
|
76
77
|
type RecordPlacement = {
|
|
77
78
|
isCallerAllocated?: boolean;
|
|
78
79
|
isInline?: boolean;
|
|
80
|
+
isReceived?: boolean;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
type RecordLayout = {
|
|
82
84
|
isCallerAllocated: boolean;
|
|
83
85
|
isInline: boolean;
|
|
86
|
+
isReceived: boolean;
|
|
84
87
|
};
|
|
85
88
|
|
|
86
89
|
type FundamentalDescriptor = {
|
|
@@ -90,6 +93,7 @@ type FundamentalDescriptor = {
|
|
|
90
93
|
typeName: string | undefined;
|
|
91
94
|
ownership: Ownership;
|
|
92
95
|
wrapperClass?: string | undefined;
|
|
96
|
+
fallbackClass?: string | undefined;
|
|
93
97
|
isCallerAllocated?: boolean | undefined;
|
|
94
98
|
isInline?: boolean | undefined;
|
|
95
99
|
};
|
|
@@ -110,6 +114,7 @@ type FundamentalRecordOptions = {
|
|
|
110
114
|
unrefFunc: string;
|
|
111
115
|
ownership: Ownership;
|
|
112
116
|
wrapperClass: string | undefined;
|
|
117
|
+
fallbackClass?: string | undefined;
|
|
113
118
|
isCallerAllocated: boolean;
|
|
114
119
|
isInline: boolean;
|
|
115
120
|
};
|
|
@@ -169,6 +174,7 @@ const argIndexOptions = (options: RenderDescriptorOptions): ArgIndexOptions => (
|
|
|
169
174
|
argIndexMap: options.argIndexMap,
|
|
170
175
|
cursor: options.cursor,
|
|
171
176
|
hasOutIndirection: options.hasOutIndirection === true,
|
|
177
|
+
isReceived: options.isReceived === true,
|
|
172
178
|
});
|
|
173
179
|
|
|
174
180
|
const renderDescriptor = (
|
|
@@ -310,7 +316,12 @@ const renderParamDescriptor = (
|
|
|
310
316
|
ref: TypeId | undefined,
|
|
311
317
|
argIndex: Partial<ArgIndexOptions> = {},
|
|
312
318
|
): string => {
|
|
313
|
-
const behindRef: RenderDescriptorOptions = {
|
|
319
|
+
const behindRef: RenderDescriptorOptions = {
|
|
320
|
+
...argIndex,
|
|
321
|
+
cursor: parameter.cursor,
|
|
322
|
+
hasOutIndirection: true,
|
|
323
|
+
isReceived: true,
|
|
324
|
+
};
|
|
314
325
|
|
|
315
326
|
if (isCellInout(context.library, parameter)) {
|
|
316
327
|
return tRef(renderDescriptor(context, ref, parameter.transferOwnership, behindRef), true);
|
|
@@ -323,6 +334,7 @@ const renderParamDescriptor = (
|
|
|
323
334
|
return renderDescriptor(context, ref, parameter.transferOwnership, {
|
|
324
335
|
...argIndex,
|
|
325
336
|
isCallerAllocated: isCallerAllocatedOut(parameter) || isRecordInout(context, parameter),
|
|
337
|
+
isReceived: true,
|
|
326
338
|
});
|
|
327
339
|
};
|
|
328
340
|
|
|
@@ -394,7 +406,7 @@ const renderCallbackType = (
|
|
|
394
406
|
|
|
395
407
|
return tCallback({
|
|
396
408
|
argTypes,
|
|
397
|
-
returns: renderDescriptor(context, returnValue.type, returnValue.transferOwnership),
|
|
409
|
+
returns: renderDescriptor(context, returnValue.type, returnValue.transferOwnership, { isReceived: true }),
|
|
398
410
|
options: callbackOptionsArg(owningParameter, findUserDataIndex(callback.parameters), callback.throws),
|
|
399
411
|
});
|
|
400
412
|
};
|
|
@@ -420,17 +432,28 @@ const primitiveExpression = (category: PrimitiveCategory, ownership: Ownership):
|
|
|
420
432
|
};
|
|
421
433
|
|
|
422
434
|
const renderFundamental = (descriptor: FundamentalDescriptor): string => {
|
|
423
|
-
const { lib, refFunc, unrefFunc, typeName, ownership, wrapperClass,
|
|
435
|
+
const { lib, refFunc, unrefFunc, typeName, ownership, wrapperClass, fallbackClass } = descriptor;
|
|
424
436
|
|
|
425
437
|
return tFundamental(lib, refFunc, unrefFunc, {
|
|
426
438
|
ownership,
|
|
427
439
|
typeName,
|
|
428
440
|
wrapperClass,
|
|
429
|
-
|
|
430
|
-
|
|
441
|
+
fallbackClass,
|
|
442
|
+
isCallerAllocated: descriptor.isCallerAllocated,
|
|
443
|
+
isInline: descriptor.isInline,
|
|
431
444
|
});
|
|
432
445
|
};
|
|
433
446
|
|
|
447
|
+
const fallbackClassThunk = (
|
|
448
|
+
context: ModuleContext,
|
|
449
|
+
namespaceName: string,
|
|
450
|
+
name: string,
|
|
451
|
+
isReceived: boolean,
|
|
452
|
+
): string | undefined =>
|
|
453
|
+
isReceived && context.library.isTreeShaken
|
|
454
|
+
? `() => ${context.qualify(namespaceName, sanitizeTypeIdentifier(name))}`
|
|
455
|
+
: undefined;
|
|
456
|
+
|
|
434
457
|
const sunkOwnership = (
|
|
435
458
|
ancestor: AncestorFundamental,
|
|
436
459
|
ownership: Ownership,
|
|
@@ -447,15 +470,20 @@ const classOrInterfaceExpression = (
|
|
|
447
470
|
context: ModuleContext,
|
|
448
471
|
resolved: Extract<EntityType, { kind: "class" | "interface" }>,
|
|
449
472
|
ownership: Ownership,
|
|
450
|
-
isNewlyCreated: boolean,
|
|
473
|
+
options: { isNewlyCreated: boolean; isReceived: boolean },
|
|
451
474
|
): string => {
|
|
452
475
|
const ancestor = fundamentalAncestor(context, resolved);
|
|
476
|
+
const fallbackClass = fallbackClassThunk(context, resolved.namespace.name, resolved.value.name, options.isReceived);
|
|
453
477
|
|
|
454
478
|
if (ancestor === undefined) {
|
|
455
|
-
return tObject(ownership);
|
|
479
|
+
return tObject(ownership, fallbackClass);
|
|
456
480
|
}
|
|
457
481
|
|
|
458
|
-
return renderFundamental({
|
|
482
|
+
return renderFundamental({
|
|
483
|
+
...ancestor,
|
|
484
|
+
ownership: sunkOwnership(ancestor, ownership, options.isNewlyCreated),
|
|
485
|
+
fallbackClass,
|
|
486
|
+
});
|
|
459
487
|
};
|
|
460
488
|
|
|
461
489
|
const isClassOrInterface = (type: GirType | undefined): type is Extract<EntityType, { kind: "class" | "interface" }> =>
|
|
@@ -552,6 +580,7 @@ const renderSelfDescriptor = (context: ModuleContext, instance: GirParameter): s
|
|
|
552
580
|
const recordLayout = (placement: RecordPlacement): RecordLayout => ({
|
|
553
581
|
isCallerAllocated: placement.isCallerAllocated ?? false,
|
|
554
582
|
isInline: placement.isInline ?? false,
|
|
583
|
+
isReceived: placement.isReceived === true,
|
|
555
584
|
});
|
|
556
585
|
|
|
557
586
|
const recordRefPair = (record: ResolvedRecord): { refFunc: string | undefined; unrefFunc: string | undefined } => ({
|
|
@@ -588,7 +617,7 @@ const structExpression = (
|
|
|
588
617
|
};
|
|
589
618
|
|
|
590
619
|
const fundamentalRecordExpression = (options: FundamentalRecordOptions): string => {
|
|
591
|
-
const { resolved, lib, refFunc, unrefFunc, ownership, wrapperClass,
|
|
620
|
+
const { resolved, lib, refFunc, unrefFunc, ownership, wrapperClass, fallbackClass } = options;
|
|
592
621
|
|
|
593
622
|
return renderFundamental({
|
|
594
623
|
lib,
|
|
@@ -597,8 +626,9 @@ const fundamentalRecordExpression = (options: FundamentalRecordOptions): string
|
|
|
597
626
|
typeName: resolved.value.glibTypeName,
|
|
598
627
|
ownership,
|
|
599
628
|
wrapperClass,
|
|
600
|
-
|
|
601
|
-
|
|
629
|
+
fallbackClass,
|
|
630
|
+
isCallerAllocated: options.isCallerAllocated,
|
|
631
|
+
isInline: options.isInline,
|
|
602
632
|
});
|
|
603
633
|
};
|
|
604
634
|
|
|
@@ -608,6 +638,7 @@ const boxedRecordExpression = (options: {
|
|
|
608
638
|
ownership: Ownership;
|
|
609
639
|
isCallerAllocated: boolean;
|
|
610
640
|
isInline: boolean;
|
|
641
|
+
isReceived: boolean;
|
|
611
642
|
typeFnName: string;
|
|
612
643
|
}): string => {
|
|
613
644
|
const { context, resolved, ownership, isCallerAllocated, isInline, typeFnName } = options;
|
|
@@ -623,6 +654,7 @@ const boxedRecordExpression = (options: {
|
|
|
623
654
|
isCallerAllocated,
|
|
624
655
|
isInline,
|
|
625
656
|
size: size > 0 ? size : undefined,
|
|
657
|
+
fallbackClass: fallbackClassThunk(context, resolved.namespace.name, record.name, options.isReceived),
|
|
626
658
|
});
|
|
627
659
|
};
|
|
628
660
|
|
|
@@ -653,35 +685,48 @@ const isPlainStruct = (resolved: Extract<EntityType, { kind: "record" }>): boole
|
|
|
653
685
|
return record.glibGetType === undefined;
|
|
654
686
|
};
|
|
655
687
|
|
|
656
|
-
const
|
|
688
|
+
const fundamentalRecordPath = (
|
|
657
689
|
context: ModuleContext,
|
|
658
690
|
resolved: Extract<EntityType, { kind: "record" }>,
|
|
659
691
|
ownership: Ownership,
|
|
660
|
-
placement: RecordPlacement
|
|
661
|
-
): string => {
|
|
692
|
+
placement: RecordPlacement,
|
|
693
|
+
): string | undefined => {
|
|
662
694
|
const record = resolved.value;
|
|
663
695
|
const { refFunc, unrefFunc } = recordRefPair(record);
|
|
664
696
|
const lib = resolved.namespace.sharedLibrary;
|
|
665
697
|
|
|
666
|
-
if (refFunc
|
|
667
|
-
|
|
668
|
-
? context.qualify(resolved.namespace.name, sanitizeTypeIdentifier(record.name))
|
|
669
|
-
: undefined;
|
|
670
|
-
|
|
671
|
-
return fundamentalRecordExpression({
|
|
672
|
-
resolved,
|
|
673
|
-
lib,
|
|
674
|
-
refFunc,
|
|
675
|
-
unrefFunc,
|
|
676
|
-
ownership,
|
|
677
|
-
wrapperClass,
|
|
678
|
-
...recordLayout(placement),
|
|
679
|
-
});
|
|
698
|
+
if (refFunc === undefined || unrefFunc === undefined || lib === undefined) {
|
|
699
|
+
return undefined;
|
|
680
700
|
}
|
|
681
701
|
|
|
682
|
-
|
|
702
|
+
const wrapperClass = requiresFallbackClass(record)
|
|
703
|
+
? context.qualify(resolved.namespace.name, sanitizeTypeIdentifier(record.name))
|
|
704
|
+
: undefined;
|
|
705
|
+
|
|
706
|
+
return fundamentalRecordExpression({
|
|
707
|
+
resolved,
|
|
708
|
+
lib,
|
|
709
|
+
refFunc,
|
|
710
|
+
unrefFunc,
|
|
711
|
+
ownership,
|
|
712
|
+
wrapperClass,
|
|
713
|
+
fallbackClass:
|
|
714
|
+
wrapperClass === undefined
|
|
715
|
+
? fallbackClassThunk(context, resolved.namespace.name, record.name, placement.isReceived === true)
|
|
716
|
+
: undefined,
|
|
717
|
+
...recordLayout(placement),
|
|
718
|
+
});
|
|
683
719
|
};
|
|
684
720
|
|
|
721
|
+
const recordExpression = (
|
|
722
|
+
context: ModuleContext,
|
|
723
|
+
resolved: Extract<EntityType, { kind: "record" }>,
|
|
724
|
+
ownership: Ownership,
|
|
725
|
+
placement: RecordPlacement = {},
|
|
726
|
+
): string =>
|
|
727
|
+
fundamentalRecordPath(context, resolved, ownership, placement) ??
|
|
728
|
+
plainRecordExpression(context, resolved, ownership, placement);
|
|
729
|
+
|
|
685
730
|
const rawEnumDescriptor = (isSigned: boolean): string => (isSigned ? tInt32 : tUint32);
|
|
686
731
|
|
|
687
732
|
const flagsMask = (resolved: Extract<EntityType, { kind: "enum" }>): number =>
|
|
@@ -711,12 +756,16 @@ const expressionForResolved = (
|
|
|
711
756
|
switch (resolved.kind) {
|
|
712
757
|
case "class":
|
|
713
758
|
case "interface": {
|
|
714
|
-
return classOrInterfaceExpression(context, resolved, ownership,
|
|
759
|
+
return classOrInterfaceExpression(context, resolved, ownership, {
|
|
760
|
+
isNewlyCreated: options.isNewlyCreated ?? false,
|
|
761
|
+
isReceived: options.isReceived === true,
|
|
762
|
+
});
|
|
715
763
|
}
|
|
716
764
|
case "record": {
|
|
717
765
|
return recordExpression(context, resolved, ownership, {
|
|
718
766
|
isCallerAllocated: options.isCallerAllocated ?? false,
|
|
719
767
|
isInline: options.isInline ?? false,
|
|
768
|
+
isReceived: options.isReceived === true,
|
|
720
769
|
});
|
|
721
770
|
}
|
|
722
771
|
case "enum": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
import type { GirCursorBounds } from "../gir/parameter.js";
|
|
3
|
-
import { joinArgs } from "../writer/emit.js";
|
|
3
|
+
import { joinArgs, pure } from "../writer/emit.js";
|
|
4
4
|
|
|
5
5
|
type Ownership = "borrowed" | "full";
|
|
6
6
|
|
|
@@ -70,6 +70,7 @@ type BoxedOptions = {
|
|
|
70
70
|
isCallerAllocated: boolean;
|
|
71
71
|
isInline?: boolean;
|
|
72
72
|
size: number | undefined;
|
|
73
|
+
fallbackClass?: string | undefined;
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
type StructOptions = {
|
|
@@ -83,6 +84,7 @@ type FundamentalOptions = {
|
|
|
83
84
|
ownership: Ownership;
|
|
84
85
|
typeName: string | undefined;
|
|
85
86
|
wrapperClass: string | undefined;
|
|
87
|
+
fallbackClass?: string | undefined;
|
|
86
88
|
isCallerAllocated?: boolean | undefined;
|
|
87
89
|
isInline?: boolean | undefined;
|
|
88
90
|
};
|
|
@@ -178,26 +180,29 @@ const optionsObject = (parts: (string | undefined)[]): string | undefined => {
|
|
|
178
180
|
return present.length === 0 ? undefined : `{ ${present.join(", ")} }`;
|
|
179
181
|
};
|
|
180
182
|
|
|
183
|
+
const optionalLiteralEntry = (key: string, value: string | undefined): string | undefined =>
|
|
184
|
+
value === undefined ? undefined : `${key}: ${sourceStringLiteral(value)}`;
|
|
185
|
+
|
|
181
186
|
const tScalar = (name: ScalarDescriptorName): string => T[name];
|
|
182
187
|
|
|
183
188
|
const tString = (ownership: Ownership, length?: string): string =>
|
|
184
189
|
call("string", [sourceStringLiteral(ownership), length]);
|
|
185
190
|
|
|
186
|
-
const tObject = (ownership: Ownership): string =>
|
|
191
|
+
const tObject = (ownership: Ownership, fallbackClass?: string): string =>
|
|
192
|
+
call("object", [sourceStringLiteral(ownership), fallbackClass]);
|
|
187
193
|
|
|
188
194
|
const tBoxed = (glibName: string, options: BoxedOptions): string =>
|
|
189
195
|
call("boxed", [
|
|
190
196
|
sourceStringLiteral(glibName),
|
|
191
197
|
optionsObject([
|
|
192
198
|
`ownership: ${sourceStringLiteral(options.ownership)}`,
|
|
193
|
-
options.sharedLibrary
|
|
194
|
-
? undefined
|
|
195
|
-
: `sharedLibrary: ${sourceStringLiteral(options.sharedLibrary)}`,
|
|
199
|
+
optionalLiteralEntry("sharedLibrary", options.sharedLibrary),
|
|
196
200
|
`getTypeFnName: ${sourceStringLiteral(options.getTypeFnName)}`,
|
|
197
|
-
|
|
201
|
+
optionalLiteralEntry("freeFnName", options.freeFnName),
|
|
198
202
|
options.isCallerAllocated ? "isCallerAllocated: true" : undefined,
|
|
199
203
|
options.isInline === true ? "isInline: true" : undefined,
|
|
200
204
|
options.size === undefined ? undefined : `size: ${String(options.size)}`,
|
|
205
|
+
options.fallbackClass === undefined ? undefined : `fallbackClass: ${options.fallbackClass}`,
|
|
201
206
|
]),
|
|
202
207
|
]);
|
|
203
208
|
|
|
@@ -224,6 +229,7 @@ const tFundamental = (lib: string, refFunc: string, unrefFunc: string, options:
|
|
|
224
229
|
`ownership: ${sourceStringLiteral(options.ownership)}`,
|
|
225
230
|
options.typeName === undefined ? undefined : `typeName: ${sourceStringLiteral(options.typeName)}`,
|
|
226
231
|
options.wrapperClass === undefined ? undefined : `wrapperClass: ${options.wrapperClass}`,
|
|
232
|
+
options.fallbackClass === undefined ? undefined : `fallbackClass: ${options.fallbackClass}`,
|
|
227
233
|
options.isCallerAllocated === true ? "isCallerAllocated: true" : undefined,
|
|
228
234
|
options.isInline === true ? "isInline: true" : undefined,
|
|
229
235
|
]),
|
|
@@ -327,11 +333,13 @@ const tFn = (lib: string, cIdentifier: string, spec: FnSpecParts): string => {
|
|
|
327
333
|
const unpackEntry = spec.isReturnUnpacked ? `, ${UNPACKED_RETURN_ENTRY}` : "";
|
|
328
334
|
const throwsEntry = spec.canThrow ? ", canThrow: true" : "";
|
|
329
335
|
|
|
330
|
-
return
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
336
|
+
return pure(
|
|
337
|
+
call("fn", [
|
|
338
|
+
sourceStringLiteral(lib),
|
|
339
|
+
sourceStringLiteral(cIdentifier),
|
|
340
|
+
`() => ({ args: ${spec.args}, returns: ${spec.returns}${skipEntry}${unpackEntry}${throwsEntry} })`,
|
|
341
|
+
]),
|
|
342
|
+
);
|
|
335
343
|
};
|
|
336
344
|
|
|
337
345
|
export {
|
package/src/compile.ts
CHANGED
|
@@ -76,9 +76,12 @@ const DECLARATION_EMIT = {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
const MODULE_EMIT = {
|
|
79
|
-
removeComments:
|
|
79
|
+
removeComments: false,
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
const PURE_ANNOTATION_TEXT = "@__PURE__";
|
|
83
|
+
const PURE_ANNOTATION_COMMENT = ` ${PURE_ANNOTATION_TEXT} `;
|
|
84
|
+
|
|
82
85
|
const DECLARATION_OPTIONS = ts.convertCompilerOptionsFromJson(
|
|
83
86
|
{ ...BASE_COMPILER_OPTIONS, ...DECLARATION_EMIT },
|
|
84
87
|
".",
|
|
@@ -213,7 +216,7 @@ const diagnosticError = (params: ProjectContext, diagnostics: ts.Diagnostic[]):
|
|
|
213
216
|
|
|
214
217
|
const lines = [...diagnosed.map((entry) => entry.text), ...originLines(diagnosed, params.files)];
|
|
215
218
|
|
|
216
|
-
return new Error(`Compiling ${label}
|
|
219
|
+
return new Error(`Compiling ${label} failed:\n${lines.join("\n")}`);
|
|
217
220
|
};
|
|
218
221
|
|
|
219
222
|
const keepFailedProject = (input: FailedProjectInput): Error => {
|
|
@@ -266,10 +269,46 @@ const transpileOptions = (compilerOptions: ts.CompilerOptions, fileName: string)
|
|
|
266
269
|
reportDiagnostics: true,
|
|
267
270
|
});
|
|
268
271
|
|
|
272
|
+
const isPureAnnotated = (text: string, node: ts.Node): boolean =>
|
|
273
|
+
ts.isCallExpression(node) &&
|
|
274
|
+
node.pos >= 0 &&
|
|
275
|
+
(ts.getLeadingCommentRanges(text, node.pos) ?? []).some((range) =>
|
|
276
|
+
text.slice(range.pos, range.end).includes(PURE_ANNOTATION_TEXT),
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
const dropCommentsExceptPureAnnotations =
|
|
280
|
+
(): ts.TransformerFactory<ts.SourceFile> => (context) => (sourceFile) => {
|
|
281
|
+
const { text } = sourceFile;
|
|
282
|
+
|
|
283
|
+
const visit = (node: ts.Node): ts.Node => {
|
|
284
|
+
const isPure = isPureAnnotated(text, node);
|
|
285
|
+
const visited = ts.visitEachChild(node, visit, context);
|
|
286
|
+
ts.setEmitFlags(visited, ts.EmitFlags.NoLeadingComments | ts.EmitFlags.NoTrailingComments);
|
|
287
|
+
|
|
288
|
+
if (isPure) {
|
|
289
|
+
ts.addSyntheticLeadingComment(
|
|
290
|
+
visited,
|
|
291
|
+
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
292
|
+
PURE_ANNOTATION_COMMENT,
|
|
293
|
+
false,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return visited;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
return ts.visitEachChild(sourceFile, visit, context);
|
|
301
|
+
};
|
|
302
|
+
|
|
269
303
|
const emitModule = (module: SourceModule, projectDir: string): ts.Diagnostic[] => {
|
|
270
304
|
const fileName = join(projectDir, module.fileName);
|
|
271
305
|
const declaration = ts.transpileDeclaration(module.source, transpileOptions(DECLARATION_OPTIONS, fileName));
|
|
272
|
-
|
|
306
|
+
|
|
307
|
+
const javascript = ts.transpileModule(module.source, {
|
|
308
|
+
...transpileOptions(MODULE_OPTIONS, fileName),
|
|
309
|
+
transformers: { after: [dropCommentsExceptPureAnnotations()] },
|
|
310
|
+
});
|
|
311
|
+
|
|
273
312
|
const diagnostics = [...declaration.diagnostics ?? [], ...javascript.diagnostics ?? []];
|
|
274
313
|
|
|
275
314
|
if (diagnostics.length > 0) {
|
|
@@ -33,6 +33,8 @@ type ApiReferenceOptions = {
|
|
|
33
33
|
isFinishTrimmed?: boolean;
|
|
34
34
|
/** Describes a handle-passing inout parameter as mutated in place rather than returned; off by default. */
|
|
35
35
|
isInoutInPlace?: boolean;
|
|
36
|
+
/** Folds registrations into each class so bundlers can drop unused ones; off by default. */
|
|
37
|
+
isTreeShaken?: boolean;
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
/** Narrows an `ApiReference.symbols` enumeration. */
|
|
@@ -386,6 +388,7 @@ class ApiReference {
|
|
|
386
388
|
isValueUnwrapped: options.isValueUnwrapped === true,
|
|
387
389
|
isFinishTrimmed: options.isFinishTrimmed === true,
|
|
388
390
|
isInoutInPlace: options.isInoutInPlace === true,
|
|
391
|
+
isTreeShaken: options.isTreeShaken === true,
|
|
389
392
|
});
|
|
390
393
|
|
|
391
394
|
this.elementContext = { library: this.library, linkFor: (): string | undefined => undefined };
|
|
@@ -679,7 +682,7 @@ class ApiReference {
|
|
|
679
682
|
|
|
680
683
|
lines.push(
|
|
681
684
|
"",
|
|
682
|
-
`## ${KIND_SECTION_TITLES[kind]}
|
|
685
|
+
`## ${KIND_SECTION_TITLES[kind]}`,
|
|
683
686
|
"",
|
|
684
687
|
sortStrings(names)
|
|
685
688
|
.map((symbolName) => `\`${symbolName}\``)
|
package/src/docs/pipeline.ts
CHANGED
|
@@ -30,11 +30,14 @@ type DocsNamespace = {
|
|
|
30
30
|
elements: DocsElementLink[];
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
type DocsLinkStyle = "url" | "file";
|
|
34
|
+
|
|
33
35
|
type DocsOptions = {
|
|
34
36
|
libraries: string[];
|
|
35
37
|
girPath: string[];
|
|
36
38
|
outDir: string;
|
|
37
39
|
basePath?: string;
|
|
40
|
+
linkStyle?: DocsLinkStyle;
|
|
38
41
|
props?: ElementProps;
|
|
39
42
|
omittedProps?: OmittedProps;
|
|
40
43
|
isForced?: boolean;
|
|
@@ -42,6 +45,7 @@ type DocsOptions = {
|
|
|
42
45
|
isValueUnwrapped?: boolean;
|
|
43
46
|
isFinishTrimmed?: boolean;
|
|
44
47
|
isInoutInPlace?: boolean;
|
|
48
|
+
isTreeShaken?: boolean;
|
|
45
49
|
};
|
|
46
50
|
|
|
47
51
|
type DocsManifest = {
|
|
@@ -75,9 +79,7 @@ const namespaceIndexPage = (namespace: DocsNamespace, elements: GlibNamedClass[]
|
|
|
75
79
|
return `| [${entry.glibName}](${link}) | ${description} |`;
|
|
76
80
|
});
|
|
77
81
|
|
|
78
|
-
const description =
|
|
79
|
-
`Reference pages for the ${String(namespace.elements.length)} JSX elements in ` +
|
|
80
|
-
`the ${namespace.name} namespace.`;
|
|
82
|
+
const description = `Reference pages for the JSX elements in the ${namespace.name} namespace.`;
|
|
81
83
|
|
|
82
84
|
return [
|
|
83
85
|
"---",
|
|
@@ -96,7 +98,41 @@ const namespaceIndexPage = (namespace: DocsNamespace, elements: GlibNamedClass[]
|
|
|
96
98
|
].join("\n");
|
|
97
99
|
};
|
|
98
100
|
|
|
99
|
-
const
|
|
101
|
+
const fileIndexPage = (namespaces: DocsNamespace[], libraries: string[]): string => {
|
|
102
|
+
const rows = namespaces.map(
|
|
103
|
+
(ns) => `| ${ns.name} | \`@gtkx/jsx/${ns.directory}\` | ${String(ns.elements.length)} | ${ns.link} |`,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const librariesList = libraries.map((library) => `\`${library}\``).join(", ");
|
|
107
|
+
|
|
108
|
+
return [
|
|
109
|
+
"# Element reference",
|
|
110
|
+
"",
|
|
111
|
+
`Every JSX element generated from ${librariesList} by \`gtkx codegen\` has a page here, regenerated ` +
|
|
112
|
+
"whenever the GIR libraries or the project's element configuration change. These pages describe " +
|
|
113
|
+
"this project's bindings exactly, so they are the authority on props, signals, and method signatures.",
|
|
114
|
+
"",
|
|
115
|
+
"Every path here is from the project root, ready to read as-is.",
|
|
116
|
+
"",
|
|
117
|
+
"One page per element, at `<namespace>/<element>.md`, where the element file name is its class name in " +
|
|
118
|
+
"kebab-case without the namespace prefix: `GtkButton` is `gtk/button.md`, `AdwHeaderBar` is " +
|
|
119
|
+
"`adw/header-bar.md`. Read a page directly by that path rather than searching for it.",
|
|
120
|
+
"",
|
|
121
|
+
"Each page lists the element's props (GObject properties plus what GTKX adds, with types and defaults), " +
|
|
122
|
+
"its signals as `on<Signal>` handler props with exact signatures, and the methods reachable through `ref`.",
|
|
123
|
+
"",
|
|
124
|
+
"| Namespace | Import | Elements | Index |",
|
|
125
|
+
"| --- | --- | --- | --- |",
|
|
126
|
+
...rows,
|
|
127
|
+
"",
|
|
128
|
+
].join("\n");
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const rootIndexPage = (namespaces: DocsNamespace[], libraries: string[], linkStyle: DocsLinkStyle): string => {
|
|
132
|
+
if (linkStyle === "file") {
|
|
133
|
+
return fileIndexPage(namespaces, libraries);
|
|
134
|
+
}
|
|
135
|
+
|
|
100
136
|
const rows = namespaces.map(
|
|
101
137
|
(ns) => `| [${ns.name}](${ns.link}) | \`@gtkx/jsx/${ns.directory}\` | ${String(ns.elements.length)} |`,
|
|
102
138
|
);
|
|
@@ -143,12 +179,17 @@ const groupElementsByNamespace = (elements: GlibNamedClass[]): Map<string, GlibN
|
|
|
143
179
|
return byNamespace;
|
|
144
180
|
};
|
|
145
181
|
|
|
146
|
-
const buildElementLinks = (
|
|
182
|
+
const buildElementLinks = (
|
|
183
|
+
elements: GlibNamedClass[],
|
|
184
|
+
basePath: string,
|
|
185
|
+
linkStyle: DocsLinkStyle,
|
|
186
|
+
): Map<string, string> => {
|
|
147
187
|
const linkByGlibName: Map<string, string> = new Map();
|
|
188
|
+
const suffix = linkStyle === "file" ? ".md" : "";
|
|
148
189
|
|
|
149
190
|
for (const entry of elements) {
|
|
150
191
|
const directory = namespaceDirectory(entry.namespace);
|
|
151
|
-
const link = `${basePath}/${directory}/${elementSlug(entry.klass.name)}`;
|
|
192
|
+
const link = `${basePath}/${directory}/${elementSlug(entry.klass.name)}${suffix}`;
|
|
152
193
|
|
|
153
194
|
if (linkByGlibName.values().some((existing) => existing === link)) {
|
|
154
195
|
throw new Error(`Docs page slug collision for ${entry.glibName} at ${link}`);
|
|
@@ -186,16 +227,17 @@ const namespacePages = (input: {
|
|
|
186
227
|
name: string;
|
|
187
228
|
elements: GlibNamedClass[];
|
|
188
229
|
basePath: string;
|
|
230
|
+
linkStyle: DocsLinkStyle;
|
|
189
231
|
linkByGlibName: Map<string, string>;
|
|
190
232
|
pageContext: ElementPageContext;
|
|
191
233
|
}): NamespacePages => {
|
|
192
|
-
const { name, elements, basePath, linkByGlibName, pageContext } = input;
|
|
234
|
+
const { name, elements, basePath, linkStyle, linkByGlibName, pageContext } = input;
|
|
193
235
|
const directory = ownedEntry(namespaceDirectory({ name }), `the GIR namespace ${name}`);
|
|
194
236
|
|
|
195
237
|
const docs: DocsNamespace = {
|
|
196
238
|
name,
|
|
197
239
|
directory,
|
|
198
|
-
link: `${basePath}/${directory}/`,
|
|
240
|
+
link: linkStyle === "file" ? `${basePath}/${directory}/index.md` : `${basePath}/${directory}/`,
|
|
199
241
|
elements: elements.map((entry) => ({ text: entry.glibName, link: linkByGlibName.get(entry.glibName) ?? "" })),
|
|
200
242
|
};
|
|
201
243
|
|
|
@@ -209,10 +251,15 @@ const namespacePages = (input: {
|
|
|
209
251
|
return { docs, pages };
|
|
210
252
|
};
|
|
211
253
|
|
|
212
|
-
const generatePages = (
|
|
254
|
+
const generatePages = (
|
|
255
|
+
options: DocsOptions,
|
|
256
|
+
basePath: string,
|
|
257
|
+
linkStyle: DocsLinkStyle,
|
|
258
|
+
library: Library,
|
|
259
|
+
): GeneratedDocs => {
|
|
213
260
|
const intrinsicElements = collectIntrinsicElementClasses(library);
|
|
214
261
|
const byNamespace = groupElementsByNamespace(intrinsicElements);
|
|
215
|
-
const linkByGlibName = buildElementLinks(intrinsicElements, basePath);
|
|
262
|
+
const linkByGlibName = buildElementLinks(intrinsicElements, basePath, linkStyle);
|
|
216
263
|
const pageContext: ElementPageContext = { library, linkFor: (glibName) => linkByGlibName.get(glibName) };
|
|
217
264
|
const pages: Page[] = [];
|
|
218
265
|
const namespaces: DocsNamespace[] = [];
|
|
@@ -220,12 +267,12 @@ const generatePages = (options: DocsOptions, basePath: string, library: Library)
|
|
|
220
267
|
|
|
221
268
|
for (const name of orderedNames) {
|
|
222
269
|
const elements = sortStringsBy(byNamespace.get(name) ?? [], (entry) => entry.glibName);
|
|
223
|
-
const result = namespacePages({ name, elements, basePath, linkByGlibName, pageContext });
|
|
270
|
+
const result = namespacePages({ name, elements, basePath, linkStyle, linkByGlibName, pageContext });
|
|
224
271
|
pages.push(...result.pages);
|
|
225
272
|
namespaces.push(result.docs);
|
|
226
273
|
}
|
|
227
274
|
|
|
228
|
-
pages.push({ path: ROOT_INDEX_FILENAME, content: rootIndexPage(namespaces, options.libraries) });
|
|
275
|
+
pages.push({ path: ROOT_INDEX_FILENAME, content: rootIndexPage(namespaces, options.libraries, linkStyle) });
|
|
229
276
|
|
|
230
277
|
return { pages, namespaces };
|
|
231
278
|
};
|
|
@@ -267,6 +314,7 @@ const giInputs = (options: DocsOptions, girFiles: string[]): GiInputs => ({
|
|
|
267
314
|
isValueUnwrapped: options.isValueUnwrapped === true,
|
|
268
315
|
isFinishTrimmed: options.isFinishTrimmed === true,
|
|
269
316
|
isInoutInPlace: options.isInoutInPlace === true,
|
|
317
|
+
isTreeShaken: options.isTreeShaken === true,
|
|
270
318
|
});
|
|
271
319
|
|
|
272
320
|
const assertOwnedOutDir = (options: DocsOptions, manifest: DocsManifest | undefined): void => {
|
|
@@ -334,11 +382,13 @@ const writePages = (outDir: string, pages: Page[]): void => {
|
|
|
334
382
|
|
|
335
383
|
const docsFingerprintInput = (options: DocsOptions): DocsFingerprintInput => ({
|
|
336
384
|
basePath: options.basePath ?? DEFAULT_BASE_PATH,
|
|
385
|
+
linkStyle: options.linkStyle ?? "url",
|
|
337
386
|
props: options.props ?? {},
|
|
338
387
|
omittedProps: options.omittedProps ?? {},
|
|
339
388
|
});
|
|
340
389
|
|
|
341
390
|
const writeDocs = (options: DocsOptions): DocsResult => {
|
|
391
|
+
const linkStyle = options.linkStyle ?? "url";
|
|
342
392
|
const input = docsFingerprintInput(options);
|
|
343
393
|
setElementProps(input.props);
|
|
344
394
|
setOmittedProps(input.omittedProps);
|
|
@@ -357,9 +407,10 @@ const writeDocs = (options: DocsOptions): DocsResult => {
|
|
|
357
407
|
isValueUnwrapped: options.isValueUnwrapped === true,
|
|
358
408
|
isFinishTrimmed: options.isFinishTrimmed === true,
|
|
359
409
|
isInoutInPlace: options.isInoutInPlace === true,
|
|
410
|
+
isTreeShaken: options.isTreeShaken === true,
|
|
360
411
|
});
|
|
361
412
|
|
|
362
|
-
const { pages, namespaces } = generatePages(options, input.basePath, library);
|
|
413
|
+
const { pages, namespaces } = generatePages(options, input.basePath, linkStyle, library);
|
|
363
414
|
clearOutDir(options, previous);
|
|
364
415
|
mkdirSync(options.outDir, { recursive: true });
|
|
365
416
|
const manifest: DocsManifest = { generator: MANIFEST_GENERATOR, namespaces };
|