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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { decoratedName } from "../decorators.js";
|
|
2
|
+
import { forEachChild } from "../walk.js";
|
|
3
|
+
// What code reads: the names of values, and the variable a change goes into.
|
|
4
|
+
/** The variable at the start of `a.b[i].c()`, or `null`. */
|
|
5
|
+
export function rootName(node) {
|
|
6
|
+
switch (node.kind) {
|
|
7
|
+
case 'Identifier':
|
|
8
|
+
return node.name;
|
|
9
|
+
case 'MemberExpression':
|
|
10
|
+
case 'IndexExpression':
|
|
11
|
+
return rootName(node.object);
|
|
12
|
+
case 'CallExpression':
|
|
13
|
+
return rootName(node.callee);
|
|
14
|
+
case 'DecoratorGet':
|
|
15
|
+
return rootName(node.target);
|
|
16
|
+
case 'DecoratorMember':
|
|
17
|
+
return decoratedName(node.decorator.name, node.member.name);
|
|
18
|
+
default:
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Names whose values a node reads, not counting code that runs on events. */
|
|
23
|
+
export function readNames(node, names) {
|
|
24
|
+
switch (node.kind) {
|
|
25
|
+
case 'Identifier':
|
|
26
|
+
names.add(node.name);
|
|
27
|
+
return;
|
|
28
|
+
case 'DecoratorMember':
|
|
29
|
+
names.add(decoratedName(node.decorator.name, node.member.name));
|
|
30
|
+
return;
|
|
31
|
+
case 'MemberExpression':
|
|
32
|
+
readNames(node.object, names);
|
|
33
|
+
return;
|
|
34
|
+
case 'Property':
|
|
35
|
+
readNames(node.value, names);
|
|
36
|
+
return;
|
|
37
|
+
case 'ElementExpression':
|
|
38
|
+
// `<section.content />` and `<Page />` read the value they take the component from.
|
|
39
|
+
if (node.value)
|
|
40
|
+
readNames(node.value, names);
|
|
41
|
+
else if (node.tag && /^[A-Z]/.test(node.tag.name))
|
|
42
|
+
names.add(node.tag.name);
|
|
43
|
+
for (const attribute of node.attributes)
|
|
44
|
+
readNames(attribute, names);
|
|
45
|
+
for (const child of node.children)
|
|
46
|
+
readNames(child, names);
|
|
47
|
+
return;
|
|
48
|
+
case 'JsxAttribute':
|
|
49
|
+
if (node.value !== null && !/^on[A-Z]/.test(node.name.name))
|
|
50
|
+
readNames(node.value, names);
|
|
51
|
+
return;
|
|
52
|
+
// Both run later, when the markup exists.
|
|
53
|
+
case 'EventHandler':
|
|
54
|
+
case 'MountStatement':
|
|
55
|
+
case 'EffectStatement':
|
|
56
|
+
return;
|
|
57
|
+
default:
|
|
58
|
+
forEachChild(node, (child) => readNames(child, names));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Names an effect reads while it runs: not in the functions it creates, which run later, nor in
|
|
63
|
+
* its `defer`, nor the variables it writes, or `count++` would run it again.
|
|
64
|
+
*/
|
|
65
|
+
export function effectReads(node, names) {
|
|
66
|
+
switch (node.kind) {
|
|
67
|
+
case 'FuncDeclaration':
|
|
68
|
+
case 'FuncExpression':
|
|
69
|
+
case 'ArrowFunction':
|
|
70
|
+
case 'ClassDeclaration':
|
|
71
|
+
case 'DeferStatement':
|
|
72
|
+
return;
|
|
73
|
+
case 'AssignmentStatement':
|
|
74
|
+
for (const target of node.targets) {
|
|
75
|
+
if (target.kind !== 'Identifier')
|
|
76
|
+
effectReads(target, names);
|
|
77
|
+
}
|
|
78
|
+
for (const value of node.values)
|
|
79
|
+
effectReads(value, names);
|
|
80
|
+
return;
|
|
81
|
+
case 'IncDecStatement':
|
|
82
|
+
case 'DeleteStatement':
|
|
83
|
+
if (node.target.kind !== 'Identifier')
|
|
84
|
+
effectReads(node.target, names);
|
|
85
|
+
return;
|
|
86
|
+
case 'Identifier':
|
|
87
|
+
case 'DecoratorMember':
|
|
88
|
+
case 'ElementExpression':
|
|
89
|
+
case 'JsxAttribute':
|
|
90
|
+
case 'EventHandler':
|
|
91
|
+
readNames(node, names);
|
|
92
|
+
return;
|
|
93
|
+
case 'MemberExpression':
|
|
94
|
+
effectReads(node.object, names);
|
|
95
|
+
return;
|
|
96
|
+
case 'Property':
|
|
97
|
+
effectReads(node.value, names);
|
|
98
|
+
return;
|
|
99
|
+
default:
|
|
100
|
+
forEachChild(node, (child) => effectReads(child, names));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type * as ast from '../ast.ts';
|
|
2
|
+
import { ControlStatementEmitter } from './control-statements.ts';
|
|
3
|
+
export declare abstract class ParallelLoopEmitter extends ControlStatementEmitter {
|
|
4
|
+
protected forInStatement(node: ast.ForInStatement): void;
|
|
5
|
+
/** The loop over a part, in the function of the worker module that runs it. */
|
|
6
|
+
private partLoop;
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { arrayName, arrayUses, partOf, writesArray } from "../go-for.js";
|
|
2
|
+
import { goCaptures, goTarget } from "../goroutines.js";
|
|
3
|
+
import { declaredIn } from "../names.js";
|
|
4
|
+
import { ControlStatementEmitter } from "./control-statements.js";
|
|
5
|
+
import { ARROW } from "./syntax.js";
|
|
6
|
+
// `go for i, v in items { ... }`: `await $$goFor("$$goroutine0", items, ...)` splits the array into
|
|
7
|
+
// parts and runs each as a goroutine (go-helpers.ts). In the worker module, the function of a part
|
|
8
|
+
// loops over it: `i` is the index in the whole array, from `$$from`, the index of the part's first
|
|
9
|
+
// element, and `items[i]` is `items[$$i]`, the index in the part. The part goes back if the body
|
|
10
|
+
// writes into it; a typed array is moved back, not copied.
|
|
11
|
+
export class ParallelLoopEmitter extends ControlStatementEmitter {
|
|
12
|
+
forInStatement(node) {
|
|
13
|
+
const loop = partOf(node);
|
|
14
|
+
if (loop) {
|
|
15
|
+
this.partLoop(node, loop);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!node.go) {
|
|
19
|
+
super.forInStatement(node);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const args = [
|
|
23
|
+
JSON.stringify(goTarget(this.program, node)),
|
|
24
|
+
this.expression(node.iterable, ARROW),
|
|
25
|
+
...goCaptures(this.program, node).map((name) => this.name(name)),
|
|
26
|
+
];
|
|
27
|
+
this.helpers.add('goFor');
|
|
28
|
+
this.helpers.add(this.inWorker ? 'goLocal' : 'go');
|
|
29
|
+
this.line(`await $$goFor(${args.join(', ')});`);
|
|
30
|
+
}
|
|
31
|
+
/** The loop over a part, in the function of the worker module that runs it. */
|
|
32
|
+
partLoop(node, loop) {
|
|
33
|
+
const array = this.name(arrayName(loop) ?? '$$items');
|
|
34
|
+
const uses = arrayUses(loop);
|
|
35
|
+
const key = node.key && node.key.name !== '_' ? node.key.name : null;
|
|
36
|
+
const value = node.value.name === '_' ? null : node.value.name;
|
|
37
|
+
const bindings = [key, value].flatMap((name) => name === null ? [] : [[name, 'loop']]);
|
|
38
|
+
// A declaration of the same name in the body would clash with the loop's in one block.
|
|
39
|
+
const hidden = declaredIn(node.body.body).some((name) => name === key || name === value);
|
|
40
|
+
for (const element of uses.elements)
|
|
41
|
+
this.partElements.add(element);
|
|
42
|
+
this.withScope(bindings, () => {
|
|
43
|
+
const body = this.withBreakTarget(null, () => this.block(() => {
|
|
44
|
+
if (key !== null)
|
|
45
|
+
this.line(`const ${this.name(key)} = $$from + $$i;`);
|
|
46
|
+
if (value !== null)
|
|
47
|
+
this.line(`const ${this.name(value)} = ${array}[$$i];`);
|
|
48
|
+
if (hidden)
|
|
49
|
+
this.line(this.blockStatement(node.body));
|
|
50
|
+
else
|
|
51
|
+
this.blockStatements(node.body.body);
|
|
52
|
+
}));
|
|
53
|
+
this.line(`for (let $$i = 0; $$i < ${array}.length; $$i++) ${body}`);
|
|
54
|
+
});
|
|
55
|
+
for (const element of uses.elements)
|
|
56
|
+
this.partElements.delete(element);
|
|
57
|
+
if (!writesArray(loop, uses))
|
|
58
|
+
return;
|
|
59
|
+
// The part of a typed array moves back; without types, $$transfer leaves an array as it is.
|
|
60
|
+
const plain = this.options.types?.get(loop.iterable)?.kind === 'array';
|
|
61
|
+
this.line(plain ? `return ${array};` : `return $$transfer(${array});`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type * as ast from '../ast.ts';
|
|
2
|
+
import type { Type } from '../checker/types.ts';
|
|
3
|
+
import { readNames } from './mutations.ts';
|
|
4
|
+
/** What markup can depend on: a `state` variable, or a property that gets the parent's state. */
|
|
5
|
+
export interface Source {
|
|
6
|
+
/** Unique in the module; marks the places that change the source in the generated code. */
|
|
7
|
+
readonly id: number;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly kind: 'state' | 'prop';
|
|
10
|
+
/** The function that brings dependent nodes up to date, e.g. `$$updateCount3`. */
|
|
11
|
+
readonly update: string;
|
|
12
|
+
/**
|
|
13
|
+
* Statements that compute again the `derived` values that read it: `double = count * 2`. They
|
|
14
|
+
* run first, also before the markup exists, so that the values are right whenever they are read.
|
|
15
|
+
*/
|
|
16
|
+
readonly computations: string[];
|
|
17
|
+
/** Statements that bring the nodes depending on it up to date. */
|
|
18
|
+
readonly dependents: string[];
|
|
19
|
+
/** Places that change it. */
|
|
20
|
+
readonly writes: Write[];
|
|
21
|
+
}
|
|
22
|
+
export interface Write {
|
|
23
|
+
/** Whether it may run before the markup exists: in a function of the body, not in a handler. */
|
|
24
|
+
early: boolean;
|
|
25
|
+
/** A dependent it does not need: `bind:` does not update its own element. */
|
|
26
|
+
skip: number | null;
|
|
27
|
+
}
|
|
28
|
+
/** Everything a change of the source runs: the computations, then the updates of the nodes. */
|
|
29
|
+
export declare function updatesOf(source: Source): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Where the updates of live markup go: the update functions of a component's state, or the update
|
|
32
|
+
* of a block of `{if ...}` / `{for ...}`.
|
|
33
|
+
*/
|
|
34
|
+
export interface Live {
|
|
35
|
+
/** Sources whose values an expression reads. */
|
|
36
|
+
dependencies(node: ast.Node): Set<Source>;
|
|
37
|
+
/** Adds a statement that brings a part of the markup up to date when the sources change. */
|
|
38
|
+
depend(sources: ReadonlySet<Source>, statement: string): void;
|
|
39
|
+
/** The index that the next statement for a source gets, for `bind:` to skip its own update. */
|
|
40
|
+
ownIndex(source: Source): number | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A block of markup control flow: a branch of `{if ...}` or the content for one item of
|
|
44
|
+
* `{for ...}`. It is created again when needed, so its updates go into a function of its own,
|
|
45
|
+
* which runs when any source that the block reads changes.
|
|
46
|
+
*/
|
|
47
|
+
export declare class Block implements Live {
|
|
48
|
+
readonly statements: string[];
|
|
49
|
+
/** Sources that any statement depends on. */
|
|
50
|
+
readonly sources: Set<Source>;
|
|
51
|
+
private readonly parent;
|
|
52
|
+
constructor(parent: Live);
|
|
53
|
+
dependencies(node: ast.Node): Set<Source>;
|
|
54
|
+
depend(sources: ReadonlySet<Source>, statement: string): void;
|
|
55
|
+
ownIndex(): null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The reactivity of one inlined component. The analysis goes by names: a local variable that
|
|
59
|
+
* has the name of a state variable can only cause extra updates, never a missed one.
|
|
60
|
+
*/
|
|
61
|
+
export declare class Reactive implements Live {
|
|
62
|
+
readonly sources: Map<string, Source>;
|
|
63
|
+
/** The function context the body runs in; code in other functions runs later. */
|
|
64
|
+
readonly setup: unknown;
|
|
65
|
+
/** Markup declared at the top level of the body, `const input = <input />`: created once. */
|
|
66
|
+
readonly topLevel: Set<ast.ElementExpression>;
|
|
67
|
+
/** Variables that refer into a source's value: `for todo in todos`, `todos.map(t => ...)`. */
|
|
68
|
+
private readonly aliases;
|
|
69
|
+
/** Local functions: what they read counts where they are mentioned. */
|
|
70
|
+
private readonly functions;
|
|
71
|
+
/** Local functions that the live markup calls: they run while it is created and updated. */
|
|
72
|
+
private readonly renderFunctions;
|
|
73
|
+
constructor(component: ast.ComponentDeclaration, setup: unknown, props: Iterable<string>, createSource: (name: string, kind: Source['kind']) => Source);
|
|
74
|
+
/** Whether a statement of the body declares a function that the live markup calls. */
|
|
75
|
+
declaresRenderFunction(node: ast.Statement): boolean;
|
|
76
|
+
/** Adds a statement that computes a `derived` value again when the sources change. */
|
|
77
|
+
compute(sources: ReadonlySet<Source>, statement: string): void;
|
|
78
|
+
depend(sources: ReadonlySet<Source>, statement: string): void;
|
|
79
|
+
ownIndex(source: Source): number;
|
|
80
|
+
/**
|
|
81
|
+
* Sources whose values an expression reads, directly or through local functions. `read` finds
|
|
82
|
+
* the names that the node itself reads.
|
|
83
|
+
*/
|
|
84
|
+
dependencies(node: ast.Node, read?: typeof readNames): Set<Source>;
|
|
85
|
+
/**
|
|
86
|
+
* `state` variables that a statement (or an expression body) changes: by assignment, `++`,
|
|
87
|
+
* or a method that may change the value, such as `push`. Nested blocks and functions are not
|
|
88
|
+
* included: their statements are handled on their own.
|
|
89
|
+
*/
|
|
90
|
+
writtenBy(node: ast.Node, typeOf: (node: ast.Expression) => Type | undefined): Set<Source>;
|
|
91
|
+
/** Sources whose value `node` refers into: `todos`, `todos[i].tags`, `todos.find(...)`. */
|
|
92
|
+
rootSources(node: ast.Expression): ReadonlySet<Source>;
|
|
93
|
+
/** Repeats until nothing changes, since an alias of an alias is an alias too. */
|
|
94
|
+
private findAliases;
|
|
95
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { wrappedMarkup } from "../decorators.js";
|
|
2
|
+
import { containsReturn, returnedMarkup } from "../recursion.js";
|
|
3
|
+
import { forEachChild } from "../walk.js";
|
|
4
|
+
import { mayChange } from "../methods.js";
|
|
5
|
+
import { readNames, rootName } from "./mutations.js";
|
|
6
|
+
const EMPTY = new Set();
|
|
7
|
+
/** Everything a change of the source runs: the computations, then the updates of the nodes. */
|
|
8
|
+
export function updatesOf(source) {
|
|
9
|
+
return [...source.computations, ...source.dependents];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A block of markup control flow: a branch of `{if ...}` or the content for one item of
|
|
13
|
+
* `{for ...}`. It is created again when needed, so its updates go into a function of its own,
|
|
14
|
+
* which runs when any source that the block reads changes.
|
|
15
|
+
*/
|
|
16
|
+
export class Block {
|
|
17
|
+
statements = [];
|
|
18
|
+
/** Sources that any statement depends on. */
|
|
19
|
+
sources = new Set();
|
|
20
|
+
parent;
|
|
21
|
+
constructor(parent) {
|
|
22
|
+
this.parent = parent;
|
|
23
|
+
}
|
|
24
|
+
dependencies(node) {
|
|
25
|
+
return this.parent.dependencies(node);
|
|
26
|
+
}
|
|
27
|
+
depend(sources, statement) {
|
|
28
|
+
this.statements.push(statement);
|
|
29
|
+
for (const source of sources)
|
|
30
|
+
this.sources.add(source);
|
|
31
|
+
}
|
|
32
|
+
ownIndex() {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The reactivity of one inlined component. The analysis goes by names: a local variable that
|
|
38
|
+
* has the name of a state variable can only cause extra updates, never a missed one.
|
|
39
|
+
*/
|
|
40
|
+
export class Reactive {
|
|
41
|
+
sources = new Map();
|
|
42
|
+
/** The function context the body runs in; code in other functions runs later. */
|
|
43
|
+
setup;
|
|
44
|
+
/** Markup declared at the top level of the body, `const input = <input />`: created once. */
|
|
45
|
+
topLevel = new Set();
|
|
46
|
+
/** Variables that refer into a source's value: `for todo in todos`, `todos.map(t => ...)`. */
|
|
47
|
+
aliases = new Map();
|
|
48
|
+
/** Local functions: what they read counts where they are mentioned. */
|
|
49
|
+
functions = new Map();
|
|
50
|
+
/** Local functions that the live markup calls: they run while it is created and updated. */
|
|
51
|
+
renderFunctions = new Set();
|
|
52
|
+
constructor(component, setup, props, createSource) {
|
|
53
|
+
this.setup = setup;
|
|
54
|
+
for (const name of props)
|
|
55
|
+
this.sources.set(name, createSource(name, 'prop'));
|
|
56
|
+
// Markup declared after an early return may never be created, so it is not updated.
|
|
57
|
+
let returned = false;
|
|
58
|
+
for (const statement of component.body.body) {
|
|
59
|
+
if (statement.kind === 'VariableDeclaration') {
|
|
60
|
+
for (const name of statement.names) {
|
|
61
|
+
if (statement.keyword === 'state' && name.name !== '_') {
|
|
62
|
+
this.sources.set(name.name, createSource(name.name, 'state'));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const [value] = statement.values;
|
|
66
|
+
if (statement.names.length === 1 && value?.kind === 'ElementExpression' && !returned) {
|
|
67
|
+
this.topLevel.add(value);
|
|
68
|
+
}
|
|
69
|
+
if (statement.keyword === 'const' &&
|
|
70
|
+
statement.names.length === 1 &&
|
|
71
|
+
(value?.kind === 'ArrowFunction' || value?.kind === 'FuncExpression')) {
|
|
72
|
+
this.functions.set(statement.names[0].name, value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else if (statement.kind === 'FuncDeclaration') {
|
|
76
|
+
this.functions.set(statement.name.name, statement);
|
|
77
|
+
}
|
|
78
|
+
returned ||= containsReturn(statement);
|
|
79
|
+
}
|
|
80
|
+
this.findAliases(component.body);
|
|
81
|
+
const markup = [
|
|
82
|
+
...this.topLevel,
|
|
83
|
+
...returnedMarkup(component),
|
|
84
|
+
...wrappedMarkup(component),
|
|
85
|
+
];
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
const visit = (node) => {
|
|
88
|
+
const names = new Set();
|
|
89
|
+
readNames(node, names);
|
|
90
|
+
for (const name of names) {
|
|
91
|
+
const fn = this.functions.get(name);
|
|
92
|
+
if (!fn || seen.has(name))
|
|
93
|
+
continue;
|
|
94
|
+
seen.add(name);
|
|
95
|
+
this.renderFunctions.add(fn);
|
|
96
|
+
visit(fn);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
markup.forEach(visit);
|
|
100
|
+
}
|
|
101
|
+
/** Whether a statement of the body declares a function that the live markup calls. */
|
|
102
|
+
declaresRenderFunction(node) {
|
|
103
|
+
if (node.kind === 'FuncDeclaration')
|
|
104
|
+
return this.renderFunctions.has(node);
|
|
105
|
+
const [value] = node.kind === 'VariableDeclaration' ? node.values : [];
|
|
106
|
+
return value !== undefined && this.renderFunctions.has(value);
|
|
107
|
+
}
|
|
108
|
+
/** Adds a statement that computes a `derived` value again when the sources change. */
|
|
109
|
+
compute(sources, statement) {
|
|
110
|
+
for (const source of sources)
|
|
111
|
+
source.computations.push(statement);
|
|
112
|
+
}
|
|
113
|
+
depend(sources, statement) {
|
|
114
|
+
for (const source of sources) {
|
|
115
|
+
if (!source.dependents.includes(statement))
|
|
116
|
+
source.dependents.push(statement);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
ownIndex(source) {
|
|
120
|
+
return source.dependents.length;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Sources whose values an expression reads, directly or through local functions. `read` finds
|
|
124
|
+
* the names that the node itself reads.
|
|
125
|
+
*/
|
|
126
|
+
dependencies(node, read = readNames) {
|
|
127
|
+
const found = new Set();
|
|
128
|
+
const seen = new Set();
|
|
129
|
+
const visit = (node, read) => {
|
|
130
|
+
const names = new Set();
|
|
131
|
+
read(node, names);
|
|
132
|
+
for (const name of names) {
|
|
133
|
+
if (seen.has(name))
|
|
134
|
+
continue;
|
|
135
|
+
seen.add(name);
|
|
136
|
+
const source = this.sources.get(name);
|
|
137
|
+
if (source)
|
|
138
|
+
found.add(source);
|
|
139
|
+
for (const aliased of this.aliases.get(name) ?? EMPTY)
|
|
140
|
+
found.add(aliased);
|
|
141
|
+
const fn = this.functions.get(name);
|
|
142
|
+
if (fn)
|
|
143
|
+
visit(fn, readNames);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
visit(node, read);
|
|
147
|
+
return found;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* `state` variables that a statement (or an expression body) changes: by assignment, `++`,
|
|
151
|
+
* or a method that may change the value, such as `push`. Nested blocks and functions are not
|
|
152
|
+
* included: their statements are handled on their own.
|
|
153
|
+
*/
|
|
154
|
+
writtenBy(node, typeOf) {
|
|
155
|
+
const found = new Set();
|
|
156
|
+
const write = (target) => {
|
|
157
|
+
for (const source of this.rootSources(target)) {
|
|
158
|
+
if (source.kind === 'state')
|
|
159
|
+
found.add(source);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const visit = (node) => {
|
|
163
|
+
switch (node.kind) {
|
|
164
|
+
case 'BlockStatement':
|
|
165
|
+
case 'EventHandler':
|
|
166
|
+
case 'FuncDeclaration':
|
|
167
|
+
case 'FuncExpression':
|
|
168
|
+
case 'ArrowFunction':
|
|
169
|
+
case 'ClassDeclaration':
|
|
170
|
+
return;
|
|
171
|
+
case 'SwitchCase':
|
|
172
|
+
node.tests.forEach(visit);
|
|
173
|
+
return;
|
|
174
|
+
case 'AssignmentStatement':
|
|
175
|
+
node.targets.forEach(write);
|
|
176
|
+
break;
|
|
177
|
+
case 'IncDecStatement':
|
|
178
|
+
case 'DeleteStatement':
|
|
179
|
+
write(node.target);
|
|
180
|
+
break;
|
|
181
|
+
case 'CallExpression': {
|
|
182
|
+
const { callee } = node;
|
|
183
|
+
if (callee.kind === 'MemberExpression' &&
|
|
184
|
+
mayChange(typeOf(callee.object), callee.property.name)) {
|
|
185
|
+
write(callee.object);
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
forEachChild(node, visit);
|
|
193
|
+
};
|
|
194
|
+
visit(node);
|
|
195
|
+
return found;
|
|
196
|
+
}
|
|
197
|
+
/** Sources whose value `node` refers into: `todos`, `todos[i].tags`, `todos.find(...)`. */
|
|
198
|
+
rootSources(node) {
|
|
199
|
+
const name = rootName(node);
|
|
200
|
+
if (name === null)
|
|
201
|
+
return EMPTY;
|
|
202
|
+
const source = this.sources.get(name);
|
|
203
|
+
return source ? new Set([source]) : (this.aliases.get(name) ?? EMPTY);
|
|
204
|
+
}
|
|
205
|
+
/** Repeats until nothing changes, since an alias of an alias is an alias too. */
|
|
206
|
+
findAliases(body) {
|
|
207
|
+
let changed = true;
|
|
208
|
+
const add = (name, sources) => {
|
|
209
|
+
if (name === '_' || this.sources.has(name))
|
|
210
|
+
return;
|
|
211
|
+
let set = this.aliases.get(name);
|
|
212
|
+
for (const source of sources) {
|
|
213
|
+
if (set?.has(source))
|
|
214
|
+
continue;
|
|
215
|
+
set ??= new Set();
|
|
216
|
+
set.add(source);
|
|
217
|
+
this.aliases.set(name, set);
|
|
218
|
+
changed = true;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
// In markup, a loop index and a `const` change with what they are computed from.
|
|
222
|
+
let inMarkup = false;
|
|
223
|
+
const visit = (node) => {
|
|
224
|
+
switch (node.kind) {
|
|
225
|
+
case 'JsxStatementContainer': {
|
|
226
|
+
const saved = inMarkup;
|
|
227
|
+
inMarkup = true;
|
|
228
|
+
visit(node.statement);
|
|
229
|
+
inMarkup = saved;
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
case 'FuncExpression':
|
|
233
|
+
case 'ArrowFunction': {
|
|
234
|
+
const saved = inMarkup;
|
|
235
|
+
inMarkup = false;
|
|
236
|
+
forEachChild(node, visit);
|
|
237
|
+
inMarkup = saved;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
case 'ForInStatement':
|
|
241
|
+
add(node.value.name, this.rootSources(node.iterable));
|
|
242
|
+
if (node.key && inMarkup)
|
|
243
|
+
add(node.key.name, this.dependencies(node.iterable));
|
|
244
|
+
break;
|
|
245
|
+
case 'VariableDeclaration':
|
|
246
|
+
node.names.forEach((name, i) => {
|
|
247
|
+
const value = node.values.length === node.names.length ? node.values[i] : node.values[0];
|
|
248
|
+
if (!value)
|
|
249
|
+
return;
|
|
250
|
+
add(name.name, this.rootSources(value));
|
|
251
|
+
// A derived value changes with all it is computed from.
|
|
252
|
+
if (inMarkup || node.keyword === 'derived')
|
|
253
|
+
add(name.name, this.dependencies(value));
|
|
254
|
+
});
|
|
255
|
+
break;
|
|
256
|
+
case 'CallExpression': {
|
|
257
|
+
if (node.callee.kind !== 'MemberExpression')
|
|
258
|
+
break;
|
|
259
|
+
const sources = this.rootSources(node.callee.object);
|
|
260
|
+
if (sources.size === 0)
|
|
261
|
+
break;
|
|
262
|
+
for (const arg of node.arguments) {
|
|
263
|
+
if (arg.kind === 'ArrowFunction' || arg.kind === 'FuncExpression') {
|
|
264
|
+
for (const param of arg.params)
|
|
265
|
+
add(param.name.name, sources);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
default:
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
forEachChild(node, visit);
|
|
274
|
+
};
|
|
275
|
+
while (changed) {
|
|
276
|
+
changed = false;
|
|
277
|
+
visit(body);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type * as ast from '../ast.ts';
|
|
2
|
+
import { EarlyReturnEmitter } from './early-returns.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Refs: `ref input` creates the element of `<input ref={input} />` where it is declared, with its
|
|
5
|
+
* constant attributes, and the markup fills that element in instead of creating one.
|
|
6
|
+
*
|
|
7
|
+
* `<Card ref={card} />` creates the element at the top of what `Card` returns. An inlined `Card`
|
|
8
|
+
* fills it in under a name of its own, `$$root4`, since its own names may hide `card`; the
|
|
9
|
+
* function of `Card` gets it as its last argument, `$$root`, which is undefined without a ref.
|
|
10
|
+
*/
|
|
11
|
+
/** The element at the top of the markup of the component being written, created by a ref. */
|
|
12
|
+
export interface RootPreset {
|
|
13
|
+
/** The element, or the use of a component, at the top of the component's own markup. */
|
|
14
|
+
node: ast.ElementExpression;
|
|
15
|
+
/** The variable with the element. */
|
|
16
|
+
name: string;
|
|
17
|
+
/** False for `$$root` of a function: the element is created when the caller gave none. */
|
|
18
|
+
created: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare abstract class RefEmitter extends EarlyReturnEmitter {
|
|
21
|
+
/** The elements that the refs of the component being written are bound to. */
|
|
22
|
+
private refElements;
|
|
23
|
+
/** Those of them that are SVG elements. */
|
|
24
|
+
private svgTargets;
|
|
25
|
+
private rootPreset;
|
|
26
|
+
/** Tags of components that refs point to or that are at the top of components: lazily. */
|
|
27
|
+
private rootTags;
|
|
28
|
+
/** Writes the code of a component: its refs, and the element at its top if a ref created it. */
|
|
29
|
+
protected withRefs<T>(component: ast.ComponentDeclaration, preset: RootPreset | null, emit: () => T): T;
|
|
30
|
+
/** `ref input`: `const input = document.createElement("input");` and its constant attributes. */
|
|
31
|
+
protected refDeclaration(node: ast.VariableDeclaration): void;
|
|
32
|
+
/**
|
|
33
|
+
* The element that markup fills in instead of creating one: that of its ref, which has its
|
|
34
|
+
* constant attributes already, or the one a ref to the component created.
|
|
35
|
+
*/
|
|
36
|
+
protected presetElement(node: ast.ElementExpression): {
|
|
37
|
+
name: string;
|
|
38
|
+
created: boolean;
|
|
39
|
+
} | null;
|
|
40
|
+
/**
|
|
41
|
+
* What a use of a component gives it as the element at its top: the element of a ref on the use,
|
|
42
|
+
* or the one given to the component being written, when the use is at its top.
|
|
43
|
+
*/
|
|
44
|
+
protected rootFor(use: ast.ElementExpression): {
|
|
45
|
+
name: string;
|
|
46
|
+
created: boolean;
|
|
47
|
+
} | null;
|
|
48
|
+
/** The preset of an inlined component, whose names may hide the variable with the element. */
|
|
49
|
+
protected inlineRoot(component: ast.ComponentDeclaration, given: {
|
|
50
|
+
name: string;
|
|
51
|
+
created: boolean;
|
|
52
|
+
} | null): RootPreset | null;
|
|
53
|
+
/**
|
|
54
|
+
* Whether the function of a component takes `$$root`: when the element at its top is known, and
|
|
55
|
+
* a ref may point to it, here or in another module, or a component that does returns it.
|
|
56
|
+
*/
|
|
57
|
+
protected takesRoot(component: ast.ComponentDeclaration): boolean;
|
|
58
|
+
private findRootTags;
|
|
59
|
+
/** The element that markup creates: itself, or the one at the top of the component it uses. */
|
|
60
|
+
private elementOf;
|
|
61
|
+
private componentRootOf;
|
|
62
|
+
}
|