@gtkx/codegen 1.0.0 → 1.1.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 +48 -31
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +16 -7
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +15 -3
- 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 +23 -0
- package/dist/analysis/interface-conflicts.d.ts.map +1 -0
- package/dist/analysis/interface-conflicts.js +144 -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.map +1 -1
- package/dist/analysis/ts-type.js +10 -17
- 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/compile.d.ts +12 -3
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +73 -24
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +10 -9
- 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.map +1 -1
- package/dist/docs/pipeline.js +85 -18
- 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 +9 -6
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +12 -1
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +44 -28
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +1 -0
- 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/library.js +1 -1
- 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 +3 -6
- package/dist/gir/parse.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/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/runner.d.ts +5 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +16 -0
- 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.map +1 -1
- package/dist/store/compile-store.js +4 -2
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts +7 -2
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +25 -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 +59 -38
- 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 +10 -2
- 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 +28 -8
- 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 +32 -17
- 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 -21
- 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 -5
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +95 -44
- 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 +31 -10
- 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 +5 -1
- 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/signal.d.ts +2 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +30 -24
- 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 -3
- 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 -6
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +59 -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 +7 -1
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +43 -1
- package/dist/xml.js.map +1 -1
- package/package.json +14 -3
- package/src/analysis/descriptor-render.ts +90 -45
- package/src/analysis/descriptor.ts +35 -8
- package/src/analysis/inheritance.ts +134 -44
- package/src/analysis/interface-conflicts.ts +237 -0
- package/src/analysis/param-capability.ts +3 -6
- package/src/analysis/param-structure.ts +2 -2
- package/src/analysis/ts-type.ts +13 -17
- package/src/analysis/type-key.ts +14 -0
- package/src/compile.ts +110 -26
- package/src/docs/api-reference.ts +10 -9
- package/src/docs/element-page.ts +5 -2
- package/src/docs/pipeline.ts +129 -19
- package/src/docs/render.ts +7 -3
- package/src/docs/symbol-page.ts +12 -7
- package/src/fingerprint.ts +86 -31
- package/src/gi.ts +1 -0
- 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/library.ts +1 -1
- package/src/gir/namespace.ts +8 -2
- package/src/gir/parameter.ts +15 -0
- package/src/gir/parse.ts +5 -7
- package/src/guards.ts +23 -0
- package/src/internal.ts +2 -0
- package/src/json.ts +11 -0
- 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/runner.ts +19 -1
- package/src/staging.ts +69 -0
- package/src/store/compile-store.ts +6 -4
- package/src/store/gi/callables.ts +41 -33
- package/src/store/gi/callback.ts +9 -9
- package/src/store/gi/class.ts +79 -48
- package/src/store/gi/companion.ts +7 -6
- package/src/store/gi/constant.ts +12 -2
- package/src/store/gi/constructor-props.ts +1 -1
- package/src/store/gi/enum.ts +35 -21
- package/src/store/gi/function.ts +30 -24
- package/src/store/gi/gtype-binding.ts +7 -2
- package/src/store/gi/interface.ts +37 -18
- package/src/store/gi/method.ts +28 -29
- 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 +156 -73
- package/src/store/gi/record-constructor.ts +50 -18
- package/src/store/gi/record-field-accessor.ts +8 -1
- 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/signal.ts +36 -38
- 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 -3
- package/src/store/resolve-store.ts +133 -18
- package/src/store/store-fs.ts +87 -34
- 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 +61 -1
package/src/analysis/ts-type.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { sanitizeTypeIdentifier } from "@gtkx/utils";
|
|
1
2
|
import type { Library } from "../gir/library.js";
|
|
2
3
|
import type { EntityType, GirType } from "../gir/type.js";
|
|
3
4
|
import type { ModuleContext } from "../writer/context.js";
|
|
5
|
+
import { isEmittableEntity } from "../gir/emittable.js";
|
|
4
6
|
import { PRIMITIVE_TS_TYPE } from "../gir/primitives.js";
|
|
5
7
|
import {
|
|
6
8
|
type CArrayType,
|
|
@@ -24,21 +26,14 @@ type TsTypeTarget = {
|
|
|
24
26
|
renderGtype: () => string;
|
|
25
27
|
};
|
|
26
28
|
|
|
27
|
-
const willEmitEntity = (type: EntityType): boolean =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
case "alias":
|
|
36
|
-
case "class":
|
|
37
|
-
case "enum":
|
|
38
|
-
case "interface": {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
29
|
+
const willEmitEntity = (type: EntityType): boolean => isEmittableEntity(type.value);
|
|
30
|
+
|
|
31
|
+
const referenceName = (library: Library, ref: TypeId): ReferenceName | undefined => {
|
|
32
|
+
const name = library.nameFor(ref);
|
|
33
|
+
|
|
34
|
+
return name === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: { namespaceName: name.namespaceName, typeName: sanitizeTypeIdentifier(name.typeName) };
|
|
42
37
|
};
|
|
43
38
|
|
|
44
39
|
const renderPrimitiveType = (target: TsTypeTarget, type: Extract<GirType, { kind: "primitive" }>): string =>
|
|
@@ -56,12 +51,13 @@ const renderBaseType = (library: Library, target: TsTypeTarget, ref: TypeId | un
|
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
const type = library.typeFor(ref);
|
|
59
|
-
const name = library.nameFor(ref);
|
|
60
54
|
|
|
61
55
|
if (type === undefined) {
|
|
62
|
-
return renderNamedType(target, undefined,
|
|
56
|
+
return renderNamedType(target, undefined, undefined);
|
|
63
57
|
}
|
|
64
58
|
|
|
59
|
+
const name = referenceName(library, ref);
|
|
60
|
+
|
|
65
61
|
switch (type.kind) {
|
|
66
62
|
case "primitive": {
|
|
67
63
|
return renderPrimitiveType(target, type);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Library } from "../gir/library.js";
|
|
2
|
+
import type { TypeId } from "../gir/type-id.js";
|
|
3
|
+
|
|
4
|
+
const typeKey = (library: Library, ref: TypeId | undefined): string => {
|
|
5
|
+
if (ref === undefined) {
|
|
6
|
+
return "void";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const type = library.typeFor(ref);
|
|
10
|
+
|
|
11
|
+
return type?.kind === "primitive" && type.category === "void" ? "void" : `${String(ref.nsId)}.${String(ref.id)}`;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { typeKey };
|
package/src/compile.ts
CHANGED
|
@@ -1,20 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { errorMessage, normalizeError } from "@gtkx/utils";
|
|
2
|
+
import { existsSync, mkdirSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import ts from "typescript";
|
|
6
|
+
import { createStagingDir, sweepStrandedDirs } from "./staging.js";
|
|
5
7
|
|
|
6
|
-
type
|
|
8
|
+
type ProjectFile = {
|
|
7
9
|
fileName: string;
|
|
10
|
+
origin?: string | undefined;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type SourceModule = ProjectFile & {
|
|
8
14
|
source: string;
|
|
9
15
|
};
|
|
10
16
|
|
|
11
17
|
type CompileProjectParams = {
|
|
12
18
|
projectDir: string;
|
|
13
|
-
|
|
19
|
+
files: ProjectFile[];
|
|
14
20
|
compilerOptions: Record<string, unknown>;
|
|
15
21
|
label: string;
|
|
16
22
|
};
|
|
17
23
|
|
|
24
|
+
type DiagnosedFile = {
|
|
25
|
+
fileName: string;
|
|
26
|
+
text: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type FailedProjectInput = {
|
|
30
|
+
projectDir: string;
|
|
31
|
+
keepAt: string;
|
|
32
|
+
error: unknown;
|
|
33
|
+
};
|
|
34
|
+
|
|
18
35
|
const BASE_COMPILER_OPTIONS = {
|
|
19
36
|
module: "esnext",
|
|
20
37
|
moduleResolution: "bundler",
|
|
@@ -43,6 +60,10 @@ const CHECK_OPTIONS = {
|
|
|
43
60
|
noEmit: true,
|
|
44
61
|
};
|
|
45
62
|
|
|
63
|
+
const CHECK_DIR = ".gtkx-check";
|
|
64
|
+
const FAILED_CHECK_DIR = `${CHECK_DIR}.failed`;
|
|
65
|
+
const LEGACY_CHECK_PREFIX = `${CHECK_DIR}-`;
|
|
66
|
+
|
|
46
67
|
const FORMAT_HOST: ts.FormatDiagnosticsHost = {
|
|
47
68
|
getCanonicalFileName: (fileName) => fileName,
|
|
48
69
|
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
|
|
@@ -72,54 +93,107 @@ const linkToolingModules = (projectDir: string): (() => void) => {
|
|
|
72
93
|
const isProjectFile = (rel: string): boolean =>
|
|
73
94
|
!rel.startsWith("..") && !isAbsolute(rel) && !rel.split(/[/\\]/).includes("node_modules");
|
|
74
95
|
|
|
75
|
-
const
|
|
96
|
+
const projectDiagnosticFile = (diagnostic: ts.Diagnostic, projectDir: string): DiagnosedFile | undefined => {
|
|
76
97
|
const { file, start } = diagnostic;
|
|
77
98
|
|
|
78
99
|
if (file === undefined || start === undefined) {
|
|
79
100
|
return undefined;
|
|
80
101
|
}
|
|
81
102
|
|
|
82
|
-
const
|
|
103
|
+
const fileName = relative(projectDir, file.fileName);
|
|
83
104
|
|
|
84
|
-
if (!isProjectFile(
|
|
105
|
+
if (!isProjectFile(fileName)) {
|
|
85
106
|
return undefined;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
const { line, character } = file.getLineAndCharacterOfPosition(start);
|
|
89
110
|
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
90
111
|
|
|
91
|
-
return
|
|
112
|
+
return {
|
|
113
|
+
fileName,
|
|
114
|
+
text: `${fileName}:${String(line + 1)}:${String(character + 1)} - ${message} (TS${String(diagnostic.code)})`,
|
|
115
|
+
};
|
|
92
116
|
};
|
|
93
117
|
|
|
94
|
-
const
|
|
95
|
-
const
|
|
118
|
+
const projectDiagnosticFiles = (diagnostics: ts.Diagnostic[], projectDir: string): DiagnosedFile[] => {
|
|
119
|
+
const diagnosed: DiagnosedFile[] = [];
|
|
96
120
|
|
|
97
121
|
for (const diagnostic of diagnostics) {
|
|
98
|
-
const
|
|
122
|
+
const entry = projectDiagnosticFile(diagnostic, projectDir);
|
|
123
|
+
|
|
124
|
+
if (entry !== undefined) {
|
|
125
|
+
diagnosed.push(entry);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return diagnosed;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const collectOrigins = (files: ProjectFile[]): Map<string, string> => {
|
|
133
|
+
const origins: Map<string, string> = new Map();
|
|
134
|
+
|
|
135
|
+
for (const { fileName, origin } of files) {
|
|
136
|
+
if (origin !== undefined) {
|
|
137
|
+
origins.set(fileName, origin);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
99
140
|
|
|
100
|
-
|
|
101
|
-
|
|
141
|
+
return origins;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const groupByOrigin = (diagnosed: DiagnosedFile[], origins: Map<string, string>): Map<string, Set<string>> => {
|
|
145
|
+
const grouped: Map<string, Set<string>> = new Map();
|
|
146
|
+
|
|
147
|
+
for (const { fileName } of diagnosed) {
|
|
148
|
+
const origin = origins.get(fileName);
|
|
149
|
+
|
|
150
|
+
if (origin !== undefined) {
|
|
151
|
+
grouped.set(origin, (grouped.get(origin) ?? new Set<string>()).add(fileName));
|
|
102
152
|
}
|
|
103
153
|
}
|
|
104
154
|
|
|
105
|
-
return
|
|
155
|
+
return grouped;
|
|
106
156
|
};
|
|
107
157
|
|
|
108
|
-
const
|
|
109
|
-
|
|
158
|
+
const originLines = (diagnosed: DiagnosedFile[], files: ProjectFile[]): string[] =>
|
|
159
|
+
[...groupByOrigin(diagnosed, collectOrigins(files))].map(
|
|
160
|
+
([origin, generated]) => `Generated from ${origin}: ${[...generated].join(", ")}`,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const diagnosticError = (params: CompileProjectParams, diagnostics: ts.Diagnostic[]): Error => {
|
|
164
|
+
const diagnosed = projectDiagnosticFiles(diagnostics, params.projectDir);
|
|
165
|
+
const { label } = params;
|
|
110
166
|
|
|
111
|
-
if (
|
|
112
|
-
return new Error(`Type checking ${label}
|
|
167
|
+
if (diagnosed.length === 0) {
|
|
168
|
+
return new Error(`Type checking ${label} failed:\n${ts.formatDiagnostics(diagnostics, FORMAT_HOST).trim()}`);
|
|
113
169
|
}
|
|
114
170
|
|
|
115
|
-
|
|
171
|
+
const lines = [...diagnosed.map((entry) => entry.text), ...originLines(diagnosed, params.files)];
|
|
172
|
+
|
|
173
|
+
return new Error(`Type checking ${label} found ${String(diagnosed.length)} error(s):\n${lines.join("\n")}`);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const keepFailedProject = (input: FailedProjectInput): Error => {
|
|
177
|
+
const { projectDir, keepAt, error } = input;
|
|
178
|
+
|
|
179
|
+
if (!existsSync(projectDir)) {
|
|
180
|
+
return normalizeError(error);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
rmSync(keepAt, { recursive: true, force: true });
|
|
184
|
+
renameSync(projectDir, keepAt);
|
|
185
|
+
const rebased = errorMessage(error).split(projectDir).join(keepAt);
|
|
186
|
+
|
|
187
|
+
return new Error(`${rebased}\nThe generated sources are kept at ${keepAt}, where every path above resolves.`, {
|
|
188
|
+
cause: error,
|
|
189
|
+
});
|
|
116
190
|
};
|
|
117
191
|
|
|
118
192
|
const runProgram = (params: CompileProjectParams): ts.Diagnostic[] => {
|
|
119
193
|
const parsed = ts.parseJsonConfigFileContent(
|
|
120
194
|
{
|
|
121
195
|
compilerOptions: { ...BASE_COMPILER_OPTIONS, ...params.compilerOptions },
|
|
122
|
-
files: params.
|
|
196
|
+
files: params.files.map((file) => `./${file.fileName}`),
|
|
123
197
|
},
|
|
124
198
|
ts.sys,
|
|
125
199
|
params.projectDir,
|
|
@@ -147,17 +221,24 @@ const compileProject = (params: CompileProjectParams): void => {
|
|
|
147
221
|
const diagnostics = runProgram(params);
|
|
148
222
|
|
|
149
223
|
if (diagnostics.length > 0) {
|
|
150
|
-
throw diagnosticError(params
|
|
224
|
+
throw diagnosticError(params, diagnostics);
|
|
151
225
|
}
|
|
152
226
|
} finally {
|
|
153
227
|
unlinkToolingModules();
|
|
154
228
|
}
|
|
155
229
|
};
|
|
156
230
|
|
|
231
|
+
const stageCheckProject = (checkRoot: string): string => {
|
|
232
|
+
const projectDir = createStagingDir(join(checkRoot, CHECK_DIR));
|
|
233
|
+
sweepStrandedDirs(checkRoot, LEGACY_CHECK_PREFIX);
|
|
234
|
+
|
|
235
|
+
return projectDir;
|
|
236
|
+
};
|
|
237
|
+
|
|
157
238
|
const checkModules = (params: { modules: SourceModule[]; resolveFrom: string; label: string }): void => {
|
|
158
239
|
const checkRoot = join(params.resolveFrom, "node_modules");
|
|
159
|
-
|
|
160
|
-
const
|
|
240
|
+
const projectDir = stageCheckProject(checkRoot);
|
|
241
|
+
const keepAt = join(checkRoot, FAILED_CHECK_DIR);
|
|
161
242
|
|
|
162
243
|
try {
|
|
163
244
|
for (const module of params.modules) {
|
|
@@ -168,13 +249,16 @@ const checkModules = (params: { modules: SourceModule[]; resolveFrom: string; la
|
|
|
168
249
|
|
|
169
250
|
compileProject({
|
|
170
251
|
projectDir,
|
|
171
|
-
|
|
252
|
+
files: params.modules,
|
|
172
253
|
compilerOptions: CHECK_OPTIONS,
|
|
173
254
|
label: params.label,
|
|
174
255
|
});
|
|
175
|
-
}
|
|
176
|
-
|
|
256
|
+
} catch (error) {
|
|
257
|
+
throw keepFailedProject({ projectDir, keepAt, error });
|
|
177
258
|
}
|
|
259
|
+
|
|
260
|
+
rmSync(projectDir, { recursive: true, force: true });
|
|
261
|
+
rmSync(keepAt, { recursive: true, force: true });
|
|
178
262
|
};
|
|
179
263
|
|
|
180
|
-
export { compileProject, checkModules, type SourceModule };
|
|
264
|
+
export { compileProject, checkModules, keepFailedProject, type ProjectFile, type SourceModule };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sanitizeIdentifier, sanitizeTypeIdentifier, sortStrings, sortStringsBy } from "@gtkx/utils";
|
|
2
2
|
import type { GirClass } from "../gir/class.js";
|
|
3
3
|
import type { GirFunction } from "../gir/function.js";
|
|
4
4
|
import type { GirRecord } from "../gir/record.js";
|
|
5
|
+
import { isEmittableEntity } from "../gir/emittable.js";
|
|
5
6
|
import { Library } from "../gir/library.js";
|
|
6
7
|
import { type GirNamespace, namespaceDirectory } from "../gir/namespace.js";
|
|
7
8
|
import { dedupeCallables, isEmittableCallable } from "../store/gi/callables.js";
|
|
@@ -214,13 +215,13 @@ const functionEntry = (
|
|
|
214
215
|
};
|
|
215
216
|
|
|
216
217
|
const classEntry = (namespace: GirNamespace, klass: GirClass): GiSymbolEntry | undefined => {
|
|
217
|
-
if (!klass
|
|
218
|
+
if (!isEmittableEntity(klass)) {
|
|
218
219
|
return undefined;
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
const kind = klass.isInterface ? "interface" : "class";
|
|
222
223
|
|
|
223
|
-
return { kind, namespace, name:
|
|
224
|
+
return { kind, namespace, name: sanitizeTypeIdentifier(klass.name), doc: klass.doc, klass };
|
|
224
225
|
};
|
|
225
226
|
|
|
226
227
|
const classEntries = (namespace: GirNamespace): GiSymbolEntry[] => {
|
|
@@ -238,11 +239,11 @@ const classEntries = (namespace: GirNamespace): GiSymbolEntry[] => {
|
|
|
238
239
|
};
|
|
239
240
|
|
|
240
241
|
const recordEntry = (namespace: GirNamespace, record: GirRecord): GiSymbolEntry | undefined => {
|
|
241
|
-
if (
|
|
242
|
+
if (record.isVtable || !isEmittableEntity(record)) {
|
|
242
243
|
return undefined;
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
return { kind: "record", namespace, name: record.name, doc: record.doc, record };
|
|
246
|
+
return { kind: "record", namespace, name: sanitizeTypeIdentifier(record.name), doc: record.doc, record };
|
|
246
247
|
};
|
|
247
248
|
|
|
248
249
|
const recordEntries = (namespace: GirNamespace): GiSymbolEntry[] => {
|
|
@@ -265,7 +266,7 @@ const valueEntries = (namespace: GirNamespace): GiSymbolEntry[] => [
|
|
|
265
266
|
.map<GiSymbolEntry>((enumeration) => ({
|
|
266
267
|
kind: "enum",
|
|
267
268
|
namespace,
|
|
268
|
-
name: enumeration.name,
|
|
269
|
+
name: sanitizeTypeIdentifier(enumeration.name),
|
|
269
270
|
doc: enumeration.doc,
|
|
270
271
|
enumeration,
|
|
271
272
|
})),
|
|
@@ -274,21 +275,21 @@ const valueEntries = (namespace: GirNamespace): GiSymbolEntry[] => [
|
|
|
274
275
|
.map<GiSymbolEntry>((callback) => ({
|
|
275
276
|
kind: "callback",
|
|
276
277
|
namespace,
|
|
277
|
-
name: callback.name,
|
|
278
|
+
name: sanitizeTypeIdentifier(callback.name),
|
|
278
279
|
doc: callback.doc,
|
|
279
280
|
callback,
|
|
280
281
|
})),
|
|
281
282
|
...namespace.aliases.map<GiSymbolEntry>((alias) => ({
|
|
282
283
|
kind: "alias",
|
|
283
284
|
namespace,
|
|
284
|
-
name: alias.name,
|
|
285
|
+
name: sanitizeTypeIdentifier(alias.name),
|
|
285
286
|
doc: alias.doc,
|
|
286
287
|
alias,
|
|
287
288
|
})),
|
|
288
289
|
...namespace.constants.map<GiSymbolEntry>((constant) => ({
|
|
289
290
|
kind: "constant",
|
|
290
291
|
namespace,
|
|
291
|
-
name: constant.name,
|
|
292
|
+
name: sanitizeIdentifier(constant.name),
|
|
292
293
|
doc: constant.doc,
|
|
293
294
|
constant,
|
|
294
295
|
})),
|
package/src/docs/element-page.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
originSignatureBlocks,
|
|
30
30
|
type OriginSignatureEntry,
|
|
31
31
|
propertyMetaLine,
|
|
32
|
+
qualifiedClassName,
|
|
32
33
|
renderDocsSignalSignature,
|
|
33
34
|
renderDocsType,
|
|
34
35
|
signalTags,
|
|
@@ -76,7 +77,9 @@ const hierarchySection = (entry: GlibNamedClass, context: ElementPageContext): s
|
|
|
76
77
|
const parts = ancestors.map((ancestor) => {
|
|
77
78
|
const glib = getGlibName(ancestor.klass);
|
|
78
79
|
|
|
79
|
-
return glib === undefined
|
|
80
|
+
return glib === undefined
|
|
81
|
+
? `\`${qualifiedClassName(ancestor.namespaceName, ancestor.klass.name)}\``
|
|
82
|
+
: glibLabel(context, glib);
|
|
80
83
|
});
|
|
81
84
|
|
|
82
85
|
parts.push(`**${entry.glibName}**`);
|
|
@@ -265,7 +268,7 @@ const methodsSection = (entry: GlibNamedClass, context: ElementPageContext, self
|
|
|
265
268
|
};
|
|
266
269
|
|
|
267
270
|
const renderElementPage = (entry: GlibNamedClass, context: ElementPageContext): string => {
|
|
268
|
-
const selfType =
|
|
271
|
+
const selfType = qualifiedClassName(entry.namespace.name, entry.klass.name);
|
|
269
272
|
|
|
270
273
|
return joinSections([
|
|
271
274
|
frontmatter(entry),
|
package/src/docs/pipeline.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { sortStringsBy } from "@gtkx/utils";
|
|
2
|
-
import {
|
|
2
|
+
import { mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
computeDocsFingerprint,
|
|
6
|
+
type DocsFingerprintInput,
|
|
7
|
+
FINGERPRINT_FILENAME,
|
|
8
|
+
isDocsOutputFresh,
|
|
9
|
+
} from "../fingerprint.js";
|
|
5
10
|
import { Library } from "../gir/library.js";
|
|
6
11
|
import { namespaceDirectory } from "../gir/namespace.js";
|
|
12
|
+
import { arrayGuard, hasFields, isString } from "../guards.js";
|
|
13
|
+
import { readJsonFile } from "../json.js";
|
|
7
14
|
import { type ElementProps, setElementProps } from "../store/jsx/element-prop-imports.js";
|
|
8
15
|
import { collectIntrinsicElementClasses, type GlibNamedClass } from "../store/jsx/intrinsic-elements.js";
|
|
9
16
|
import { type OmittedProps, setOmittedProps } from "../store/jsx/omitted-props.js";
|
|
@@ -33,6 +40,7 @@ type DocsOptions = {
|
|
|
33
40
|
};
|
|
34
41
|
|
|
35
42
|
type DocsManifest = {
|
|
43
|
+
generator: string;
|
|
36
44
|
namespaces: DocsNamespace[];
|
|
37
45
|
};
|
|
38
46
|
|
|
@@ -50,6 +58,9 @@ type DocsResult = {
|
|
|
50
58
|
};
|
|
51
59
|
|
|
52
60
|
const MANIFEST_FILENAME = "manifest.json";
|
|
61
|
+
const MANIFEST_GENERATOR = "gtkx-docs";
|
|
62
|
+
const ROOT_INDEX_FILENAME = "index.md";
|
|
63
|
+
const DEFAULT_BASE_PATH = "/reference";
|
|
53
64
|
|
|
54
65
|
const namespaceIndexPage = (namespace: DocsNamespace, elements: GlibNamedClass[]): string => {
|
|
55
66
|
const rows = elements.map((entry, index) => {
|
|
@@ -144,6 +155,28 @@ const buildElementLinks = (elements: GlibNamedClass[], basePath: string): Map<st
|
|
|
144
155
|
return linkByGlibName;
|
|
145
156
|
};
|
|
146
157
|
|
|
158
|
+
const isEntryInsideOutDir = (value: string): boolean =>
|
|
159
|
+
value.length > 0 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\");
|
|
160
|
+
|
|
161
|
+
const isChildEntry = (value: unknown): value is string => isString(value) && isEntryInsideOutDir(value);
|
|
162
|
+
|
|
163
|
+
const ownedEntry = (entry: string, source: string): string => {
|
|
164
|
+
if (isEntryInsideOutDir(entry)) {
|
|
165
|
+
return entry;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
throw new Error(
|
|
169
|
+
`Refusing to generate documentation outside the output directory: ${source} maps to \`${entry}\`, ` +
|
|
170
|
+
"which is not an entry inside it. The GIR that declares it is malformed.",
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const elementPagePath = (directory: string, entry: GlibNamedClass): string => {
|
|
175
|
+
const slug = ownedEntry(elementSlug(entry.klass.name), `the element ${entry.glibName}`);
|
|
176
|
+
|
|
177
|
+
return `${directory}/${slug}.md`;
|
|
178
|
+
};
|
|
179
|
+
|
|
147
180
|
const namespacePages = (input: {
|
|
148
181
|
name: string;
|
|
149
182
|
elements: GlibNamedClass[];
|
|
@@ -152,7 +185,7 @@ const namespacePages = (input: {
|
|
|
152
185
|
pageContext: ElementPageContext;
|
|
153
186
|
}): NamespacePages => {
|
|
154
187
|
const { name, elements, basePath, linkByGlibName, pageContext } = input;
|
|
155
|
-
const directory = name
|
|
188
|
+
const directory = ownedEntry(namespaceDirectory({ name }), `the GIR namespace ${name}`);
|
|
156
189
|
|
|
157
190
|
const docs: DocsNamespace = {
|
|
158
191
|
name,
|
|
@@ -162,7 +195,7 @@ const namespacePages = (input: {
|
|
|
162
195
|
};
|
|
163
196
|
|
|
164
197
|
const pages: Page[] = elements.map((entry) => ({
|
|
165
|
-
path:
|
|
198
|
+
path: elementPagePath(directory, entry),
|
|
166
199
|
content: renderElementPage(entry, pageContext),
|
|
167
200
|
}));
|
|
168
201
|
|
|
@@ -187,21 +220,90 @@ const generatePages = (options: DocsOptions, basePath: string, library: Library)
|
|
|
187
220
|
namespaces.push(result.docs);
|
|
188
221
|
}
|
|
189
222
|
|
|
190
|
-
pages.push({ path:
|
|
223
|
+
pages.push({ path: ROOT_INDEX_FILENAME, content: rootIndexPage(namespaces, options.libraries) });
|
|
191
224
|
|
|
192
225
|
return { pages, namespaces };
|
|
193
226
|
};
|
|
194
227
|
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
228
|
+
const isGeneratorTag = (value: unknown): value is string => value === MANIFEST_GENERATOR;
|
|
229
|
+
|
|
230
|
+
const isDocsElementLink = (value: unknown): value is DocsElementLink =>
|
|
231
|
+
hasFields<DocsElementLink>(value, { text: isString, link: isString });
|
|
232
|
+
|
|
233
|
+
const isDocsNamespace = (value: unknown): value is DocsNamespace =>
|
|
234
|
+
hasFields<DocsNamespace>(value, {
|
|
235
|
+
name: isString,
|
|
236
|
+
directory: isChildEntry,
|
|
237
|
+
link: isString,
|
|
238
|
+
elements: arrayGuard(isDocsElementLink),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const isDocsManifest = (value: unknown): value is DocsManifest =>
|
|
242
|
+
hasFields<DocsManifest>(value, { generator: isGeneratorTag, namespaces: arrayGuard(isDocsNamespace) });
|
|
243
|
+
|
|
244
|
+
const readDocsManifest = (manifestPath: string): DocsManifest | undefined => {
|
|
245
|
+
const parsed = readJsonFile(manifestPath);
|
|
246
|
+
|
|
247
|
+
return isDocsManifest(parsed) ? parsed : undefined;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const outDirRefusal = (outDir: string, reason: string): Error =>
|
|
251
|
+
new Error(
|
|
252
|
+
`Refusing to generate documentation into ${outDir}: ${reason}. Point the output directory at an ` +
|
|
253
|
+
"empty directory or at one gtkx generated, or remove it yourself first.",
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const assertOwnedOutDir = (options: DocsOptions, manifest: DocsManifest | undefined): void => {
|
|
257
|
+
const stats = statSync(options.outDir, { throwIfNoEntry: false });
|
|
258
|
+
|
|
259
|
+
if (stats === undefined) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!stats.isDirectory()) {
|
|
264
|
+
throw outDirRefusal(options.outDir, "it already exists and is not a directory");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (manifest !== undefined || readdirSync(options.outDir).length === 0) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
throw outDirRefusal(
|
|
272
|
+
options.outDir,
|
|
273
|
+
`it is not empty and holds no ${MANIFEST_FILENAME} written by \`gtkx docs\`, ` +
|
|
274
|
+
"so its contents are not gtkx's to replace",
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const clearOutDir = (options: DocsOptions, manifest: DocsManifest | undefined): void => {
|
|
279
|
+
if (manifest === undefined) {
|
|
280
|
+
return;
|
|
198
281
|
}
|
|
199
282
|
|
|
200
|
-
|
|
283
|
+
const entries = [
|
|
284
|
+
...manifest.namespaces.map((namespace) => namespace.directory),
|
|
285
|
+
ROOT_INDEX_FILENAME,
|
|
286
|
+
MANIFEST_FILENAME,
|
|
287
|
+
FINGERPRINT_FILENAME,
|
|
288
|
+
];
|
|
289
|
+
|
|
290
|
+
for (const entry of entries) {
|
|
291
|
+
rmSync(join(options.outDir, entry), { recursive: true, force: true });
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const cachedDocsResult = (
|
|
296
|
+
options: DocsOptions,
|
|
297
|
+
manifest: DocsManifest | undefined,
|
|
298
|
+
input: DocsFingerprintInput,
|
|
299
|
+
): DocsResult | undefined => {
|
|
300
|
+
if (manifest === undefined || options.isForced === true) {
|
|
201
301
|
return undefined;
|
|
202
302
|
}
|
|
203
303
|
|
|
204
|
-
|
|
304
|
+
if (!isDocsOutputFresh(options.outDir, options.libraries, options.girPath, input)) {
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
205
307
|
|
|
206
308
|
return { isRegenerated: false, namespaces: manifest.namespaces };
|
|
207
309
|
};
|
|
@@ -214,28 +316,36 @@ const writePages = (outDir: string, pages: Page[]): void => {
|
|
|
214
316
|
}
|
|
215
317
|
};
|
|
216
318
|
|
|
319
|
+
const docsFingerprintInput = (options: DocsOptions): DocsFingerprintInput => ({
|
|
320
|
+
basePath: options.basePath ?? DEFAULT_BASE_PATH,
|
|
321
|
+
props: options.props ?? {},
|
|
322
|
+
omittedProps: options.omittedProps ?? {},
|
|
323
|
+
});
|
|
324
|
+
|
|
217
325
|
const writeDocs = (options: DocsOptions): DocsResult => {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
326
|
+
const input = docsFingerprintInput(options);
|
|
327
|
+
setElementProps(input.props);
|
|
328
|
+
setOmittedProps(input.omittedProps);
|
|
221
329
|
const manifestPath = join(options.outDir, MANIFEST_FILENAME);
|
|
222
|
-
const
|
|
330
|
+
const previous = readDocsManifest(manifestPath);
|
|
331
|
+
const cached = cachedDocsResult(options, previous, input);
|
|
223
332
|
|
|
224
333
|
if (cached !== undefined) {
|
|
225
334
|
return cached;
|
|
226
335
|
}
|
|
227
336
|
|
|
337
|
+
assertOwnedOutDir(options, previous);
|
|
228
338
|
const library = Library.load(options.libraries, options.girPath);
|
|
229
|
-
const { pages, namespaces } = generatePages(options, basePath, library);
|
|
230
|
-
|
|
339
|
+
const { pages, namespaces } = generatePages(options, input.basePath, library);
|
|
340
|
+
clearOutDir(options, previous);
|
|
231
341
|
mkdirSync(options.outDir, { recursive: true });
|
|
232
|
-
|
|
233
|
-
const manifest: DocsManifest = { namespaces };
|
|
342
|
+
const manifest: DocsManifest = { generator: MANIFEST_GENERATOR, namespaces };
|
|
234
343
|
writeFileSync(manifestPath, JSON.stringify(manifest));
|
|
344
|
+
writePages(options.outDir, pages);
|
|
235
345
|
|
|
236
346
|
writeFileSync(
|
|
237
347
|
join(options.outDir, FINGERPRINT_FILENAME),
|
|
238
|
-
JSON.stringify(
|
|
348
|
+
JSON.stringify(computeDocsFingerprint(library.girFiles, options.libraries, options.girPath, input)),
|
|
239
349
|
);
|
|
240
350
|
|
|
241
351
|
return { isRegenerated: true, namespaces };
|
package/src/docs/render.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sanitizeTypeIdentifier, sortStringsBy } from "@gtkx/utils";
|
|
2
2
|
import type { GirAnnotations } from "../gir/annotations.js";
|
|
3
3
|
import type { GirClass } from "../gir/class.js";
|
|
4
4
|
import type { GirFunction } from "../gir/function.js";
|
|
@@ -286,10 +286,13 @@ const originSignatureBlocks = (entries: OriginSignatureEntry[]): string[] =>
|
|
|
286
286
|
signatureEntryBlock(item, item.origin === undefined ? [] : [`From \`${item.origin}\`.`]),
|
|
287
287
|
);
|
|
288
288
|
|
|
289
|
+
const qualifiedClassName = (namespaceName: string, className: string): string =>
|
|
290
|
+
`${namespaceName}.${sanitizeTypeIdentifier(className)}`;
|
|
291
|
+
|
|
289
292
|
const classMethodEntries = (library: Library, namespace: GirNamespace, klass: GirClass): SignatureEntry[] => {
|
|
290
293
|
const realContext = new ModuleContext(namespace, library);
|
|
291
294
|
const signatureContext = docsSignatureContext(namespace, library);
|
|
292
|
-
const className =
|
|
295
|
+
const className = sanitizeTypeIdentifier(klass.name);
|
|
293
296
|
const inherited = collectInheritedMethods(realContext, klass);
|
|
294
297
|
|
|
295
298
|
return instanceMethodEntries(signatureContext, klass, (method) =>
|
|
@@ -307,7 +310,7 @@ const instanceMethodEntries = (
|
|
|
307
310
|
): SignatureEntry[] => {
|
|
308
311
|
const deduped = dedupeCallables(klass.methods);
|
|
309
312
|
|
|
310
|
-
const scope = instanceScope(
|
|
313
|
+
const scope = instanceScope(sanitizeTypeIdentifier(klass.name), {
|
|
311
314
|
constructors: dedupeCallables(klass.constructors),
|
|
312
315
|
functions: dedupeCallables(klass.functions),
|
|
313
316
|
methods: deduped,
|
|
@@ -362,6 +365,7 @@ export {
|
|
|
362
365
|
originSignatureBlocks,
|
|
363
366
|
classMethodEntries,
|
|
364
367
|
methodsSectionBlocks,
|
|
368
|
+
qualifiedClassName,
|
|
365
369
|
tagNotes,
|
|
366
370
|
type MetaDocEntry,
|
|
367
371
|
type SignatureEntry,
|