rooklang 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +177 -2
- package/README.ru.md +178 -0
- package/dist/ast/declarations.d.ts +185 -0
- package/dist/ast/declarations.js +1 -0
- package/dist/ast/expressions.d.ts +201 -0
- package/dist/ast/expressions.js +1 -0
- package/dist/ast/markup.d.ts +141 -0
- package/dist/ast/markup.js +1 -0
- package/dist/ast/statements.d.ts +173 -0
- package/dist/ast/statements.js +1 -0
- package/dist/ast.d.ts +18 -0
- package/dist/ast.js +18 -0
- package/dist/attrs.d.ts +8 -0
- package/dist/attrs.js +23 -0
- package/dist/browser.d.ts +30 -0
- package/dist/browser.js +36 -0
- package/dist/build.d.ts +48 -0
- package/dist/build.js +112 -0
- package/dist/checker/assignments.d.ts +14 -0
- package/dist/checker/assignments.js +197 -0
- package/dist/checker/base.d.ts +124 -0
- package/dist/checker/base.js +180 -0
- package/dist/checker/bigint.d.ts +15 -0
- package/dist/checker/bigint.js +85 -0
- package/dist/checker/builtins.d.ts +9 -0
- package/dist/checker/builtins.js +307 -0
- package/dist/checker/bytes.d.ts +11 -0
- package/dist/checker/bytes.js +72 -0
- package/dist/checker/calls.d.ts +23 -0
- package/dist/checker/calls.js +210 -0
- package/dist/checker/channel.d.ts +14 -0
- package/dist/checker/channel.js +44 -0
- package/dist/checker/channels.d.ts +9 -0
- package/dist/checker/channels.js +95 -0
- package/dist/checker/checker.d.ts +4 -0
- package/dist/checker/checker.js +22 -0
- package/dist/checker/classes.d.ts +24 -0
- package/dist/checker/classes.js +223 -0
- package/dist/checker/completion-names.d.ts +11 -0
- package/dist/checker/completion-names.js +100 -0
- package/dist/checker/completion.d.ts +25 -0
- package/dist/checker/completion.js +222 -0
- package/dist/checker/component-values.d.ts +11 -0
- package/dist/checker/component-values.js +88 -0
- package/dist/checker/components.d.ts +37 -0
- package/dist/checker/components.js +287 -0
- package/dist/checker/context.d.ts +196 -0
- package/dist/checker/context.js +35 -0
- package/dist/checker/control-flow.d.ts +24 -0
- package/dist/checker/control-flow.js +237 -0
- package/dist/checker/declarations.d.ts +26 -0
- package/dist/checker/declarations.js +259 -0
- package/dist/checker/decorator-exports.d.ts +5 -0
- package/dist/checker/decorator-exports.js +40 -0
- package/dist/checker/decorator-members.d.ts +28 -0
- package/dist/checker/decorator-members.js +140 -0
- package/dist/checker/decorator-wrappers.d.ts +20 -0
- package/dist/checker/decorator-wrappers.js +132 -0
- package/dist/checker/decorators.d.ts +28 -0
- package/dist/checker/decorators.js +265 -0
- package/dist/checker/dom-svg.d.ts +7 -0
- package/dist/checker/dom-svg.js +19 -0
- package/dist/checker/dom.d.ts +22 -0
- package/dist/checker/dom.js +361 -0
- package/dist/checker/expressions.d.ts +32 -0
- package/dist/checker/expressions.js +244 -0
- package/dist/checker/flow.d.ts +18 -0
- package/dist/checker/flow.js +134 -0
- package/dist/checker/forwarding.d.ts +15 -0
- package/dist/checker/forwarding.js +78 -0
- package/dist/checker/functions.d.ts +24 -0
- package/dist/checker/functions.js +154 -0
- package/dist/checker/go-for.d.ts +12 -0
- package/dist/checker/go-for.js +93 -0
- package/dist/checker/goroutines.d.ts +19 -0
- package/dist/checker/goroutines.js +110 -0
- package/dist/checker/helpers.d.ts +35 -0
- package/dist/checker/helpers.js +162 -0
- package/dist/checker/imports.d.ts +7 -0
- package/dist/checker/imports.js +83 -0
- package/dist/checker/initializers.d.ts +22 -0
- package/dist/checker/initializers.js +104 -0
- package/dist/checker/iterables.d.ts +5 -0
- package/dist/checker/iterables.js +17 -0
- package/dist/checker/iterators.d.ts +13 -0
- package/dist/checker/iterators.js +95 -0
- package/dist/checker/loops.d.ts +10 -0
- package/dist/checker/loops.js +82 -0
- package/dist/checker/markup.d.ts +28 -0
- package/dist/checker/markup.js +220 -0
- package/dist/checker/members.d.ts +29 -0
- package/dist/checker/members.js +233 -0
- package/dist/checker/operators.d.ts +13 -0
- package/dist/checker/operators.js +177 -0
- package/dist/checker/promise.d.ts +17 -0
- package/dist/checker/promise.js +49 -0
- package/dist/checker/refs.d.ts +26 -0
- package/dist/checker/refs.js +136 -0
- package/dist/checker/resolution.d.ts +23 -0
- package/dist/checker/resolution.js +173 -0
- package/dist/checker/statements.d.ts +28 -0
- package/dist/checker/statements.js +212 -0
- package/dist/checker/styles.d.ts +14 -0
- package/dist/checker/styles.js +49 -0
- package/dist/checker/transfer.d.ts +5 -0
- package/dist/checker/transfer.js +83 -0
- package/dist/checker/types/bytes.d.ts +4 -0
- package/dist/checker/types/bytes.js +51 -0
- package/dist/checker/types/classes.d.ts +22 -0
- package/dist/checker/types/classes.js +93 -0
- package/dist/checker/types/constructors.d.ts +27 -0
- package/dist/checker/types/constructors.js +129 -0
- package/dist/checker/types/generics.d.ts +20 -0
- package/dist/checker/types/generics.js +75 -0
- package/dist/checker/types/lazy.d.ts +30 -0
- package/dist/checker/types/lazy.js +92 -0
- package/dist/checker/types/model.d.ts +149 -0
- package/dist/checker/types/model.js +15 -0
- package/dist/checker/types/params.d.ts +7 -0
- package/dist/checker/types/params.js +220 -0
- package/dist/checker/types/printing.d.ts +6 -0
- package/dist/checker/types/printing.js +109 -0
- package/dist/checker/types/relations.d.ts +16 -0
- package/dist/checker/types/relations.js +294 -0
- package/dist/checker/types.d.ts +9 -0
- package/dist/checker/types.js +10 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +193 -0
- package/dist/codegen/analysis.d.ts +18 -0
- package/dist/codegen/analysis.js +144 -0
- package/dist/codegen/attributes.d.ts +40 -0
- package/dist/codegen/attributes.js +227 -0
- package/dist/codegen/calls.d.ts +22 -0
- package/dist/codegen/calls.js +106 -0
- package/dist/codegen/chan-helpers.d.ts +2 -0
- package/dist/codegen/chan-helpers.js +253 -0
- package/dist/codegen/component-helpers.d.ts +33 -0
- package/dist/codegen/component-helpers.js +18 -0
- package/dist/codegen/component-props.d.ts +42 -0
- package/dist/codegen/component-props.js +173 -0
- package/dist/codegen/component-values.d.ts +27 -0
- package/dist/codegen/component-values.js +146 -0
- package/dist/codegen/components.d.ts +53 -0
- package/dist/codegen/components.js +268 -0
- package/dist/codegen/control-flow.d.ts +25 -0
- package/dist/codegen/control-flow.js +152 -0
- package/dist/codegen/control-statements.d.ts +28 -0
- package/dist/codegen/control-statements.js +226 -0
- package/dist/codegen/creation.d.ts +31 -0
- package/dist/codegen/creation.js +113 -0
- package/dist/codegen/early-returns.d.ts +59 -0
- package/dist/codegen/early-returns.js +244 -0
- package/dist/codegen/element-helpers.d.ts +12 -0
- package/dist/codegen/element-helpers.js +54 -0
- package/dist/codegen/elements.d.ts +71 -0
- package/dist/codegen/elements.js +293 -0
- package/dist/codegen/emitter.d.ts +135 -0
- package/dist/codegen/emitter.js +296 -0
- package/dist/codegen/expressions.d.ts +49 -0
- package/dist/codegen/expressions.js +262 -0
- package/dist/codegen/functions.d.ts +28 -0
- package/dist/codegen/functions.js +170 -0
- package/dist/codegen/go-helpers.d.ts +9 -0
- package/dist/codegen/go-helpers.js +307 -0
- package/dist/codegen/helpers.d.ts +10 -0
- package/dist/codegen/helpers.js +356 -0
- package/dist/codegen/imported.d.ts +38 -0
- package/dist/codegen/imported.js +71 -0
- package/dist/codegen/js.d.ts +20 -0
- package/dist/codegen/js.js +113 -0
- package/dist/codegen/mutations.d.ts +10 -0
- package/dist/codegen/mutations.js +102 -0
- package/dist/codegen/parallel.d.ts +7 -0
- package/dist/codegen/parallel.js +63 -0
- package/dist/codegen/reactive.d.ts +95 -0
- package/dist/codegen/reactive.js +280 -0
- package/dist/codegen/refs.d.ts +62 -0
- package/dist/codegen/refs.js +160 -0
- package/dist/codegen/select-helpers.d.ts +2 -0
- package/dist/codegen/select-helpers.js +135 -0
- package/dist/codegen/simple-statements.d.ts +42 -0
- package/dist/codegen/simple-statements.js +253 -0
- package/dist/codegen/statements.d.ts +22 -0
- package/dist/codegen/statements.js +142 -0
- package/dist/codegen/styles.d.ts +54 -0
- package/dist/codegen/styles.js +157 -0
- package/dist/codegen/syntax.d.ts +18 -0
- package/dist/codegen/syntax.js +70 -0
- package/dist/codegen/thread-helpers.d.ts +2 -0
- package/dist/codegen/thread-helpers.js +198 -0
- package/dist/codegen/updates.d.ts +51 -0
- package/dist/codegen/updates.js +201 -0
- package/dist/codegen/web-components.d.ts +20 -0
- package/dist/codegen/web-components.js +149 -0
- package/dist/compile-file.d.ts +11 -0
- package/dist/compile-file.js +24 -0
- package/dist/compile.d.ts +53 -0
- package/dist/compile.js +187 -0
- package/dist/completion.d.ts +10 -0
- package/dist/completion.js +134 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +44 -0
- package/dist/css/hash.d.ts +1 -0
- package/dist/css/hash.js +10 -0
- package/dist/css/parse.d.ts +42 -0
- package/dist/css/parse.js +138 -0
- package/dist/css/print.d.ts +9 -0
- package/dist/css/print.js +35 -0
- package/dist/css/selectors.d.ts +29 -0
- package/dist/css/selectors.js +168 -0
- package/dist/declarations.d.ts +3 -0
- package/dist/declarations.js +207 -0
- package/dist/decorator-copy.d.ts +18 -0
- package/dist/decorator-copy.js +158 -0
- package/dist/decorators.d.ts +61 -0
- package/dist/decorators.js +241 -0
- package/dist/diagnostics.d.ts +17 -0
- package/dist/diagnostics.js +22 -0
- package/dist/go-for.d.ts +26 -0
- package/dist/go-for.js +155 -0
- package/dist/goroutines.d.ts +37 -0
- package/dist/goroutines.js +253 -0
- package/dist/html-tag.d.ts +21 -0
- package/dist/html-tag.js +103 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +55 -0
- package/dist/inline-packages.d.ts +32 -0
- package/dist/inline-packages.js +129 -0
- package/dist/iterators.d.ts +10 -0
- package/dist/iterators.js +33 -0
- package/dist/lexer/base.d.ts +24 -0
- package/dist/lexer/base.js +87 -0
- package/dist/lexer/lexer.d.ts +8 -0
- package/dist/lexer/lexer.js +134 -0
- package/dist/lexer/literals.d.ts +18 -0
- package/dist/lexer/literals.js +203 -0
- package/dist/lexer/markup.d.ts +10 -0
- package/dist/lexer/markup.js +93 -0
- package/dist/lexer/style.d.ts +17 -0
- package/dist/lexer/style.js +97 -0
- package/dist/lexer/tables.d.ts +53 -0
- package/dist/lexer/tables.js +101 -0
- package/dist/lexer/token.d.ts +42 -0
- package/dist/lexer/token.js +108 -0
- package/dist/loader.d.ts +1 -0
- package/dist/loader.js +50 -0
- package/dist/methods.d.ts +5 -0
- package/dist/methods.js +81 -0
- package/dist/modules.d.ts +3 -0
- package/dist/modules.js +49 -0
- package/dist/names.d.ts +23 -0
- package/dist/names.js +267 -0
- package/dist/parser/base.d.ts +96 -0
- package/dist/parser/base.js +202 -0
- package/dist/parser/classes.d.ts +8 -0
- package/dist/parser/classes.js +164 -0
- package/dist/parser/control-flow.d.ts +29 -0
- package/dist/parser/control-flow.js +232 -0
- package/dist/parser/declarations.d.ts +27 -0
- package/dist/parser/declarations.js +238 -0
- package/dist/parser/decorators.d.ts +30 -0
- package/dist/parser/decorators.js +176 -0
- package/dist/parser/expressions.d.ts +15 -0
- package/dist/parser/expressions.js +255 -0
- package/dist/parser/literals.d.ts +27 -0
- package/dist/parser/literals.js +206 -0
- package/dist/parser/markup.d.ts +22 -0
- package/dist/parser/markup.js +193 -0
- package/dist/parser/parser.d.ts +14 -0
- package/dist/parser/parser.js +22 -0
- package/dist/parser/simple-statements.d.ts +22 -0
- package/dist/parser/simple-statements.js +156 -0
- package/dist/parser/statements.d.ts +37 -0
- package/dist/parser/statements.js +267 -0
- package/dist/parser/syntax.d.ts +51 -0
- package/dist/parser/syntax.js +173 -0
- package/dist/parser/types.d.ts +23 -0
- package/dist/parser/types.js +218 -0
- package/dist/recursion.d.ts +25 -0
- package/dist/recursion.js +170 -0
- package/dist/refs.d.ts +49 -0
- package/dist/refs.js +210 -0
- package/dist/run.d.ts +1 -0
- package/dist/run.js +21 -0
- package/dist/source.d.ts +15 -0
- package/dist/source.js +34 -0
- package/dist/style-modules.d.ts +17 -0
- package/dist/style-modules.js +49 -0
- package/dist/styles.d.ts +36 -0
- package/dist/styles.js +160 -0
- package/dist/svg.d.ts +8 -0
- package/dist/svg.js +77 -0
- package/dist/ts-types.d.ts +11 -0
- package/dist/ts-types.js +133 -0
- package/dist/typed-arrays.d.ts +8 -0
- package/dist/typed-arrays.js +43 -0
- package/dist/typescript/convert-base.d.ts +42 -0
- package/dist/typescript/convert-base.js +135 -0
- package/dist/typescript/convert-objects.d.ts +28 -0
- package/dist/typescript/convert-objects.js +245 -0
- package/dist/typescript/convert.d.ts +14 -0
- package/dist/typescript/convert.js +67 -0
- package/dist/typescript/importer.d.ts +37 -0
- package/dist/typescript/importer.js +152 -0
- package/dist/typescript/library.d.ts +23 -0
- package/dist/typescript/library.js +81 -0
- package/dist/vite.d.ts +11 -0
- package/dist/vite.js +86 -0
- package/dist/walk-types.d.ts +4 -0
- package/dist/walk-types.js +56 -0
- package/dist/walk.d.ts +5 -0
- package/dist/walk.js +315 -0
- package/package.json +104 -4
package/dist/run.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
11
|
+
import { CompileError } from "./compile-file.js";
|
|
12
|
+
// The process of `rook run`, started with `--import` of loader.ts: it runs the program and shows
|
|
13
|
+
// compile errors without a stack trace.
|
|
14
|
+
try {
|
|
15
|
+
await import(__rewriteRelativeImportExtension(pathToFileURL(resolve(process.argv[2])).href));
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
// Anything else is thrown by the running program: show the full stack trace.
|
|
19
|
+
console.error(err instanceof CompileError ? err.message : err);
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
}
|
package/dist/source.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** A source file with fast offset → line/column lookup. */
|
|
2
|
+
export declare class SourceFile {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly text: string;
|
|
5
|
+
/** Offset at which each line starts. */
|
|
6
|
+
private readonly lineStarts;
|
|
7
|
+
constructor(name: string, text: string);
|
|
8
|
+
/** 1-based line and column of a character offset. */
|
|
9
|
+
position(offset: number): {
|
|
10
|
+
line: number;
|
|
11
|
+
column: number;
|
|
12
|
+
};
|
|
13
|
+
/** Text of a 1-based line, without the line break. */
|
|
14
|
+
lineText(line: number): string;
|
|
15
|
+
}
|
package/dist/source.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** A source file with fast offset → line/column lookup. */
|
|
2
|
+
export class SourceFile {
|
|
3
|
+
name;
|
|
4
|
+
text;
|
|
5
|
+
/** Offset at which each line starts. */
|
|
6
|
+
lineStarts = [0];
|
|
7
|
+
constructor(name, text) {
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.text = text;
|
|
10
|
+
for (let i = 0; i < text.length; i++) {
|
|
11
|
+
if (text[i] === '\n')
|
|
12
|
+
this.lineStarts.push(i + 1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** 1-based line and column of a character offset. */
|
|
16
|
+
position(offset) {
|
|
17
|
+
let low = 0;
|
|
18
|
+
let high = this.lineStarts.length - 1;
|
|
19
|
+
while (low < high) {
|
|
20
|
+
const mid = (low + high + 1) >> 1;
|
|
21
|
+
if (this.lineStarts[mid] <= offset)
|
|
22
|
+
low = mid;
|
|
23
|
+
else
|
|
24
|
+
high = mid - 1;
|
|
25
|
+
}
|
|
26
|
+
return { line: low + 1, column: offset - this.lineStarts[low] + 1 };
|
|
27
|
+
}
|
|
28
|
+
/** Text of a 1-based line, without the line break. */
|
|
29
|
+
lineText(line) {
|
|
30
|
+
const start = this.lineStarts[line - 1] ?? this.text.length;
|
|
31
|
+
const end = this.lineStarts[line] ?? this.text.length;
|
|
32
|
+
return this.text.slice(start, end).replace(/\r?\n$/, '');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type * as ast from './ast.ts';
|
|
2
|
+
export interface StyleModule {
|
|
3
|
+
/** The hash of the CSS: the suffix of its classes and the id of its `<style>`. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Its classes, in the order they are written, and the names they get. */
|
|
6
|
+
classes: Map<string, string>;
|
|
7
|
+
css: string;
|
|
8
|
+
problems: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Whether an import is of a CSS module. */
|
|
11
|
+
export declare function isStyleModule(specifier: string): boolean;
|
|
12
|
+
export declare function styleModule(text: string): StyleModule;
|
|
13
|
+
/**
|
|
14
|
+
* The classes of a CSS module that the program never names: `styles.button` and
|
|
15
|
+
* `styles["is-active"]` name one. Any other use, e.g. `styles[kind]`, may name each of them.
|
|
16
|
+
*/
|
|
17
|
+
export declare function unusedClasses(program: ast.Program, local: string, module: StyleModule): string[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { hash } from "./css/hash.js";
|
|
2
|
+
import { parseCss } from "./css/parse.js";
|
|
3
|
+
import { printCss, valueText } from "./css/print.js";
|
|
4
|
+
import { renameClasses } from "./css/selectors.js";
|
|
5
|
+
import { forEachChild } from "./walk.js";
|
|
6
|
+
/** Whether an import is of a CSS module. */
|
|
7
|
+
export function isStyleModule(specifier) {
|
|
8
|
+
return specifier.endsWith('.module.css');
|
|
9
|
+
}
|
|
10
|
+
export function styleModule(text) {
|
|
11
|
+
const id = hash(text);
|
|
12
|
+
const sheet = parseCss(text);
|
|
13
|
+
const classes = new Map();
|
|
14
|
+
const css = printCss(sheet.nodes, {
|
|
15
|
+
selector: (selector) => renameClasses(selector, (name) => `${name}_${id}`, (name) => classes.set(name, `${name}_${id}`)),
|
|
16
|
+
value: (declaration) => valueText(declaration, () => ''),
|
|
17
|
+
});
|
|
18
|
+
return { id, classes, css, problems: sheet.problems.map((problem) => problem.message) };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The classes of a CSS module that the program never names: `styles.button` and
|
|
22
|
+
* `styles["is-active"]` name one. Any other use, e.g. `styles[kind]`, may name each of them.
|
|
23
|
+
*/
|
|
24
|
+
export function unusedClasses(program, local, module) {
|
|
25
|
+
const used = new Set();
|
|
26
|
+
let dynamic = false;
|
|
27
|
+
const visit = (node) => {
|
|
28
|
+
if (node.kind === 'MemberExpression' && isLocal(node.object)) {
|
|
29
|
+
used.add(node.property.name);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (node.kind === 'IndexExpression' && isLocal(node.object)) {
|
|
33
|
+
if (node.index.kind === 'StringLiteral')
|
|
34
|
+
used.add(node.index.value);
|
|
35
|
+
else
|
|
36
|
+
dynamic = true;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (isLocal(node))
|
|
40
|
+
dynamic = true;
|
|
41
|
+
forEachChild(node, visit);
|
|
42
|
+
};
|
|
43
|
+
const isLocal = (node) => node.kind === 'Identifier' && node.name === local;
|
|
44
|
+
for (const statement of program.body) {
|
|
45
|
+
if (statement.kind !== 'ImportDeclaration')
|
|
46
|
+
visit(statement);
|
|
47
|
+
}
|
|
48
|
+
return dynamic ? [] : [...module.classes.keys()].filter((name) => !used.has(name));
|
|
49
|
+
}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type * as ast from './ast.ts';
|
|
2
|
+
import { type CssDeclaration, type CssNode, type CssProblem } from './css/parse.ts';
|
|
3
|
+
export interface ComponentStyle {
|
|
4
|
+
/** `rook-product-card-1x9k2az`: the class of the elements of the component's own markup. */
|
|
5
|
+
scope: string;
|
|
6
|
+
nodes: CssNode[];
|
|
7
|
+
/** Problems of the CSS, with offsets in the source of the module. */
|
|
8
|
+
problems: CssProblem[];
|
|
9
|
+
/** The values from code, in the order they are numbered in the declarations. */
|
|
10
|
+
values: ast.Expression[];
|
|
11
|
+
/** Declarations with values from code and the CSS variables they become. */
|
|
12
|
+
variables: Map<CssDeclaration, string>;
|
|
13
|
+
/** The offset in the source of an offset in the parsed text. */
|
|
14
|
+
sourceOffset: (offset: number) => number;
|
|
15
|
+
}
|
|
16
|
+
/** The `style` blocks at the top level of the body of a component or a decorator. */
|
|
17
|
+
export declare function styleBlocks(body: ast.BlockStatement): ast.StyleStatement[];
|
|
18
|
+
/** The style of a component or a decorator, or null if it has no `style` block. */
|
|
19
|
+
export declare function componentStyle(name: string, body: ast.BlockStatement): ComponentStyle | null;
|
|
20
|
+
/** The CSS of a style: the class of the component in the selectors, variables for the values. */
|
|
21
|
+
export declare function scopedCss(style: ComponentStyle): string;
|
|
22
|
+
/** `ProductCard` → `product-card`. */
|
|
23
|
+
export declare function kebabCase(name: string): string;
|
|
24
|
+
/** Whether an element has a `class` attribute. */
|
|
25
|
+
export declare function hasClass(node: ast.ElementExpression): boolean;
|
|
26
|
+
/** The elements of the markup of a body: those that get the class of its style. */
|
|
27
|
+
export declare function ownElements(body: ast.Node): ast.ElementExpression[];
|
|
28
|
+
/**
|
|
29
|
+
* Selectors of a style that no element of the markup of `body` can match: with a tag, a class or
|
|
30
|
+
* an id that none of them has. Elements with `class={...}` may have any class.
|
|
31
|
+
*/
|
|
32
|
+
export declare function unmatchedSelectors(style: ComponentStyle, body: ast.Node): {
|
|
33
|
+
selector: string;
|
|
34
|
+
start: number;
|
|
35
|
+
end: number;
|
|
36
|
+
}[];
|
package/dist/styles.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { hash } from "./css/hash.js";
|
|
2
|
+
import { parseCss, SLOT } from "./css/parse.js";
|
|
3
|
+
import { holdsRules } from "./css/parse.js";
|
|
4
|
+
import { printCss, valueText } from "./css/print.js";
|
|
5
|
+
import { requirements, scopeSelector, splitComplex, splitList } from "./css/selectors.js";
|
|
6
|
+
import { forEachChild } from "./walk.js";
|
|
7
|
+
/** The `style` blocks at the top level of the body of a component or a decorator. */
|
|
8
|
+
export function styleBlocks(body) {
|
|
9
|
+
return body.body.filter((statement) => statement.kind === 'StyleStatement');
|
|
10
|
+
}
|
|
11
|
+
/** The style of a component or a decorator, or null if it has no `style` block. */
|
|
12
|
+
export function componentStyle(name, body) {
|
|
13
|
+
const blocks = styleBlocks(body);
|
|
14
|
+
if (blocks.length === 0)
|
|
15
|
+
return null;
|
|
16
|
+
// The blocks as one text, values from code as SLOT; `segments` map it back to the source.
|
|
17
|
+
let text = '';
|
|
18
|
+
const segments = [];
|
|
19
|
+
const values = [];
|
|
20
|
+
for (const block of blocks) {
|
|
21
|
+
for (const part of block.parts) {
|
|
22
|
+
segments.push({ at: text.length, offset: part.start });
|
|
23
|
+
if (part.kind === 'CssText') {
|
|
24
|
+
text += part.value;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
text += SLOT;
|
|
28
|
+
values.push(part);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
text += '\n';
|
|
32
|
+
}
|
|
33
|
+
const sourceOffset = (offset) => {
|
|
34
|
+
const segment = segments.findLast((each) => each.at <= offset) ?? { at: 0, offset: 0 };
|
|
35
|
+
return segment.offset + offset - segment.at;
|
|
36
|
+
};
|
|
37
|
+
const scope = `rook-${kebabCase(name)}-${hash(text)}`;
|
|
38
|
+
const sheet = parseCss(text);
|
|
39
|
+
const variables = new Map();
|
|
40
|
+
visitDeclarations(sheet.nodes, (declaration) => {
|
|
41
|
+
if (declaration.value.some((part) => typeof part === 'number')) {
|
|
42
|
+
variables.set(declaration, `--${scope}-${variables.size}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
scope,
|
|
47
|
+
nodes: sheet.nodes,
|
|
48
|
+
problems: sheet.problems.map((problem) => ({
|
|
49
|
+
message: problem.message,
|
|
50
|
+
start: sourceOffset(problem.start),
|
|
51
|
+
end: sourceOffset(problem.end),
|
|
52
|
+
})),
|
|
53
|
+
values,
|
|
54
|
+
variables,
|
|
55
|
+
sourceOffset,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** The CSS of a style: the class of the component in the selectors, variables for the values. */
|
|
59
|
+
export function scopedCss(style) {
|
|
60
|
+
return printCss(style.nodes, {
|
|
61
|
+
selector: (selector) => scopeSelector(selector, style.scope),
|
|
62
|
+
value: (declaration) => {
|
|
63
|
+
const variable = style.variables.get(declaration);
|
|
64
|
+
return variable ? `var(${variable})` : valueText(declaration, () => '');
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** `ProductCard` → `product-card`. */
|
|
69
|
+
export function kebabCase(name) {
|
|
70
|
+
return name
|
|
71
|
+
.replace(/[^\w-]/g, '')
|
|
72
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
73
|
+
.toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
function visitDeclarations(nodes, visit) {
|
|
76
|
+
for (const node of nodes) {
|
|
77
|
+
if (node.kind === 'declaration')
|
|
78
|
+
visit(node);
|
|
79
|
+
else if (node.body)
|
|
80
|
+
visitDeclarations(node.body, visit);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Whether an element has a `class` attribute. */
|
|
84
|
+
export function hasClass(node) {
|
|
85
|
+
return node.attributes.some((attribute) => attribute.kind === 'JsxAttribute' && attribute.name.name === 'class');
|
|
86
|
+
}
|
|
87
|
+
/** The elements of the markup of a body: those that get the class of its style. */
|
|
88
|
+
export function ownElements(body) {
|
|
89
|
+
const found = [];
|
|
90
|
+
const visit = (node) => {
|
|
91
|
+
// The use of a component is not an element, but what is passed to it is the markup here.
|
|
92
|
+
if (node.kind === 'ElementExpression' &&
|
|
93
|
+
node.tag &&
|
|
94
|
+
node.value === null &&
|
|
95
|
+
!/^[A-Z]/.test(node.tag.name)) {
|
|
96
|
+
found.push(node);
|
|
97
|
+
}
|
|
98
|
+
forEachChild(node, visit);
|
|
99
|
+
};
|
|
100
|
+
visit(body);
|
|
101
|
+
return found;
|
|
102
|
+
}
|
|
103
|
+
function describe(node) {
|
|
104
|
+
let classes = new Set();
|
|
105
|
+
let id = null;
|
|
106
|
+
for (const attribute of node.attributes) {
|
|
107
|
+
if (attribute.kind === 'JsxSpreadAttribute') {
|
|
108
|
+
classes = null;
|
|
109
|
+
id = undefined;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const { name, value } = attribute;
|
|
113
|
+
const text = value?.kind === 'StringLiteral' ? value.value : undefined;
|
|
114
|
+
if (name.name === 'class' && classes !== null) {
|
|
115
|
+
classes = text === undefined ? null : new Set(text.split(/\s+/).filter(Boolean));
|
|
116
|
+
}
|
|
117
|
+
else if (name.name === 'id') {
|
|
118
|
+
id = text;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { tag: node.tag.name.toLowerCase(), classes, id };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Selectors of a style that no element of the markup of `body` can match: with a tag, a class or
|
|
125
|
+
* an id that none of them has. Elements with `class={...}` may have any class.
|
|
126
|
+
*/
|
|
127
|
+
export function unmatchedSelectors(style, body) {
|
|
128
|
+
const elements = ownElements(body).map(describe);
|
|
129
|
+
const found = [];
|
|
130
|
+
const matches = (compound) => {
|
|
131
|
+
if (compound === '' || compound.includes('&') || compound.includes(':global('))
|
|
132
|
+
return true;
|
|
133
|
+
const { tag, classes, ids } = requirements(compound);
|
|
134
|
+
return elements.some((element) => (tag === null || tag.toLowerCase() === element.tag) &&
|
|
135
|
+
(element.classes === null || classes.every((name) => element.classes.has(name))) &&
|
|
136
|
+
(element.id === undefined || ids.every((id) => id === element.id)));
|
|
137
|
+
};
|
|
138
|
+
const visit = (nodes) => {
|
|
139
|
+
for (const node of nodes) {
|
|
140
|
+
if (node.kind === 'rule') {
|
|
141
|
+
for (const complex of splitList(node.selector)) {
|
|
142
|
+
const compounds = splitComplex(complex).filter((_, i) => i % 2 === 0);
|
|
143
|
+
if (!compounds.every(matches)) {
|
|
144
|
+
found.push({
|
|
145
|
+
selector: complex,
|
|
146
|
+
start: style.sourceOffset(node.start),
|
|
147
|
+
end: style.sourceOffset(node.end),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
visit(node.body);
|
|
152
|
+
}
|
|
153
|
+
else if (node.kind === 'at-rule' && node.body && holdsRules(node)) {
|
|
154
|
+
visit(node.body);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
visit(style.nodes);
|
|
159
|
+
return found;
|
|
160
|
+
}
|
package/dist/svg.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type * as ast from './ast.ts';
|
|
2
|
+
export declare const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
3
|
+
/** Whether `<tag>` is an SVG element, inside `<svg>` or not. */
|
|
4
|
+
export declare function isSvgElement(tag: string, inSvg: boolean): boolean;
|
|
5
|
+
/** Whether the children of an element are inside SVG: those of `<foreignObject>` are HTML. */
|
|
6
|
+
export declare function childrenInSvg(tag: string | null, svg: boolean, inSvg: boolean): boolean;
|
|
7
|
+
/** The SVG elements of the markup in `root`, for code that creates them out of their place. */
|
|
8
|
+
export declare function svgElements(root: ast.Node): Set<ast.ElementExpression>;
|
package/dist/svg.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { forEachChild } from "./walk.js";
|
|
2
|
+
// SVG in markup. An element is created in the SVG namespace when it is `<svg>`, inside one, or a
|
|
3
|
+
// tag that only SVG has: so a component can return `<path>` to be put into an `<svg>`. The
|
|
4
|
+
// children of `<foreignObject>` are HTML again. Tags that both have (`a`, `title`, `style`,
|
|
5
|
+
// `script`) are SVG only inside `<svg>`.
|
|
6
|
+
export const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
7
|
+
const SVG_ONLY = new Set([
|
|
8
|
+
'animate',
|
|
9
|
+
'animateMotion',
|
|
10
|
+
'animateTransform',
|
|
11
|
+
'circle',
|
|
12
|
+
'clipPath',
|
|
13
|
+
'defs',
|
|
14
|
+
'desc',
|
|
15
|
+
'ellipse',
|
|
16
|
+
'feBlend',
|
|
17
|
+
'feColorMatrix',
|
|
18
|
+
'feComposite',
|
|
19
|
+
'feDropShadow',
|
|
20
|
+
'feFlood',
|
|
21
|
+
'feGaussianBlur',
|
|
22
|
+
'feMerge',
|
|
23
|
+
'feMergeNode',
|
|
24
|
+
'feOffset',
|
|
25
|
+
'filter',
|
|
26
|
+
'foreignObject',
|
|
27
|
+
'g',
|
|
28
|
+
'image',
|
|
29
|
+
'line',
|
|
30
|
+
'linearGradient',
|
|
31
|
+
'marker',
|
|
32
|
+
'mask',
|
|
33
|
+
'metadata',
|
|
34
|
+
'path',
|
|
35
|
+
'pattern',
|
|
36
|
+
'polygon',
|
|
37
|
+
'polyline',
|
|
38
|
+
'radialGradient',
|
|
39
|
+
'rect',
|
|
40
|
+
'stop',
|
|
41
|
+
'symbol',
|
|
42
|
+
'text',
|
|
43
|
+
'textPath',
|
|
44
|
+
'tspan',
|
|
45
|
+
'use',
|
|
46
|
+
'view',
|
|
47
|
+
]);
|
|
48
|
+
/** Whether `<tag>` is an SVG element, inside `<svg>` or not. */
|
|
49
|
+
export function isSvgElement(tag, inSvg) {
|
|
50
|
+
return tag === 'svg' || SVG_ONLY.has(tag) || (inSvg && !tag.includes('-'));
|
|
51
|
+
}
|
|
52
|
+
/** Whether the children of an element are inside SVG: those of `<foreignObject>` are HTML. */
|
|
53
|
+
export function childrenInSvg(tag, svg, inSvg) {
|
|
54
|
+
return tag === null ? inSvg : svg && tag !== 'foreignObject';
|
|
55
|
+
}
|
|
56
|
+
/** The SVG elements of the markup in `root`, for code that creates them out of their place. */
|
|
57
|
+
export function svgElements(root) {
|
|
58
|
+
const found = new Set();
|
|
59
|
+
const visit = (node, inSvg) => {
|
|
60
|
+
if (node.kind !== 'ElementExpression' ||
|
|
61
|
+
node.value !== null ||
|
|
62
|
+
(node.tag && /^[A-Z]/.test(node.tag.name))) {
|
|
63
|
+
forEachChild(node, (child) => visit(child, inSvg));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const tag = node.tag?.name ?? null;
|
|
67
|
+
const svg = tag !== null && isSvgElement(tag, inSvg);
|
|
68
|
+
if (svg)
|
|
69
|
+
found.add(node);
|
|
70
|
+
for (const attribute of node.attributes)
|
|
71
|
+
visit(attribute, inSvg);
|
|
72
|
+
for (const child of node.children)
|
|
73
|
+
visit(child, childrenInSvg(tag, svg, inSvg));
|
|
74
|
+
};
|
|
75
|
+
visit(root, false);
|
|
76
|
+
return found;
|
|
77
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FunctionType, type Type } from './checker/types.ts';
|
|
2
|
+
/** A nullable property may be left out of an object: `name?: string | null`. */
|
|
3
|
+
export declare function property(name: string, type: Type): string;
|
|
4
|
+
export declare function resultType(results: readonly Type[]): string;
|
|
5
|
+
/**
|
|
6
|
+
* A type in TypeScript syntax. A union keeps the name of its alias, except in the alias itself
|
|
7
|
+
* (`expand`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function tsType(type: Type, expand?: boolean): string;
|
|
10
|
+
/** What calling an iterator gives: a generator of what its `yield` takes, a value or a pair. */
|
|
11
|
+
export declare function generatorType(iterator: FunctionType): string;
|
package/dist/ts-types.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { CONTENT } from "./checker/dom.js";
|
|
2
|
+
import { ERROR_CLASS, memberNames, } from "./checker/types.js";
|
|
3
|
+
// Types of the checker in TypeScript syntax, for declaration files (declarations.ts).
|
|
4
|
+
/** A nullable property may be left out of an object: `name?: string | null`. */
|
|
5
|
+
export function property(name, type) {
|
|
6
|
+
const optional = type.kind === 'nullable' || type.kind === 'null' ? '?' : '';
|
|
7
|
+
return `${name}${optional}: ${tsType(type)};`;
|
|
8
|
+
}
|
|
9
|
+
export function resultType(results) {
|
|
10
|
+
if (results.length === 0)
|
|
11
|
+
return 'void';
|
|
12
|
+
if (results.length === 1)
|
|
13
|
+
return tsType(results[0]);
|
|
14
|
+
return `[${results.map((result) => tsType(result)).join(', ')}]`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A type in TypeScript syntax. A union keeps the name of its alias, except in the alias itself
|
|
18
|
+
* (`expand`).
|
|
19
|
+
*/
|
|
20
|
+
export function tsType(type, expand = false) {
|
|
21
|
+
switch (type.kind) {
|
|
22
|
+
case 'number':
|
|
23
|
+
case 'bigint':
|
|
24
|
+
case 'string':
|
|
25
|
+
case 'any':
|
|
26
|
+
case 'void':
|
|
27
|
+
case 'null':
|
|
28
|
+
case 'never':
|
|
29
|
+
case 'unknown':
|
|
30
|
+
return type.kind;
|
|
31
|
+
case 'bool':
|
|
32
|
+
return 'boolean';
|
|
33
|
+
case 'literal':
|
|
34
|
+
return typeof type.value === 'string' ? JSON.stringify(type.value) : String(type.value);
|
|
35
|
+
case 'nullable':
|
|
36
|
+
return `${grouped(type.type)} | null`;
|
|
37
|
+
case 'union':
|
|
38
|
+
if (type.name !== undefined && !expand)
|
|
39
|
+
return type.name;
|
|
40
|
+
return type.types.map(grouped).join(' | ');
|
|
41
|
+
case 'array':
|
|
42
|
+
return `${element(type.element)}[]`;
|
|
43
|
+
case 'tuple':
|
|
44
|
+
return `[${type.types.map((each) => tsType(each)).join(', ')}]`;
|
|
45
|
+
case 'function':
|
|
46
|
+
return functionType(type);
|
|
47
|
+
// The function of the component: it returns the node and a function that sets the properties.
|
|
48
|
+
case 'component': {
|
|
49
|
+
const params = type.params.map((param) => `${param.name}${param.optional ? '?' : ''}: ${tsType(param.type)}`);
|
|
50
|
+
return `(${params.join(', ')}) => [Node, ...unknown[]]`;
|
|
51
|
+
}
|
|
52
|
+
case 'object':
|
|
53
|
+
return objectType(type);
|
|
54
|
+
case 'class': {
|
|
55
|
+
if (type.info === ERROR_CLASS)
|
|
56
|
+
return 'Error';
|
|
57
|
+
const args = type.args ? `<${type.args.map((arg) => tsType(arg)).join(', ')}>` : '';
|
|
58
|
+
return `${type.info.name}${args}`;
|
|
59
|
+
}
|
|
60
|
+
case 'classValue':
|
|
61
|
+
return `typeof ${type.info.name}`;
|
|
62
|
+
case 'param':
|
|
63
|
+
return type.name;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function functionType(type) {
|
|
67
|
+
if (type.iterator)
|
|
68
|
+
return `() => ${generatorType(type)}`;
|
|
69
|
+
return `(${anonymousParameters(type)}) => ${resultType(type.results)}`;
|
|
70
|
+
}
|
|
71
|
+
/** What calling an iterator gives: a generator of what its `yield` takes, a value or a pair. */
|
|
72
|
+
export function generatorType(iterator) {
|
|
73
|
+
const yieldType = iterator.params[0];
|
|
74
|
+
const taken = yieldType?.kind === 'function' ? yieldType.params : [];
|
|
75
|
+
const yielded = taken.length === 1 ? tsType(taken[0]) : `[${taken.map((each) => tsType(each)).join(', ')}]`;
|
|
76
|
+
return `Generator<${yielded}, void, unknown>`;
|
|
77
|
+
}
|
|
78
|
+
/** A method of an object type: `name(arg1: number): string`. */
|
|
79
|
+
function methodType(name, type) {
|
|
80
|
+
return `${name}(${anonymousParameters(type)}): ${resultType(type.results)};`;
|
|
81
|
+
}
|
|
82
|
+
/** Parameters of a function type, which has no names for them. */
|
|
83
|
+
function anonymousParameters(type) {
|
|
84
|
+
const params = type.params.map((param, i) => `arg${i + 1}${i < type.required ? '' : '?'}: ${tsType(param)}`);
|
|
85
|
+
if (type.rest)
|
|
86
|
+
params.push(`...rest: ${element(type.rest)}[]`);
|
|
87
|
+
return params.join(', ');
|
|
88
|
+
}
|
|
89
|
+
function objectType(type) {
|
|
90
|
+
// The children of a component are a fragment at runtime.
|
|
91
|
+
if (type === CONTENT)
|
|
92
|
+
return 'Node';
|
|
93
|
+
// A channel is an object with its id; TypeScript code only passes it on.
|
|
94
|
+
if (type.name === 'chan' || type.name === 'chan<-' || type.name === '<-chan') {
|
|
95
|
+
return `{ readonly $$chan: string }`;
|
|
96
|
+
}
|
|
97
|
+
if (type.name !== null) {
|
|
98
|
+
const args = type.instanceOf?.args ?? type.typeParams;
|
|
99
|
+
return args ? `${type.name}<${args.map((arg) => tsType(arg)).join(', ')}>` : type.name;
|
|
100
|
+
}
|
|
101
|
+
const members = [...memberNames(type.members)].map((name) => {
|
|
102
|
+
const member = type.members.get(name);
|
|
103
|
+
if (!member)
|
|
104
|
+
return '';
|
|
105
|
+
if (member.method && member.type.kind === 'function')
|
|
106
|
+
return methodType(name, member.type);
|
|
107
|
+
return property(name, member.type);
|
|
108
|
+
});
|
|
109
|
+
if (type.call)
|
|
110
|
+
members.push(methodType('', type.call));
|
|
111
|
+
if (type.index)
|
|
112
|
+
members.unshift(`[key: string]: ${tsType(type.index)};`);
|
|
113
|
+
return members.length === 0 ? '{}' : `{ ${members.filter(Boolean).join(' ')} }`;
|
|
114
|
+
}
|
|
115
|
+
/** Parentheses around unions and functions inside `| null`: `(string | number) | null`. */
|
|
116
|
+
function grouped(type) {
|
|
117
|
+
const text = tsType(type);
|
|
118
|
+
return type.kind === 'function' ||
|
|
119
|
+
type.kind === 'component' ||
|
|
120
|
+
(type.kind === 'union' && type.name === undefined)
|
|
121
|
+
? `(${text})`
|
|
122
|
+
: text;
|
|
123
|
+
}
|
|
124
|
+
/** An element type before `[]`: `(string | null)[]`. */
|
|
125
|
+
function element(type) {
|
|
126
|
+
const text = tsType(type);
|
|
127
|
+
return type.kind === 'function' ||
|
|
128
|
+
type.kind === 'component' ||
|
|
129
|
+
type.kind === 'nullable' ||
|
|
130
|
+
(type.kind === 'union' && type.name === undefined)
|
|
131
|
+
? `(${text})`
|
|
132
|
+
: text;
|
|
133
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The typed array of each element type of Go. */
|
|
2
|
+
export declare const TYPED_ELEMENTS: ReadonlyMap<string, string>;
|
|
3
|
+
/** The typed arrays, by the size of an element in bytes. */
|
|
4
|
+
export declare const TYPED_ARRAYS: ReadonlyMap<string, number>;
|
|
5
|
+
/** Whether the elements of a typed array are bigints. */
|
|
6
|
+
export declare function holdsBigInts(name: string): boolean;
|
|
7
|
+
/** How a typed array is written: `[]float64`, or its own name if Go has none (Uint8ClampedArray). */
|
|
8
|
+
export declare function typedArrayName(name: string): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Typed arrays, written as slices of Go: `[]float64` is a Float64Array, as `[]byte` is a
|
|
2
|
+
// Uint8Array. The names of the elements are numbers, and bigints for the integers of 64 bits.
|
|
3
|
+
/** The typed array of each element type of Go. */
|
|
4
|
+
export const TYPED_ELEMENTS = new Map([
|
|
5
|
+
['byte', 'Uint8Array'],
|
|
6
|
+
['uint8', 'Uint8Array'],
|
|
7
|
+
['int8', 'Int8Array'],
|
|
8
|
+
['int16', 'Int16Array'],
|
|
9
|
+
['uint16', 'Uint16Array'],
|
|
10
|
+
['int32', 'Int32Array'],
|
|
11
|
+
['uint32', 'Uint32Array'],
|
|
12
|
+
['float32', 'Float32Array'],
|
|
13
|
+
['float64', 'Float64Array'],
|
|
14
|
+
['int64', 'BigInt64Array'],
|
|
15
|
+
['uint64', 'BigUint64Array'],
|
|
16
|
+
]);
|
|
17
|
+
/** The typed arrays, by the size of an element in bytes. */
|
|
18
|
+
export const TYPED_ARRAYS = new Map([
|
|
19
|
+
['Int8Array', 1],
|
|
20
|
+
['Uint8Array', 1],
|
|
21
|
+
['Uint8ClampedArray', 1],
|
|
22
|
+
['Int16Array', 2],
|
|
23
|
+
['Uint16Array', 2],
|
|
24
|
+
['Int32Array', 4],
|
|
25
|
+
['Uint32Array', 4],
|
|
26
|
+
['Float32Array', 4],
|
|
27
|
+
['Float64Array', 8],
|
|
28
|
+
['BigInt64Array', 8],
|
|
29
|
+
['BigUint64Array', 8],
|
|
30
|
+
]);
|
|
31
|
+
/** Whether the elements of a typed array are bigints. */
|
|
32
|
+
export function holdsBigInts(name) {
|
|
33
|
+
return name === 'BigInt64Array' || name === 'BigUint64Array';
|
|
34
|
+
}
|
|
35
|
+
/** How a typed array is written: `[]float64`, or its own name if Go has none (Uint8ClampedArray). */
|
|
36
|
+
export function typedArrayName(name) {
|
|
37
|
+
if (name === 'Uint8Array')
|
|
38
|
+
return '[]byte';
|
|
39
|
+
for (const [element, array] of TYPED_ELEMENTS)
|
|
40
|
+
if (array === name)
|
|
41
|
+
return `[]${element}`;
|
|
42
|
+
return name;
|
|
43
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ClassInfo, type ObjectType, type Type, type TypeParam } from '../checker/types.ts';
|
|
2
|
+
import type * as TS from 'typescript';
|
|
3
|
+
/**
|
|
4
|
+
* Types of declarations in TypeScript's lib files and in `node_modules`, by file and name. These
|
|
5
|
+
* files do not change while the compiler runs, so the converters of later programs (a program is
|
|
6
|
+
* created again when an import adds a file) reuse the types of the first one. Otherwise the same
|
|
7
|
+
* `Node` of lib.dom would be two different types, and checking that one fits the other would go
|
|
8
|
+
* through the whole DOM.
|
|
9
|
+
*/
|
|
10
|
+
export type SharedTypes = Map<string, Type | ClassInfo>;
|
|
11
|
+
export declare abstract class ConverterBase {
|
|
12
|
+
protected abstract object(type: TS.Type, name: string | null, typeParams?: TypeParam[]): ObjectType;
|
|
13
|
+
protected abstract objectType(type: TS.ObjectType): Type;
|
|
14
|
+
protected readonly ts: typeof TS;
|
|
15
|
+
protected readonly program: TS.Program;
|
|
16
|
+
protected readonly checker: TS.TypeChecker;
|
|
17
|
+
protected readonly types: Map<TS.Type, Type>;
|
|
18
|
+
/** Types being converted: a function type that refers to itself becomes `any` inside. */
|
|
19
|
+
protected readonly converting: Set<TS.Type>;
|
|
20
|
+
protected readonly params: Map<TS.Type, TypeParam>;
|
|
21
|
+
protected readonly classes: Map<TS.Symbol, ClassInfo>;
|
|
22
|
+
protected readonly shared: SharedTypes;
|
|
23
|
+
protected arrayInterface: ObjectType | undefined;
|
|
24
|
+
constructor(ts: typeof TS, program: TS.Program, shared?: SharedTypes);
|
|
25
|
+
/** The key of a declaration that does not change between programs, or `null`. */
|
|
26
|
+
protected sharedKey(symbol: TS.Symbol, kind: string): string | null;
|
|
27
|
+
convert(type: TS.Type): Type;
|
|
28
|
+
protected convertType(type: TS.Type): Type;
|
|
29
|
+
/** `undefined`, `null` and `void` in a union make it nullable: `string | undefined` is `?string`. */
|
|
30
|
+
protected union(types: readonly TS.Type[]): Type;
|
|
31
|
+
protected typeParamOrThis(type: TS.Type): Type;
|
|
32
|
+
/**
|
|
33
|
+
* Constraints are not kept: they only matter in the bodies of generic functions, which in a
|
|
34
|
+
* `.d.ts` are not checked, and many have no counterpart. Defaults are kept: `Buffer` is
|
|
35
|
+
* `Buffer<ArrayBufferLike>`.
|
|
36
|
+
*/
|
|
37
|
+
protected typeParam(type: TS.Type): TypeParam;
|
|
38
|
+
/** Declared in TypeScript's lib files. */
|
|
39
|
+
protected isLibrary(symbol: TS.Symbol): boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Members that Rook code can name: not `[Symbol.iterator]` and the like. */
|
|
42
|
+
export declare function propertyNames(checker: TS.TypeChecker, type: TS.Type): string[];
|