@gtkx/codegen 1.0.0 → 1.2.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 +12 -15
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +59 -38
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +25 -10
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +37 -9
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/inheritance.d.ts +4 -2
- package/dist/analysis/inheritance.d.ts.map +1 -1
- package/dist/analysis/inheritance.js +80 -38
- package/dist/analysis/inheritance.js.map +1 -1
- package/dist/analysis/interface-conflicts.d.ts +25 -0
- package/dist/analysis/interface-conflicts.d.ts.map +1 -0
- package/dist/analysis/interface-conflicts.js +139 -0
- package/dist/analysis/interface-conflicts.js.map +1 -0
- package/dist/analysis/param-capability.d.ts.map +1 -1
- package/dist/analysis/param-capability.js +3 -4
- package/dist/analysis/param-capability.js.map +1 -1
- package/dist/analysis/param-structure.js +2 -2
- package/dist/analysis/param-structure.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +3 -2
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +26 -26
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/analysis/type-key.d.ts +5 -0
- package/dist/analysis/type-key.d.ts.map +1 -0
- package/dist/analysis/type-key.js +9 -0
- package/dist/analysis/type-key.js.map +1 -0
- package/dist/analysis/type-shape.d.ts +3 -2
- package/dist/analysis/type-shape.d.ts.map +1 -1
- package/dist/analysis/type-shape.js +2 -1
- package/dist/analysis/type-shape.js.map +1 -1
- package/dist/compile.d.ts +14 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +125 -24
- 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 +11 -10
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/element-page.d.ts.map +1 -1
- package/dist/docs/element-page.js +5 -3
- package/dist/docs/element-page.js.map +1 -1
- package/dist/docs/pipeline.d.ts +1 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +93 -19
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/docs/render.d.ts +2 -1
- package/dist/docs/render.d.ts.map +1 -1
- package/dist/docs/render.js +5 -4
- package/dist/docs/render.js.map +1 -1
- package/dist/docs/symbol-page.d.ts.map +1 -1
- package/dist/docs/symbol-page.js +10 -9
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +20 -3
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +56 -37
- 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 +8 -2
- package/dist/gi.js.map +1 -1
- package/dist/gir/ancestry.d.ts +7 -1
- package/dist/gir/ancestry.d.ts.map +1 -1
- package/dist/gir/ancestry.js +9 -1
- package/dist/gir/ancestry.js.map +1 -1
- package/dist/gir/annotations.d.ts +1 -2
- package/dist/gir/annotations.d.ts.map +1 -1
- package/dist/gir/annotations.js +1 -1
- package/dist/gir/annotations.js.map +1 -1
- package/dist/gir/cursor-overrides.d.ts +8 -0
- package/dist/gir/cursor-overrides.d.ts.map +1 -0
- package/dist/gir/cursor-overrides.js +6 -0
- package/dist/gir/cursor-overrides.js.map +1 -0
- package/dist/gir/emittable.d.ts +7 -0
- package/dist/gir/emittable.d.ts.map +1 -0
- package/dist/gir/emittable.js +3 -0
- package/dist/gir/emittable.js.map +1 -0
- package/dist/gir/function.d.ts.map +1 -1
- package/dist/gir/function.js +28 -2
- package/dist/gir/function.js.map +1 -1
- package/dist/gir/gir-path.d.ts +1 -1
- package/dist/gir/gir-path.js +1 -1
- package/dist/gir/gir-path.js.map +1 -1
- package/dist/gir/library.d.ts +5 -1
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +9 -2
- package/dist/gir/library.js.map +1 -1
- package/dist/gir/namespace.d.ts +5 -1
- package/dist/gir/namespace.d.ts.map +1 -1
- package/dist/gir/namespace.js +4 -2
- package/dist/gir/namespace.js.map +1 -1
- package/dist/gir/parameter.d.ts +13 -1
- package/dist/gir/parameter.d.ts.map +1 -1
- package/dist/gir/parameter.js +1 -0
- package/dist/gir/parameter.js.map +1 -1
- package/dist/gir/parse.d.ts.map +1 -1
- package/dist/gir/parse.js +6 -6
- package/dist/gir/parse.js.map +1 -1
- package/dist/gir/primitives.js +1 -1
- package/dist/gir/primitives.js.map +1 -1
- package/dist/guards.d.ts +16 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +11 -0
- package/dist/guards.js.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/json.d.ts +3 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +11 -0
- package/dist/json.js.map +1 -0
- package/dist/khronos/args.d.ts.map +1 -1
- package/dist/khronos/args.js +8 -6
- package/dist/khronos/args.js.map +1 -1
- package/dist/khronos/modules.d.ts.map +1 -1
- package/dist/khronos/modules.js +22 -7
- package/dist/khronos/modules.js.map +1 -1
- package/dist/khronos/parse.d.ts.map +1 -1
- package/dist/khronos/parse.js +3 -4
- package/dist/khronos/parse.js.map +1 -1
- package/dist/khronos/pipeline.d.ts +1 -1
- package/dist/khronos/pipeline.d.ts.map +1 -1
- package/dist/khronos/pipeline.js.map +1 -1
- package/dist/khronos/plan.d.ts +1 -7
- package/dist/khronos/plan.d.ts.map +1 -1
- package/dist/khronos/plan.js +1 -1
- package/dist/khronos/plan.js.map +1 -1
- package/dist/khronos/render.d.ts.map +1 -1
- package/dist/khronos/render.js +8 -4
- package/dist/khronos/render.js.map +1 -1
- package/dist/runner.d.ts +7 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +21 -3
- package/dist/runner.js.map +1 -1
- package/dist/staging.d.ts +5 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +57 -0
- package/dist/staging.js.map +1 -0
- package/dist/store/compile-store.d.ts +0 -1
- package/dist/store/compile-store.d.ts.map +1 -1
- package/dist/store/compile-store.js +7 -32
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts +6 -3
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +40 -30
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/callback.d.ts.map +1 -1
- package/dist/store/gi/callback.js +9 -5
- package/dist/store/gi/callback.js.map +1 -1
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +104 -44
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/companion.d.ts.map +1 -1
- package/dist/store/gi/companion.js +6 -6
- package/dist/store/gi/companion.js.map +1 -1
- package/dist/store/gi/constant.d.ts.map +1 -1
- package/dist/store/gi/constant.js +11 -3
- package/dist/store/gi/constant.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/enum.d.ts.map +1 -1
- package/dist/store/gi/enum.js +29 -12
- package/dist/store/gi/enum.js.map +1 -1
- package/dist/store/gi/function.d.ts +1 -3
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +24 -18
- 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 +4 -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 +34 -19
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts +7 -6
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +13 -24
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/param-marshal.d.ts +3 -2
- package/dist/store/gi/param-marshal.d.ts.map +1 -1
- package/dist/store/gi/param-marshal.js +50 -5
- package/dist/store/gi/param-marshal.js.map +1 -1
- package/dist/store/gi/pipeline.d.ts.map +1 -1
- package/dist/store/gi/pipeline.js +21 -10
- package/dist/store/gi/pipeline.js.map +1 -1
- package/dist/store/gi/properties.d.ts +2 -1
- package/dist/store/gi/properties.d.ts.map +1 -1
- package/dist/store/gi/properties.js +6 -3
- package/dist/store/gi/properties.js.map +1 -1
- package/dist/store/gi/property-accessor.d.ts +10 -8
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +49 -91
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts +8 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +34 -13
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +20 -4
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record-layout.d.ts +6 -1
- package/dist/store/gi/record-layout.d.ts.map +1 -1
- package/dist/store/gi/record-layout.js +8 -1
- package/dist/store/gi/record-layout.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +19 -8
- 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 +2 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +55 -28
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/gi/value-marshalable.d.ts.map +1 -1
- package/dist/store/gi/value-marshalable.js +2 -1
- package/dist/store/gi/value-marshalable.js.map +1 -1
- package/dist/store/gi/vtable.d.ts +4 -1
- package/dist/store/gi/vtable.d.ts.map +1 -1
- package/dist/store/gi/vtable.js +60 -17
- 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 +15 -20
- package/dist/store/gi-store.js.map +1 -1
- package/dist/store/jsx/generated-elements.d.ts +2 -1
- package/dist/store/jsx/generated-elements.d.ts.map +1 -1
- package/dist/store/jsx/generated-elements.js +13 -7
- package/dist/store/jsx/generated-elements.js.map +1 -1
- package/dist/store/jsx/jsx.js +3 -3
- package/dist/store/jsx/jsx.js.map +1 -1
- package/dist/store/jsx/metadata.d.ts.map +1 -1
- package/dist/store/jsx/metadata.js +3 -1
- package/dist/store/jsx/metadata.js.map +1 -1
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +3 -4
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/resolve-store.d.ts +14 -3
- package/dist/store/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +98 -15
- package/dist/store/resolve-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +9 -7
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +54 -25
- package/dist/store/store-fs.js.map +1 -1
- package/dist/store/store-links.d.ts +3 -0
- package/dist/store/store-links.d.ts.map +1 -0
- package/dist/store/store-links.js +39 -0
- package/dist/store/store-links.js.map +1 -0
- package/dist/writer/comparison-context.d.ts +4 -0
- package/dist/writer/comparison-context.d.ts.map +1 -0
- package/dist/writer/comparison-context.js +13 -0
- package/dist/writer/comparison-context.js.map +1 -0
- package/dist/writer/context.d.ts +3 -3
- package/dist/writer/context.d.ts.map +1 -1
- package/dist/writer/context.js +11 -6
- package/dist/writer/context.js.map +1 -1
- package/dist/writer/module.d.ts +13 -5
- package/dist/writer/module.d.ts.map +1 -1
- package/dist/writer/module.js +68 -11
- package/dist/writer/module.js.map +1 -1
- package/dist/xml.d.ts +8 -1
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +70 -1
- package/dist/xml.js.map +1 -1
- package/overrides/gobject/object.ts.ejs +2 -0
- package/package.json +14 -3
- package/src/analysis/descriptor-render.ts +106 -52
- package/src/analysis/descriptor.ts +76 -15
- package/src/analysis/inheritance.ts +134 -44
- package/src/analysis/interface-conflicts.ts +235 -0
- package/src/analysis/param-capability.ts +3 -6
- package/src/analysis/param-structure.ts +2 -2
- package/src/analysis/ts-type.ts +43 -28
- package/src/analysis/type-key.ts +14 -0
- package/src/analysis/type-shape.ts +5 -2
- package/src/compile.ts +192 -27
- package/src/docs/api-reference.ts +13 -10
- package/src/docs/element-page.ts +5 -2
- package/src/docs/pipeline.ts +140 -24
- package/src/docs/render.ts +7 -3
- package/src/docs/symbol-page.ts +12 -11
- package/src/fingerprint.ts +95 -47
- package/src/gi.ts +10 -2
- package/src/gir/ancestry.ts +17 -1
- package/src/gir/annotations.ts +1 -1
- package/src/gir/cursor-overrides.ts +12 -0
- package/src/gir/emittable.ts +8 -0
- package/src/gir/function.ts +45 -9
- package/src/gir/gir-path.ts +1 -1
- package/src/gir/library.ts +10 -2
- package/src/gir/namespace.ts +8 -2
- package/src/gir/parameter.ts +15 -0
- package/src/gir/parse.ts +10 -7
- package/src/gir/primitives.ts +1 -1
- package/src/guards.ts +23 -0
- package/src/internal.ts +2 -0
- package/src/json.ts +11 -0
- package/src/khronos/args.ts +9 -6
- package/src/khronos/modules.ts +25 -9
- package/src/khronos/parse.ts +3 -4
- package/src/khronos/pipeline.ts +1 -1
- package/src/khronos/plan.ts +0 -1
- package/src/khronos/render.ts +8 -6
- package/src/runner.ts +26 -4
- package/src/staging.ts +67 -0
- package/src/store/compile-store.ts +7 -38
- package/src/store/gi/callables.ts +60 -33
- package/src/store/gi/callback.ts +9 -9
- package/src/store/gi/class.ts +140 -53
- package/src/store/gi/companion.ts +7 -6
- package/src/store/gi/constant.ts +13 -3
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/enum.ts +36 -26
- package/src/store/gi/function.ts +30 -24
- package/src/store/gi/gtype-binding.ts +7 -2
- package/src/store/gi/interface.ts +39 -20
- package/src/store/gi/method.ts +26 -32
- package/src/store/gi/param-marshal.ts +77 -6
- package/src/store/gi/pipeline.ts +25 -15
- package/src/store/gi/properties.ts +8 -4
- package/src/store/gi/property-accessor.ts +73 -161
- package/src/store/gi/record-constructor.ts +53 -21
- package/src/store/gi/record-field-accessor.ts +26 -4
- package/src/store/gi/record-layout.ts +11 -1
- package/src/store/gi/record.ts +20 -12
- package/src/store/gi/registration.ts +2 -2
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +66 -42
- package/src/store/gi/value-marshalable.ts +3 -1
- package/src/store/gi/vtable.ts +97 -20
- package/src/store/gi-store.ts +26 -31
- package/src/store/jsx/generated-elements.ts +17 -8
- package/src/store/jsx/jsx.ts +3 -3
- package/src/store/jsx/metadata.ts +4 -1
- package/src/store/jsx-store.ts +3 -4
- package/src/store/resolve-store.ts +133 -18
- package/src/store/store-fs.ts +82 -35
- package/src/store/store-links.ts +49 -0
- package/src/writer/comparison-context.ts +18 -0
- package/src/writer/context.ts +12 -6
- package/src/writer/module.ts +101 -14
- package/src/xml.ts +103 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
1
|
import { join } from "node:path";
|
|
3
2
|
import type { GlibNamedClass } from "./intrinsic-elements.js";
|
|
4
3
|
import { namespaceDirectory } from "../../gir/namespace.js";
|
|
4
|
+
import { arrayGuard, hasFields, isBoolean, isString } from "../../guards.js";
|
|
5
|
+
import { readJsonFile } from "../../json.js";
|
|
5
6
|
|
|
6
7
|
/** One element the `@gtkx/jsx` store binds. */
|
|
7
8
|
type GeneratedElement = {
|
|
@@ -33,22 +34,30 @@ const collectGeneratedElements = (intrinsicElements: GlibNamedClass[]): Generate
|
|
|
33
34
|
const renderGeneratedElements = (elements: GeneratedElement[]): string =>
|
|
34
35
|
`${JSON.stringify(elements, null, 2)}\n`;
|
|
35
36
|
|
|
37
|
+
const isGeneratedElement = (value: unknown): value is GeneratedElement =>
|
|
38
|
+
hasFields<GeneratedElement>(value, {
|
|
39
|
+
namespace: isString,
|
|
40
|
+
directory: isString,
|
|
41
|
+
glibName: isString,
|
|
42
|
+
isMountable: isBoolean,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const isGeneratedInventory = (value: unknown): value is GeneratedElement[] =>
|
|
46
|
+
arrayGuard(isGeneratedElement)(value);
|
|
47
|
+
|
|
36
48
|
/**
|
|
37
49
|
* Reads the inventory of elements the `@gtkx/jsx` store binds, written into the store by codegen. Answers
|
|
38
50
|
* "what does this project's JSX layer cover" without loading the store, which resolves `virtual:` specifiers
|
|
39
51
|
* that only exist inside a Vite or Vitest build.
|
|
40
52
|
*
|
|
41
53
|
* @param jsxStoreDir The jsx store directory, as given by `resolveStore(projectRoot).jsx.storeDir`.
|
|
42
|
-
* @returns Every bound element, sorted by GLib type name, or an empty array when the store
|
|
54
|
+
* @returns Every bound element, sorted by GLib type name, or an empty array when the store holds no inventory
|
|
55
|
+
* codegen wrote, which covers an absent, unreadable, unparseable and structurally foreign store file alike.
|
|
43
56
|
*/
|
|
44
57
|
const readGeneratedElements = (jsxStoreDir: string): GeneratedElement[] => {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
if (!existsSync(path)) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
58
|
+
const parsed = readJsonFile(join(jsxStoreDir, ELEMENTS_FILENAME));
|
|
50
59
|
|
|
51
|
-
return
|
|
60
|
+
return isGeneratedInventory(parsed) ? parsed : [];
|
|
52
61
|
};
|
|
53
62
|
|
|
54
63
|
export {
|
package/src/store/jsx/jsx.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sourceStringLiteral } from "@gtkx/utils";
|
|
1
|
+
import { sanitizeTypeIdentifier, sourceStringLiteral } from "@gtkx/utils";
|
|
2
2
|
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";
|
|
@@ -285,7 +285,7 @@ const renderInterfacePropsBlock = (
|
|
|
285
285
|
|
|
286
286
|
const extendsClause = prerequisiteExtends.length === 0 ? "" : ` extends ${prerequisiteExtends.join(", ")}`;
|
|
287
287
|
addGiNamespace(imports, iface.namespace.name, giNamespaceAlias(iface.namespace.name));
|
|
288
|
-
const selfDefault = `${giNamespaceAlias(iface.namespace.name)}.${iface.klass.name}`;
|
|
288
|
+
const selfDefault = `${giNamespaceAlias(iface.namespace.name)}.${sanitizeTypeIdentifier(iface.klass.name)}`;
|
|
289
289
|
const signature = `export interface ${glib}Props<Self = ${selfDefault}>${extendsClause}`;
|
|
290
290
|
const block = `${getDoc(iface.klass)}${renderBlock(signature, ownerLines.join("\n"))}`;
|
|
291
291
|
|
|
@@ -324,7 +324,7 @@ const renderPropBlock = (
|
|
|
324
324
|
const ownerLines = dedupePropLines(["ref?: Ref<Self | null> | undefined;", ...propLines]);
|
|
325
325
|
const extendsList = resolveElementExtends(library, entry, context);
|
|
326
326
|
const extendsClause = extendsList.length === 0 ? "" : ` extends ${extendsList.join(", ")}`;
|
|
327
|
-
const selfDefault = `${giNamespaceAlias(entry.namespace.name)}.${entry.klass.name}`;
|
|
327
|
+
const selfDefault = `${giNamespaceAlias(entry.namespace.name)}.${sanitizeTypeIdentifier(entry.klass.name)}`;
|
|
328
328
|
|
|
329
329
|
const block = `${getDoc(entry.klass)}${renderBlock(
|
|
330
330
|
`export interface ${entry.glibName}Props<Self = ${selfDefault}>${extendsClause}`,
|
|
@@ -66,12 +66,15 @@ const generateMetadata = (library: Library): string => {
|
|
|
66
66
|
|
|
67
67
|
const collectIntrinsicElements = (library: Library): IntrinsicElementEntry[] => {
|
|
68
68
|
const entries: IntrinsicElementEntry[] = [];
|
|
69
|
+
const seen: Set<string> = new Set();
|
|
69
70
|
|
|
70
71
|
for (const { glibName, klass, namespace } of iterateClassesWithGlibName(library)) {
|
|
71
|
-
if (!isIntrinsicElementClass(klass, namespace, library)) {
|
|
72
|
+
if (!isIntrinsicElementClass(klass, namespace, library) || seen.has(glibName)) {
|
|
72
73
|
continue;
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
seen.add(glibName);
|
|
77
|
+
|
|
75
78
|
const sources: GirClass[] = [
|
|
76
79
|
klass,
|
|
77
80
|
...implementedInterfaces(klass, namespace, library).map((entry) => entry.klass),
|
package/src/store/jsx-store.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JsxNamespaceFile } from "./jsx/pipeline.js";
|
|
2
2
|
import type { RawFile } from "./store-fs.js";
|
|
3
|
-
import { buildManifest, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
3
|
+
import { buildManifest, namespaceBarrel, type StoreOptions, subpathExport, writeStore } from "./store-fs.js";
|
|
4
4
|
|
|
5
5
|
const writeJsxStore = (
|
|
6
6
|
options: StoreOptions,
|
|
@@ -15,8 +15,8 @@ const writeJsxStore = (
|
|
|
15
15
|
const files = [{ fileName: "metadata.ts", source: metadata }];
|
|
16
16
|
|
|
17
17
|
for (const { directory, source } of namespaces) {
|
|
18
|
-
files.push({ fileName: `${directory}/${directory}.tsx`, source });
|
|
19
|
-
exportsMap[`./${directory}`] = subpathExport(`${directory}
|
|
18
|
+
files.push({ fileName: `${directory}/${directory}.tsx`, source }, namespaceBarrel(directory));
|
|
19
|
+
exportsMap[`./${directory}`] = subpathExport(`${directory}/index`);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
writeStore({
|
|
@@ -30,7 +30,6 @@ const writeJsxStore = (
|
|
|
30
30
|
peerDependencies: { "@gtkx/gi": "*", "@gtkx/react": "*", react: "*" },
|
|
31
31
|
}),
|
|
32
32
|
rawFiles,
|
|
33
|
-
requiresEnvReference: true,
|
|
34
33
|
});
|
|
35
34
|
};
|
|
36
35
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
2
|
-
import { dirname, join, parse } from "node:path";
|
|
2
|
+
import { dirname, join, parse, relative, sep } from "node:path";
|
|
3
3
|
import type { StoreOptions } from "./store-fs.js";
|
|
4
|
+
import { sweepStagingDirs } from "../staging.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Where a project's generated stores live, ready to spread into `runCodegen`. `jsx` is null when the
|
|
@@ -15,10 +16,20 @@ type ResolvedStore = {
|
|
|
15
16
|
reactSubexports: string[];
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
type ResolvedPackage = { dir: string; version: string };
|
|
19
|
+
type ResolvedPackage = { dir: string; nodeModules: string; version: string };
|
|
20
|
+
type StoreConsumer = { name: string; nodeModules: string };
|
|
19
21
|
|
|
20
22
|
const STORE_DIR = ".gtkx";
|
|
21
23
|
const SCOPE = "@gtkx";
|
|
24
|
+
const STORE_NAMES: string[] = ["gi", "jsx"];
|
|
25
|
+
|
|
26
|
+
const STORE_CONSUMERS: string[] = [
|
|
27
|
+
"@gtkx/cli",
|
|
28
|
+
"@gtkx/components",
|
|
29
|
+
"@gtkx/css",
|
|
30
|
+
"@gtkx/react",
|
|
31
|
+
"@gtkx/testing",
|
|
32
|
+
];
|
|
22
33
|
|
|
23
34
|
const readManifest = (path: string): { version?: string; exports?: Record<string, unknown> } =>
|
|
24
35
|
JSON.parse(readFileSync(path, "utf8")) as { version?: string; exports?: Record<string, unknown> };
|
|
@@ -28,14 +39,14 @@ const subexportNames = (packageDir: string): string[] =>
|
|
|
28
39
|
.filter((key) => key.startsWith("./") && key !== "./package.json")
|
|
29
40
|
.map((key) => key.slice(2));
|
|
30
41
|
|
|
31
|
-
const loadPackage = (manifest: string): ResolvedPackage | null => {
|
|
42
|
+
const loadPackage = (manifest: string, nodeModules: string): ResolvedPackage | null => {
|
|
32
43
|
if (!existsSync(manifest)) {
|
|
33
44
|
return null;
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
const real = realpathSync(manifest);
|
|
37
48
|
|
|
38
|
-
return { dir: dirname(real), version: readManifest(real).version ?? "0.0.0" };
|
|
49
|
+
return { dir: dirname(real), nodeModules, version: readManifest(real).version ?? "0.0.0" };
|
|
39
50
|
};
|
|
40
51
|
|
|
41
52
|
const nodeModulesChain = function* (projectRoot: string): Generator<string> {
|
|
@@ -52,49 +63,153 @@ const nodeModulesChain = function* (projectRoot: string): Generator<string> {
|
|
|
52
63
|
|
|
53
64
|
const resolvePackage = (projectRoot: string, packageName: string): ResolvedPackage | null => {
|
|
54
65
|
for (const nodeModules of nodeModulesChain(projectRoot)) {
|
|
55
|
-
const found = loadPackage(join(nodeModules, packageName, "package.json"));
|
|
66
|
+
const found = loadPackage(join(nodeModules, packageName, "package.json"), nodeModules);
|
|
56
67
|
|
|
57
68
|
if (found !== null) {
|
|
58
69
|
return found;
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
72
|
|
|
62
|
-
|
|
73
|
+
const unscoped = packageName.replace(/^@[^/]+\//, "");
|
|
74
|
+
|
|
75
|
+
return loadPackage(join(projectRoot, "packages", unscoped, "package.json"), join(projectRoot, "node_modules"));
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const isWithin = (parent: string, child: string): boolean => {
|
|
79
|
+
const path = relative(parent, child);
|
|
80
|
+
|
|
81
|
+
return path === "" || (path !== ".." && !path.startsWith(`..${sep}`));
|
|
63
82
|
};
|
|
64
83
|
|
|
84
|
+
const canImport = (fromNodeModules: string, targetNodeModules: string): boolean =>
|
|
85
|
+
isWithin(dirname(targetNodeModules), dirname(fromNodeModules));
|
|
86
|
+
|
|
65
87
|
const storeOptions = (nodeModules: string, name: string, version: string): StoreOptions => ({
|
|
66
88
|
storeDir: join(nodeModules, STORE_DIR, name),
|
|
67
89
|
linkDir: join(nodeModules, SCOPE, name),
|
|
68
90
|
version,
|
|
69
91
|
});
|
|
70
92
|
|
|
93
|
+
const resolveRuntime = (projectRoot: string): ResolvedPackage => {
|
|
94
|
+
const runtime = resolvePackage(projectRoot, "@gtkx/runtime");
|
|
95
|
+
|
|
96
|
+
if (runtime === null) {
|
|
97
|
+
throw new Error(`Cannot resolve @gtkx/runtime from ${projectRoot}; is it installed?`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return runtime;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const storeNodeModules = (runtime: ResolvedPackage, react: ResolvedPackage | null): string => {
|
|
104
|
+
if (react !== null && canImport(react.nodeModules, runtime.nodeModules)) {
|
|
105
|
+
return react.nodeModules;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return runtime.nodeModules;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const findUnreachableConsumer = (projectRoot: string, nodeModules: string): StoreConsumer | null => {
|
|
112
|
+
for (const name of STORE_CONSUMERS) {
|
|
113
|
+
const consumer = resolvePackage(projectRoot, name);
|
|
114
|
+
|
|
115
|
+
if (consumer !== null && !canImport(consumer.nodeModules, nodeModules)) {
|
|
116
|
+
return { name, nodeModules: consumer.nodeModules };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const unreachableConsumerMessage = (consumer: StoreConsumer, nodeModules: string): string =>
|
|
124
|
+
`Cannot write the generated store to ${nodeModules}: ${consumer.name} is installed in ` +
|
|
125
|
+
`${consumer.nodeModules}, above it, so that copy can never import the generated @gtkx/gi. Install every ` +
|
|
126
|
+
"@gtkx package in one node_modules, then run gtkx codegen again.";
|
|
127
|
+
|
|
128
|
+
const checkConsumers = (projectRoot: string, nodeModules: string): void => {
|
|
129
|
+
const consumer = findUnreachableConsumer(projectRoot, nodeModules);
|
|
130
|
+
|
|
131
|
+
if (consumer !== null) {
|
|
132
|
+
throw new Error(unreachableConsumerMessage(consumer, nodeModules));
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const jsxOptions = (react: ResolvedPackage | null, nodeModules: string): StoreOptions | null =>
|
|
137
|
+
react === null ? null : storeOptions(nodeModules, "jsx", react.version);
|
|
138
|
+
|
|
139
|
+
const getReactSubexports = (react: ResolvedPackage | null): string[] =>
|
|
140
|
+
react === null ? [] : subexportNames(react.dir);
|
|
141
|
+
|
|
142
|
+
const storePaths = (nodeModules: string): string[] =>
|
|
143
|
+
STORE_NAMES.flatMap((name) => [join(nodeModules, STORE_DIR, name), join(nodeModules, SCOPE, name)]);
|
|
144
|
+
|
|
145
|
+
const findStoreNodeModules = (projectRoot: string): string | null => {
|
|
146
|
+
const runtime = resolvePackage(projectRoot, "@gtkx/runtime");
|
|
147
|
+
|
|
148
|
+
if (runtime === null) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return storeNodeModules(runtime, resolvePackage(projectRoot, "@gtkx/react"));
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const getShadowingStorePaths = (projectRoot: string): string[] => {
|
|
156
|
+
const nodeModules = join(projectRoot, "node_modules");
|
|
157
|
+
const anchored = findStoreNodeModules(projectRoot);
|
|
158
|
+
|
|
159
|
+
if (anchored === null || anchored === nodeModules) {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return storePaths(nodeModules);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const stagingRoots = (projectRoot: string): string[] => {
|
|
167
|
+
const nodeModules = join(projectRoot, "node_modules");
|
|
168
|
+
const anchored = findStoreNodeModules(projectRoot);
|
|
169
|
+
|
|
170
|
+
return anchored === null || anchored === nodeModules ? [nodeModules] : [nodeModules, anchored];
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const sweepProjectStaging = (projectRoot: string): void => {
|
|
174
|
+
for (const nodeModules of stagingRoots(projectRoot)) {
|
|
175
|
+
for (const name of STORE_NAMES) {
|
|
176
|
+
sweepStagingDirs(join(nodeModules, STORE_DIR, name));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
71
181
|
/**
|
|
72
182
|
* Resolves where a project's `@gtkx/gi` and `@gtkx/jsx` stores belong, from the project root alone. The
|
|
73
183
|
* result supplies every `runCodegen` input except `libraries` and `girPath`, so a caller that has
|
|
74
184
|
* already resolved those can spread it straight into the call.
|
|
75
185
|
*
|
|
186
|
+
* Both stores go in one `node_modules`, found by walking the project's `node_modules` chain upwards:
|
|
187
|
+
* the one `@gtkx/react` resolves from, or `@gtkx/runtime`'s when no React is installed. That is the
|
|
188
|
+
* project's own directory when it installs those packages itself, and the workspace root when npm or
|
|
189
|
+
* yarn hoisted them there. Keeping the pair together is what lets the jsx store import the gi store, and
|
|
190
|
+
* anchoring them where the `@gtkx` packages sit is what lets `@gtkx/react`, the CLI, and the project's
|
|
191
|
+
* sources all reach the bindings. A package manager that hoists therefore gives every project sharing
|
|
192
|
+
* that `node_modules` one shared store.
|
|
193
|
+
*
|
|
76
194
|
* Store versions come from the installed `@gtkx/runtime` and `@gtkx/react`, so a dependency upgrade
|
|
77
195
|
* invalidates the stores. Pass explicit `gi` or `jsx` options to `runCodegen` to override any of it.
|
|
78
196
|
*
|
|
79
|
-
* @param projectRoot Directory holding the project's `package.json
|
|
197
|
+
* @param projectRoot Directory holding the project's `package.json`, whose `node_modules` chain is walked.
|
|
80
198
|
* @returns The store locations and the React subexports that shape the jsx store.
|
|
81
|
-
* @throws If `@gtkx/runtime` cannot be resolved from the project
|
|
199
|
+
* @throws If `@gtkx/runtime` cannot be resolved from the project, or a `@gtkx` package that imports the
|
|
200
|
+
* bindings is installed above the `node_modules` the stores would go in, since it could not reach them.
|
|
82
201
|
*/
|
|
83
202
|
const resolveStore = (projectRoot: string): ResolvedStore => {
|
|
84
|
-
const runtime =
|
|
85
|
-
|
|
86
|
-
if (runtime === null) {
|
|
87
|
-
throw new Error(`Cannot resolve @gtkx/runtime from ${projectRoot}; is it installed?`);
|
|
88
|
-
}
|
|
89
|
-
|
|
203
|
+
const runtime = resolveRuntime(projectRoot);
|
|
90
204
|
const react = resolvePackage(projectRoot, "@gtkx/react");
|
|
91
|
-
const nodeModules =
|
|
205
|
+
const nodeModules = storeNodeModules(runtime, react);
|
|
206
|
+
checkConsumers(projectRoot, nodeModules);
|
|
92
207
|
|
|
93
208
|
return {
|
|
94
209
|
gi: storeOptions(nodeModules, "gi", runtime.version),
|
|
95
|
-
jsx: react
|
|
96
|
-
reactSubexports:
|
|
210
|
+
jsx: jsxOptions(react, nodeModules),
|
|
211
|
+
reactSubexports: getReactSubexports(react),
|
|
97
212
|
};
|
|
98
213
|
};
|
|
99
214
|
|
|
100
|
-
export { resolveStore, type ResolvedStore };
|
|
215
|
+
export { getShadowingStorePaths, resolveStore, sweepProjectStaging, type ResolvedStore };
|
package/src/store/store-fs.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { errorMessage } from "@gtkx/utils";
|
|
2
|
+
import {
|
|
3
|
+
chmodSync,
|
|
4
|
+
existsSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
realpathSync,
|
|
7
|
+
renameSync,
|
|
8
|
+
rmSync,
|
|
9
|
+
symlinkSync,
|
|
10
|
+
writeFileSync,
|
|
11
|
+
} from "node:fs";
|
|
2
12
|
import { dirname, join, relative } from "node:path";
|
|
13
|
+
import { keepFailedProject, type SourceModule } from "../compile.js";
|
|
14
|
+
import { createStagingDir } from "../staging.js";
|
|
3
15
|
import { compileStore } from "./compile-store.js";
|
|
4
16
|
|
|
5
17
|
/** Where one generated store is written and how it is reached. */
|
|
@@ -12,10 +24,7 @@ type StoreOptions = {
|
|
|
12
24
|
version: string;
|
|
13
25
|
};
|
|
14
26
|
|
|
15
|
-
type
|
|
16
|
-
fileName: string;
|
|
17
|
-
source: string;
|
|
18
|
-
};
|
|
27
|
+
type StoreLink = Pick<StoreOptions, "storeDir" | "linkDir">;
|
|
19
28
|
|
|
20
29
|
type Manifest = {
|
|
21
30
|
name: string;
|
|
@@ -38,19 +47,24 @@ type RawFile = { relativePath: string; content: string };
|
|
|
38
47
|
type WriteStoreParams = {
|
|
39
48
|
storeDir: string;
|
|
40
49
|
linkDir: string;
|
|
41
|
-
files:
|
|
50
|
+
files: SourceModule[];
|
|
42
51
|
manifest: Manifest;
|
|
43
52
|
rawFiles?: RawFile[];
|
|
44
|
-
requiresEnvReference?: boolean;
|
|
45
53
|
};
|
|
46
54
|
|
|
47
55
|
const STORE_DIR_MODE = 0o755;
|
|
56
|
+
const FAILED_STORE_SUFFIX = ".failed";
|
|
48
57
|
|
|
49
58
|
const subpathExport = (stem: string): { types: string; default: string } => ({
|
|
50
59
|
types: `./${stem}.d.ts`,
|
|
51
60
|
default: `./${stem}.js`,
|
|
52
61
|
});
|
|
53
62
|
|
|
63
|
+
const namespaceBarrel = (directory: string): { fileName: string; source: string } => ({
|
|
64
|
+
fileName: `${directory}/index.ts`,
|
|
65
|
+
source: `export * from "./${directory}.js";\n`,
|
|
66
|
+
});
|
|
67
|
+
|
|
54
68
|
const buildManifest = (input: ManifestInput): Manifest => {
|
|
55
69
|
const manifest: Manifest = {
|
|
56
70
|
name: input.name,
|
|
@@ -69,29 +83,31 @@ const buildManifest = (input: ManifestInput): Manifest => {
|
|
|
69
83
|
|
|
70
84
|
const writeStore = (params: WriteStoreParams): void => {
|
|
71
85
|
const tmp = createTempStore(params.storeDir);
|
|
86
|
+
const keepAt = `${params.storeDir}${FAILED_STORE_SUFFIX}`;
|
|
72
87
|
|
|
73
88
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
buildTempStore(tmp, params);
|
|
90
|
+
swapStore(tmp, params.storeDir);
|
|
91
|
+
ensureStoreLink(params);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
throw keepFailedProject({ projectDir: tmp, keepAt, error });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
rmSync(keepAt, { recursive: true, force: true });
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const buildTempStore = (tmp: string, params: WriteStoreParams): void => {
|
|
100
|
+
writePackageJson(tmp, params.manifest);
|
|
101
|
+
|
|
102
|
+
for (const file of params.files) {
|
|
103
|
+
writeSourceFile(tmp, file.fileName, file.source);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
compileStore({ storeDir: tmp, files: params.files, packageName: params.manifest.name });
|
|
107
|
+
const rawFiles = params.rawFiles ?? [];
|
|
108
|
+
|
|
109
|
+
for (const raw of rawFiles) {
|
|
110
|
+
writeFileSync(join(tmp, raw.relativePath), raw.content);
|
|
95
111
|
}
|
|
96
112
|
};
|
|
97
113
|
|
|
@@ -111,7 +127,7 @@ const writePackageJson = (storeDir: string, manifest: Manifest): void => {
|
|
|
111
127
|
writeFileSync(join(storeDir, "package.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
112
128
|
};
|
|
113
129
|
|
|
114
|
-
const swapStore = (tmp: string, storeDir: string
|
|
130
|
+
const swapStore = (tmp: string, storeDir: string): void => {
|
|
115
131
|
const previous = `${storeDir}.old`;
|
|
116
132
|
rmSync(previous, { recursive: true, force: true });
|
|
117
133
|
|
|
@@ -121,15 +137,46 @@ const swapStore = (tmp: string, storeDir: string, visibleLink: string): void =>
|
|
|
121
137
|
|
|
122
138
|
renameSync(tmp, storeDir);
|
|
123
139
|
rmSync(previous, { recursive: true, force: true });
|
|
124
|
-
symlinkRelative(visibleLink, storeDir);
|
|
125
140
|
};
|
|
126
141
|
|
|
142
|
+
const isStoreLinked = (link: StoreLink): boolean => {
|
|
143
|
+
try {
|
|
144
|
+
return realpathSync(link.linkDir) === realpathSync(link.storeDir);
|
|
145
|
+
} catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const ensureStoreLink = (link: StoreLink): void => {
|
|
151
|
+
if (!existsSync(join(link.storeDir, "package.json")) || isStoreLinked(link)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
symlinkRelative(link.linkDir, link.storeDir);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const storeWriteMessage = (storeDir: string, error: unknown): string =>
|
|
159
|
+
`Cannot write the generated store to ${storeDir}: ${errorMessage(error)}. ` +
|
|
160
|
+
"Codegen writes the store into the node_modules the @gtkx packages resolve from, " +
|
|
161
|
+
`so ${dirname(storeDir)} has to be writable.`;
|
|
162
|
+
|
|
127
163
|
const createTempStore = (storeDir: string): string => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
164
|
+
try {
|
|
165
|
+
const tmp = createStagingDir(storeDir);
|
|
166
|
+
chmodSync(tmp, STORE_DIR_MODE);
|
|
131
167
|
|
|
132
|
-
|
|
168
|
+
return tmp;
|
|
169
|
+
} catch (error) {
|
|
170
|
+
throw new Error(storeWriteMessage(storeDir, error), { cause: error });
|
|
171
|
+
}
|
|
133
172
|
};
|
|
134
173
|
|
|
135
|
-
export {
|
|
174
|
+
export {
|
|
175
|
+
subpathExport,
|
|
176
|
+
buildManifest,
|
|
177
|
+
ensureStoreLink,
|
|
178
|
+
namespaceBarrel,
|
|
179
|
+
writeStore,
|
|
180
|
+
type StoreOptions,
|
|
181
|
+
type RawFile,
|
|
182
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { type ResolvedStore, resolveStore } from "./resolve-store.js";
|
|
4
|
+
import { ensureStoreLink } from "./store-fs.js";
|
|
5
|
+
|
|
6
|
+
const resolvedStores: Map<string, ResolvedStore> = new Map();
|
|
7
|
+
|
|
8
|
+
const resolveStoreOrNull = (projectRoot: string): ResolvedStore | null => {
|
|
9
|
+
try {
|
|
10
|
+
return resolveStore(projectRoot);
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const isStoreDirPresent = (store: ResolvedStore): boolean => existsSync(join(store.gi.storeDir, "package.json"));
|
|
17
|
+
|
|
18
|
+
const storeFor = (projectRoot: string): ResolvedStore | null => {
|
|
19
|
+
const cached = resolvedStores.get(projectRoot);
|
|
20
|
+
|
|
21
|
+
if (cached !== undefined && isStoreDirPresent(cached)) {
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const resolved = resolveStoreOrNull(projectRoot);
|
|
26
|
+
resolvedStores.delete(projectRoot);
|
|
27
|
+
|
|
28
|
+
if (resolved !== null) {
|
|
29
|
+
resolvedStores.set(projectRoot, resolved);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return resolved;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const ensureStoreLinks = (projectRoot: string): void => {
|
|
36
|
+
const store = storeFor(projectRoot);
|
|
37
|
+
|
|
38
|
+
if (store === null) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const unit of [store.gi, store.jsx]) {
|
|
43
|
+
if (unit !== null) {
|
|
44
|
+
ensureStoreLink(unit);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { ensureStoreLinks };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ModuleContext } from "./context.js";
|
|
2
|
+
|
|
3
|
+
const COMPARISON_CONTEXTS: WeakMap<ModuleContext, ModuleContext> = new WeakMap();
|
|
4
|
+
|
|
5
|
+
const comparisonContextFor = (context: ModuleContext): ModuleContext => {
|
|
6
|
+
const existing = COMPARISON_CONTEXTS.get(context);
|
|
7
|
+
|
|
8
|
+
if (existing !== undefined) {
|
|
9
|
+
return existing;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const created = new ModuleContext(context.namespace, context.library);
|
|
13
|
+
COMPARISON_CONTEXTS.set(context, created);
|
|
14
|
+
|
|
15
|
+
return created;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { comparisonContextFor };
|
package/src/writer/context.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Library } from "../gir/library.js";
|
|
2
2
|
import type { GirNamespace } from "../gir/namespace.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type Declaration, ModuleBuilder } from "./module.js";
|
|
4
4
|
|
|
5
5
|
class ModuleContext {
|
|
6
6
|
public module: ModuleBuilder = new ModuleBuilder();
|
|
@@ -55,16 +55,22 @@ class ModuleContext {
|
|
|
55
55
|
return namespaceName;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
declare(declaration: Declaration): void {
|
|
59
|
+
const { name, code, owner } = declaration;
|
|
60
|
+
|
|
61
|
+
this.module.appendDeclaration({
|
|
62
|
+
name,
|
|
63
|
+
code,
|
|
64
|
+
owner: owner === undefined ? undefined : `${this.namespace.name}.${owner}`,
|
|
65
|
+
});
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
qualify(namespaceName: string,
|
|
68
|
+
qualify(namespaceName: string, name: string): string {
|
|
63
69
|
if (namespaceName === this.namespace.name) {
|
|
64
|
-
return
|
|
70
|
+
return name;
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
return `${this.addCrossNamespaceImport(namespaceName)}.${
|
|
73
|
+
return `${this.addCrossNamespaceImport(namespaceName)}.${name}`;
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
|