rooklang 0.3.3 → 0.3.4
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 +32 -7
- package/README.ru.md +32 -7
- package/dist/ast/declarations.d.ts +20 -1
- package/dist/ast/expressions.d.ts +31 -1
- package/dist/ast/markup.d.ts +6 -1
- package/dist/ast/statements.d.ts +25 -1
- package/dist/auto-import.d.ts +11 -0
- package/dist/auto-import.js +81 -0
- package/dist/breaks.d.ts +6 -0
- package/dist/breaks.js +36 -0
- package/dist/build.d.ts +7 -0
- package/dist/build.js +23 -2
- package/dist/checker/array-literals.d.ts +6 -0
- package/dist/checker/array-literals.js +59 -0
- package/dist/checker/assignments.d.ts +2 -0
- package/dist/checker/assignments.js +14 -0
- package/dist/checker/base.js +6 -6
- package/dist/checker/builtins.js +15 -5
- package/dist/checker/bytes.d.ts +2 -2
- package/dist/checker/bytes.js +2 -2
- package/dist/checker/calls.js +3 -0
- package/dist/checker/channel-objects.d.ts +3 -0
- package/dist/checker/channel-objects.js +40 -0
- package/dist/checker/channels.d.ts +1 -0
- package/dist/checker/channels.js +16 -2
- package/dist/checker/checker.d.ts +1 -1
- package/dist/checker/checker.js +19 -0
- package/dist/checker/class-members.d.ts +22 -0
- package/dist/checker/class-members.js +105 -0
- package/dist/checker/classes.d.ts +5 -4
- package/dist/checker/classes.js +41 -12
- package/dist/checker/closing.d.ts +21 -0
- package/dist/checker/closing.js +164 -0
- package/dist/checker/completion.d.ts +2 -2
- package/dist/checker/completion.js +2 -2
- package/dist/checker/context.d.ts +13 -0
- package/dist/checker/control-flow.d.ts +5 -0
- package/dist/checker/control-flow.js +17 -0
- package/dist/checker/declarations.js +1 -0
- package/dist/checker/decode.d.ts +8 -0
- package/dist/checker/decode.js +32 -0
- package/dist/checker/expressions.d.ts +5 -1
- package/dist/checker/expressions.js +13 -34
- package/dist/checker/flow.js +8 -4
- package/dist/checker/helpers.d.ts +1 -1
- package/dist/checker/helpers.js +9 -2
- package/dist/checker/iterables.d.ts +3 -1
- package/dist/checker/iterables.js +13 -0
- package/dist/checker/iterators.d.ts +4 -1
- package/dist/checker/iterators.js +12 -4
- package/dist/checker/json.d.ts +5 -0
- package/dist/checker/json.js +92 -0
- package/dist/checker/loops.js +23 -3
- package/dist/checker/members.js +7 -0
- package/dist/checker/operators.d.ts +2 -2
- package/dist/checker/operators.js +7 -5
- package/dist/checker/queues.d.ts +2 -2
- package/dist/checker/queues.js +2 -2
- package/dist/checker/resolution.js +5 -3
- package/dist/checker/signals.d.ts +8 -0
- package/dist/checker/signals.js +48 -0
- package/dist/checker/topics.d.ts +6 -0
- package/dist/checker/topics.js +17 -0
- package/dist/checker/transfer.d.ts +3 -1
- package/dist/checker/transfer.js +25 -5
- package/dist/checker/try.d.ts +6 -0
- package/dist/checker/try.js +19 -0
- package/dist/checker/types/constructors.d.ts +1 -1
- package/dist/checker/types/constructors.js +2 -2
- package/dist/checker/types/generics.js +1 -1
- package/dist/checker/types/iterables.d.ts +13 -0
- package/dist/checker/types/iterables.js +52 -0
- package/dist/checker/types/model.d.ts +25 -0
- package/dist/checker/types/params.js +22 -3
- package/dist/checker/types/printing.js +4 -3
- package/dist/checker/types/relations.js +19 -25
- package/dist/checker/types/topic.d.ts +6 -0
- package/dist/checker/types/topic.js +23 -0
- package/dist/checker/types.d.ts +2 -0
- package/dist/checker/types.js +2 -0
- package/dist/cli.js +18 -36
- package/dist/codegen/calls.d.ts +23 -0
- package/dist/codegen/calls.js +88 -7
- package/dist/codegen/control-statements.d.ts +10 -2
- package/dist/codegen/control-statements.js +56 -19
- package/dist/codegen/decode.d.ts +14 -0
- package/dist/codegen/decode.js +93 -0
- package/dist/codegen/emitter.d.ts +10 -41
- package/dist/codegen/emitter.js +9 -4
- package/dist/codegen/expressions.d.ts +9 -0
- package/dist/codegen/expressions.js +15 -24
- package/dist/codegen/js.d.ts +2 -2
- package/dist/codegen/js.js +5 -2
- package/dist/codegen/options.d.ts +40 -0
- package/dist/codegen/options.js +1 -0
- package/dist/codegen/runtime.d.ts +7 -3
- package/dist/codegen/runtime.js +27 -13
- package/dist/codegen/simple-statements.d.ts +10 -4
- package/dist/codegen/simple-statements.js +40 -15
- package/dist/codegen/statements.js +64 -4
- package/dist/codegen/try.d.ts +5 -0
- package/dist/codegen/try.js +40 -0
- package/dist/compile.d.ts +9 -0
- package/dist/compile.js +19 -6
- package/dist/completion.d.ts +4 -2
- package/dist/completion.js +10 -5
- package/dist/declarations.js +32 -6
- package/dist/decorator-copy.js +5 -2
- package/dist/goroutines.d.ts +1 -1
- package/dist/goroutines.js +5 -4
- package/dist/index.d.ts +6 -2
- package/dist/index.js +14 -5
- package/dist/lexer/base.d.ts +2 -0
- package/dist/lexer/base.js +6 -1
- package/dist/lexer/lexer.js +3 -0
- package/dist/lexer/literals.d.ts +5 -0
- package/dist/lexer/literals.js +51 -1
- package/dist/lexer/markup.js +3 -4
- package/dist/lexer/tables.js +2 -0
- package/dist/lexer/token.d.ts +4 -3
- package/dist/lexer/token.js +0 -2
- package/dist/loader.js +30 -8
- package/dist/parser/base.d.ts +4 -0
- package/dist/parser/base.js +2 -1
- package/dist/parser/classes.d.ts +2 -0
- package/dist/parser/classes.js +88 -23
- package/dist/parser/control-flow.d.ts +3 -1
- package/dist/parser/control-flow.js +21 -24
- package/dist/parser/declarations.d.ts +7 -4
- package/dist/parser/declarations.js +45 -6
- package/dist/parser/expressions.js +27 -3
- package/dist/parser/jumps.d.ts +11 -0
- package/dist/parser/jumps.js +77 -0
- package/dist/parser/literals.d.ts +9 -0
- package/dist/parser/literals.js +45 -6
- package/dist/parser/markup.js +1 -1
- package/dist/parser/simple-statements.d.ts +1 -1
- package/dist/parser/simple-statements.js +16 -9
- package/dist/parser/statements.d.ts +0 -3
- package/dist/parser/statements.js +22 -25
- package/dist/parser/syntax.d.ts +11 -1
- package/dist/parser/syntax.js +16 -2
- package/dist/parser/types.js +8 -3
- package/dist/project-modules.d.ts +12 -0
- package/dist/project-modules.js +106 -0
- package/dist/run-file.d.ts +6 -0
- package/dist/run-file.js +111 -0
- package/dist/runtime/sources.js +11 -5
- package/dist/source-map.d.ts +17 -0
- package/dist/source-map.js +75 -0
- package/dist/ts-types.js +4 -1
- package/dist/typescript/convert-objects.d.ts +2 -1
- package/dist/typescript/convert-objects.js +18 -9
- package/dist/vite.js +12 -4
- package/dist/walk-types.js +1 -0
- package/dist/walk.d.ts +0 -2
- package/dist/walk.js +11 -28
- package/package.json +1 -1
- package/src/runtime/chan.js +15 -5
- package/src/runtime/channel.js +28 -0
- package/src/runtime/classes.js +32 -0
- package/src/runtime/core.js +10 -1
- package/src/runtime/decode.js +190 -0
- package/src/runtime/go.js +3 -0
- package/src/runtime/index.js +6 -0
- package/src/runtime/select.js +14 -9
- package/src/runtime/signals.js +59 -0
- package/src/runtime/threads.js +32 -5
- package/src/runtime/topic.js +118 -0
- package/src/runtime/try.js +45 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type * as ast from '../ast.ts';
|
|
2
|
-
import {
|
|
2
|
+
import { TryEmitter } from './try.ts';
|
|
3
3
|
/** Statements: lists and blocks of them, variables, assignments, `return`; the others are in later layers. */
|
|
4
|
-
export declare abstract class SimpleStatementEmitter extends
|
|
4
|
+
export declare abstract class SimpleStatementEmitter extends TryEmitter {
|
|
5
5
|
protected abstract forInStatement(node: ast.ForInStatement): void;
|
|
6
6
|
protected abstract selectStatement(node: ast.SelectStatement): void;
|
|
7
7
|
protected abstract forStatement(node: ast.ForStatement): void;
|
|
8
8
|
protected abstract ifStatement(node: ast.IfStatement): string;
|
|
9
|
-
protected abstract switchStatement(node: ast.SwitchStatement
|
|
10
|
-
protected abstract taglessSwitch(node: ast.SwitchStatement): void;
|
|
9
|
+
protected abstract switchStatement(node: ast.SwitchStatement): void;
|
|
11
10
|
protected abstract tryStatement(node: ast.TryStatement): string;
|
|
12
11
|
protected abstract classDeclaration(node: ast.ClassDeclaration): void;
|
|
13
12
|
protected abstract importDeclaration(node: ast.ImportDeclaration): void;
|
|
@@ -29,7 +28,14 @@ export declare abstract class SimpleStatementEmitter extends CallEmitter {
|
|
|
29
28
|
/** A block's statements in a new scope, without the braces; `then` writes more code in it. */
|
|
30
29
|
protected blockStatements(statements: readonly ast.Statement[], then?: () => void): void;
|
|
31
30
|
protected blockStatement(node: ast.BlockStatement): string;
|
|
31
|
+
/**
|
|
32
|
+
* The start of the statement being written, which its first line gets as a mark for the source
|
|
33
|
+
* map (source-map.ts). Imports have none, since the import of the runtime goes among them, and
|
|
34
|
+
* neither does the code of other modules, whose places are in their own sources.
|
|
35
|
+
*/
|
|
36
|
+
private sourceMark;
|
|
32
37
|
protected statement(node: ast.Statement): void;
|
|
38
|
+
protected line(text: string): void;
|
|
33
39
|
protected emitStatement(node: ast.Statement): void;
|
|
34
40
|
/** `let a, b = 1, 2` → `let a = 1, b = 2`; `const q, err = f()` → `const [q, err] = f()`. */
|
|
35
41
|
protected variableDeclaration(node: ast.VariableDeclaration): string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { isIterator } from "../iterators.js";
|
|
2
|
+
import { sourceMark } from "../source-map.js";
|
|
2
3
|
import { holdsBigInts, TYPED_ARRAYS, TYPED_ELEMENTS } from "../typed-arrays.js";
|
|
3
4
|
import { declarationsOf } from "./analysis.js";
|
|
4
|
-
import {
|
|
5
|
+
import { TryEmitter } from "./try.js";
|
|
5
6
|
import { ARROW, arrayPattern, POSTFIX } from "./syntax.js";
|
|
6
7
|
/** Statements: lists and blocks of them, variables, assignments, `return`; the others are in later layers. */
|
|
7
|
-
export class SimpleStatementEmitter extends
|
|
8
|
+
export class SimpleStatementEmitter extends TryEmitter {
|
|
8
9
|
/** Counter for the labels of switches compiled to if/else. */
|
|
9
10
|
labels = 0;
|
|
10
11
|
statements(list) {
|
|
@@ -34,8 +35,34 @@ export class SimpleStatementEmitter extends CallEmitter {
|
|
|
34
35
|
blockStatement(node) {
|
|
35
36
|
return this.block(() => this.blockStatements(node.body));
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The start of the statement being written, which its first line gets as a mark for the source
|
|
40
|
+
* map (source-map.ts). Imports have none, since the import of the runtime goes among them, and
|
|
41
|
+
* neither does the code of other modules, whose places are in their own sources.
|
|
42
|
+
*/
|
|
43
|
+
sourceMark = null;
|
|
37
44
|
statement(node) {
|
|
38
|
-
|
|
45
|
+
// A statement may write the statements inside it first, as a function writes its body before
|
|
46
|
+
// its first line: then the mark waits for that line.
|
|
47
|
+
const outer = this.sourceMark;
|
|
48
|
+
this.sourceMark =
|
|
49
|
+
node.kind === 'ImportDeclaration' || this.foreign.has(node) ? null : node.start;
|
|
50
|
+
try {
|
|
51
|
+
this.withHoisting(true, () => this.emitStatement(node));
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
this.sourceMark = outer;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// The marks of the updates of components stand alone in their lines (updates.ts).
|
|
58
|
+
line(text) {
|
|
59
|
+
if (this.sourceMark === null || text.startsWith('\uE000')) {
|
|
60
|
+
super.line(text);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const mark = sourceMark(this.sourceMark);
|
|
64
|
+
this.sourceMark = null;
|
|
65
|
+
super.line(mark + text);
|
|
39
66
|
}
|
|
40
67
|
emitStatement(node) {
|
|
41
68
|
switch (node.kind) {
|
|
@@ -115,18 +142,15 @@ export class SimpleStatementEmitter extends CallEmitter {
|
|
|
115
142
|
this.selectStatement(node);
|
|
116
143
|
break;
|
|
117
144
|
case 'SwitchStatement':
|
|
118
|
-
|
|
119
|
-
this.taglessSwitch(node);
|
|
120
|
-
else
|
|
121
|
-
this.switchStatement(node, node.discriminant);
|
|
145
|
+
this.switchStatement(node);
|
|
122
146
|
break;
|
|
123
147
|
case 'BreakStatement': {
|
|
124
|
-
const label = this.fn.breakTargets.at(-1);
|
|
148
|
+
const label = node.label ? this.label(node.label) : this.fn.breakTargets.at(-1);
|
|
125
149
|
this.line(label ? `break ${label};` : 'break;');
|
|
126
150
|
break;
|
|
127
151
|
}
|
|
128
152
|
case 'ContinueStatement':
|
|
129
|
-
this.line('continue;');
|
|
153
|
+
this.line(node.label ? `continue ${this.label(node.label)};` : 'continue;');
|
|
130
154
|
break;
|
|
131
155
|
case 'ThrowStatement':
|
|
132
156
|
this.line(`throw ${this.expression(node.argument, 0)};`);
|
|
@@ -137,12 +161,9 @@ export class SimpleStatementEmitter extends CallEmitter {
|
|
|
137
161
|
case 'DeferStatement':
|
|
138
162
|
this.deferStatement(node);
|
|
139
163
|
break;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const channel = this.expression(node.channel, ARROW);
|
|
143
|
-
this.line(`await $$send(${channel}, ${this.expression(node.value, ARROW)});`);
|
|
164
|
+
case 'SendStatement':
|
|
165
|
+
this.line(`${this.send(node)};`);
|
|
144
166
|
break;
|
|
145
|
-
}
|
|
146
167
|
case 'MountStatement':
|
|
147
168
|
this.mountStatement(node);
|
|
148
169
|
break;
|
|
@@ -192,9 +213,13 @@ export class SimpleStatementEmitter extends CallEmitter {
|
|
|
192
213
|
// An empty queue, as `[]` is an empty array.
|
|
193
214
|
case 'QueueType':
|
|
194
215
|
return 'new $$Queue()';
|
|
216
|
+
// Closed, the same for all types: what is sent to them goes nowhere.
|
|
217
|
+
case 'ChanType':
|
|
218
|
+
return '$$Channel.EMPTY';
|
|
219
|
+
case 'TopicType':
|
|
220
|
+
return '$$Topic.EMPTY';
|
|
195
221
|
case 'FuncType':
|
|
196
222
|
case 'ComponentType':
|
|
197
|
-
case 'ChanType':
|
|
198
223
|
case 'ObjectType':
|
|
199
224
|
case 'UnionType':
|
|
200
225
|
case 'LiteralType':
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSuperCall } from "../checker/helpers.js";
|
|
1
2
|
import { isIterator } from "../iterators.js";
|
|
2
3
|
import { decoratedName, moduleNamesOf } from "../decorators.js";
|
|
3
4
|
import { inlinePackages } from "../inline-packages.js";
|
|
@@ -16,7 +17,9 @@ export class StatementEmitter extends ParallelLoopEmitter {
|
|
|
16
17
|
return;
|
|
17
18
|
// Imports used only as types (e.g. interfaces) do not exist at runtime, and neither do
|
|
18
19
|
// components: a component used as a value is its function, imported below.
|
|
19
|
-
|
|
20
|
+
// A data class, even used only as a type, registers itself where it is imported.
|
|
21
|
+
const used = (name) => (this.valueNames.has(name.name) || this.options.dataClasses?.has(name.name) === true) &&
|
|
22
|
+
!this.options.components?.has(name.name);
|
|
20
23
|
const clauses = [];
|
|
21
24
|
if (node.defaultImport && used(node.defaultImport)) {
|
|
22
25
|
clauses.push(this.name(node.defaultImport.name));
|
|
@@ -100,7 +103,10 @@ export class StatementEmitter extends ParallelLoopEmitter {
|
|
|
100
103
|
: '';
|
|
101
104
|
const body = this.block(() => {
|
|
102
105
|
let previous;
|
|
106
|
+
// An abstract method has no code: only the subclasses have it.
|
|
103
107
|
for (const member of node.members) {
|
|
108
|
+
if (member.kind === 'MethodDeclaration' && member.abstract)
|
|
109
|
+
continue;
|
|
104
110
|
const bothFields = previous?.kind === 'FieldDeclaration' && member.kind === 'FieldDeclaration';
|
|
105
111
|
if (previous && (!bothFields || this.blankLineBetween(previous, member)))
|
|
106
112
|
this.blankLine();
|
|
@@ -109,6 +115,12 @@ export class StatementEmitter extends ParallelLoopEmitter {
|
|
|
109
115
|
}
|
|
110
116
|
});
|
|
111
117
|
this.line(`${exported}class ${this.name(node.name.name)}${superClass} ${body}`);
|
|
118
|
+
// A data class is registered, so that its instances get it back in another thread
|
|
119
|
+
// (runtime/classes.js); the id is the same in the worker module, which has a copy of it.
|
|
120
|
+
if (node.data) {
|
|
121
|
+
const id = `${node.name.name}:${hash(this.options.source.slice(node.start, node.end))}`;
|
|
122
|
+
this.line(`$$dataClass(${this.name(node.name.name)}, ${JSON.stringify(id)});`);
|
|
123
|
+
}
|
|
112
124
|
}
|
|
113
125
|
/** Visibility modifiers are checked by the compiler and do not exist in the output. */
|
|
114
126
|
classMember(member) {
|
|
@@ -126,17 +138,65 @@ export class StatementEmitter extends ParallelLoopEmitter {
|
|
|
126
138
|
break;
|
|
127
139
|
}
|
|
128
140
|
case 'ConstructorDeclaration': {
|
|
129
|
-
const [params, body] = this.func(member.params, member
|
|
141
|
+
const [params, body] = this.func(member.params, assignProperties(member));
|
|
130
142
|
this.line(`constructor(${params}) ${body}`);
|
|
131
143
|
break;
|
|
132
144
|
}
|
|
133
145
|
case 'MethodDeclaration': {
|
|
146
|
+
if (!member.body)
|
|
147
|
+
break;
|
|
134
148
|
const [params, body] = this.func(member.params, member.body);
|
|
135
|
-
const modifiers = `${member.isStatic ? 'static ' : ''}${member.async ? 'async ' : ''}
|
|
136
|
-
|
|
149
|
+
const modifiers = `${member.isStatic ? 'static ' : ''}${member.async ? 'async ' : ''}` +
|
|
150
|
+
(member.accessor ? `${member.accessor} ` : '');
|
|
151
|
+
const star = isIterator(member.params) && !member.accessor ? '*' : '';
|
|
137
152
|
this.line(`${modifiers}${star}${member.name.name}(${params}) ${body}`);
|
|
138
153
|
break;
|
|
139
154
|
}
|
|
140
155
|
}
|
|
141
156
|
}
|
|
142
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* The body of a constructor whose parameters are properties, `constructor(private name string)`:
|
|
160
|
+
* it assigns them first, `this.name = name`, or right after `super(...)` in a derived class.
|
|
161
|
+
*/
|
|
162
|
+
function assignProperties(node) {
|
|
163
|
+
const assignments = node.params.flatMap((param) => {
|
|
164
|
+
if (!param.property)
|
|
165
|
+
return [];
|
|
166
|
+
const at = { start: param.start, end: param.end };
|
|
167
|
+
const self = { kind: 'ThisExpression', ...at };
|
|
168
|
+
const target = {
|
|
169
|
+
kind: 'MemberExpression',
|
|
170
|
+
object: self,
|
|
171
|
+
property: param.name,
|
|
172
|
+
optional: false,
|
|
173
|
+
...at,
|
|
174
|
+
};
|
|
175
|
+
return [
|
|
176
|
+
{
|
|
177
|
+
kind: 'AssignmentStatement',
|
|
178
|
+
operator: '=',
|
|
179
|
+
targets: [target],
|
|
180
|
+
values: [param.name],
|
|
181
|
+
...at,
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
});
|
|
185
|
+
if (assignments.length === 0)
|
|
186
|
+
return node.body;
|
|
187
|
+
const statements = node.body.body;
|
|
188
|
+
const after = statements.findIndex(isSuperCall) + 1;
|
|
189
|
+
return {
|
|
190
|
+
...node.body,
|
|
191
|
+
body: [...statements.slice(0, after), ...assignments, ...statements.slice(after)],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** FNV-1a of a text, as 8 hex digits: an id that changes only with the text. */
|
|
195
|
+
function hash(text) {
|
|
196
|
+
let value = 0x811c9dc5;
|
|
197
|
+
for (let i = 0; i < text.length; i++) {
|
|
198
|
+
value ^= text.charCodeAt(i);
|
|
199
|
+
value = Math.imul(value, 0x01000193) >>> 0;
|
|
200
|
+
}
|
|
201
|
+
return value.toString(16).padStart(8, '0');
|
|
202
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isErrorType } from "../checker/error-results.js";
|
|
2
|
+
import { forEachChild } from "../walk.js";
|
|
3
|
+
import { startsWithObjectLiteral } from "./analysis.js";
|
|
4
|
+
import { DecodeEmitter } from "./decode.js";
|
|
5
|
+
import { ARROW, POSTFIX, UNARY } from "./syntax.js";
|
|
6
|
+
// `try expr`: the expression runs in a function that the runtime calls inside try/catch
|
|
7
|
+
// (runtime/try.js), `$$catch(() => JSON.parse(text))`. One that waits is an async function, whose
|
|
8
|
+
// rejected Promise is caught as well: `await $$catchAsync(async () => await fetch(url))`. The runtime
|
|
9
|
+
// is told how many values the expression gives, and whether the last of them is an error already.
|
|
10
|
+
export class TryEmitter extends DecodeEmitter {
|
|
11
|
+
tryValue(node) {
|
|
12
|
+
// The expression may not run to the end, so it creates no elements in advance.
|
|
13
|
+
const code = this.withHoisting(false, () => this.expression(node.argument, ARROW));
|
|
14
|
+
const body = startsWithObjectLiteral(node.argument) ? `(${code})` : code;
|
|
15
|
+
const type = this.options.types?.get(node.argument);
|
|
16
|
+
let results = '';
|
|
17
|
+
if (type?.kind === 'void' || (type !== undefined && isErrorType(type))) {
|
|
18
|
+
results = type.kind === 'void' ? ', 0' : ', 1, true';
|
|
19
|
+
}
|
|
20
|
+
else if (type?.kind === 'tuple') {
|
|
21
|
+
results = `, ${type.types.length}${isErrorType(type.types.at(-1)) ? ', true' : ''}`;
|
|
22
|
+
}
|
|
23
|
+
return waits(node.argument)
|
|
24
|
+
? [`await $$catchAsync(async () => ${body}${results})`, UNARY]
|
|
25
|
+
: [`$$catch(() => ${body}${results})`, POSTFIX];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Whether the expression waits, with `await` or `<-`, outside the functions in it. */
|
|
29
|
+
function waits(node) {
|
|
30
|
+
if (node.kind === 'UnaryExpression' && (node.operator === 'await' || node.operator === '<-')) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (node.kind === 'FuncExpression' || node.kind === 'ArrowFunction')
|
|
34
|
+
return false;
|
|
35
|
+
let found = false;
|
|
36
|
+
forEachChild(node, (child) => {
|
|
37
|
+
found ||= waits(child);
|
|
38
|
+
});
|
|
39
|
+
return found;
|
|
40
|
+
}
|
package/dist/compile.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type * as ast from './ast.ts';
|
|
|
2
2
|
import { type CheckOptions, type ImportResult, type Library } from './checker/checker.ts';
|
|
3
3
|
import type { RuntimeMode } from './codegen/runtime.ts';
|
|
4
4
|
import type { Diagnostic } from './diagnostics.ts';
|
|
5
|
+
import { type SourceMap } from './source-map.ts';
|
|
5
6
|
import { type StyleModule } from './style-modules.ts';
|
|
6
7
|
export interface CoreCompileOptions {
|
|
7
8
|
/** Replace `.rk` with `.js` in relative import paths. Defaults to `true`. */
|
|
@@ -22,12 +23,16 @@ export interface CoreCompileOptions {
|
|
|
22
23
|
readStyleModule?: ((specifier: string) => string | null) | undefined;
|
|
23
24
|
/** Where the worker module of `go` is, relative to the module; see workerUrl(). */
|
|
24
25
|
workerUrl?: string | undefined;
|
|
26
|
+
/** A module that a worker thread of Node imports first, to load `.rk` files (vite.ts). */
|
|
27
|
+
nodeLoader?: string | undefined;
|
|
25
28
|
/**
|
|
26
29
|
* How the code gets the runtime of Rook: `import`, the default, imports it from
|
|
27
30
|
* "rooklang/runtime"; `inline` puts the parts it uses into the module, for code that runs
|
|
28
31
|
* without imports (src/codegen/runtime.ts).
|
|
29
32
|
*/
|
|
30
33
|
runtime?: RuntimeMode | undefined;
|
|
34
|
+
/** The name of the source in the source maps, `app.rk`. */
|
|
35
|
+
sourceName?: string | undefined;
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
38
|
* Where the worker module of a module is: a `.worker.js` next to its `.js`, or, where `.rk`
|
|
@@ -45,6 +50,10 @@ export interface CompileResult {
|
|
|
45
50
|
dependencies: string[];
|
|
46
51
|
/** The `.d.ts` for the module, with the `declarations` option. */
|
|
47
52
|
declarations?: string;
|
|
53
|
+
/** Where the lines of `code` come from in the source, when there is code. */
|
|
54
|
+
map?: SourceMap;
|
|
55
|
+
/** That of the worker module. */
|
|
56
|
+
workerMap?: SourceMap;
|
|
48
57
|
/** The worker module that runs the functions `go` calls, when the module has `go`. */
|
|
49
58
|
worker?: string;
|
|
50
59
|
}
|
package/dist/compile.js
CHANGED
|
@@ -3,6 +3,7 @@ import { property, STRING } from "./checker/types.js";
|
|
|
3
3
|
import { generateJs } from "./codegen/js.js";
|
|
4
4
|
import { printDeclarations } from "./declarations.js";
|
|
5
5
|
import { goroutines, goTarget, workerProgram } from "./goroutines.js";
|
|
6
|
+
import { withoutMarks } from "./source-map.js";
|
|
6
7
|
import { parse } from "./parser/parser.js";
|
|
7
8
|
import { isStyleModule, styleModule, unusedClasses } from "./style-modules.js";
|
|
8
9
|
/**
|
|
@@ -24,6 +25,8 @@ export function compileModule(source, options = {}) {
|
|
|
24
25
|
return { code: '', diagnostics: problems, warnings: [], dependencies };
|
|
25
26
|
let types;
|
|
26
27
|
let declarations;
|
|
28
|
+
// Without the checker, only the data classes that the module declares are known.
|
|
29
|
+
let dataClasses = new Set(program.body.flatMap((each) => each.kind === 'ClassDeclaration' && each.data ? [each.name.name] : []));
|
|
27
30
|
let warnings = [];
|
|
28
31
|
if (options.typeCheck ?? true) {
|
|
29
32
|
const checked = check(program, checkOptions);
|
|
@@ -32,6 +35,7 @@ export function compileModule(source, options = {}) {
|
|
|
32
35
|
return { code: '', diagnostics: checked.diagnostics, warnings, dependencies };
|
|
33
36
|
}
|
|
34
37
|
types = checked.types;
|
|
38
|
+
dataClasses = checked.dataClasses;
|
|
35
39
|
if (options.declarations)
|
|
36
40
|
declarations = printDeclarations(program, checked);
|
|
37
41
|
}
|
|
@@ -42,25 +46,34 @@ export function compileModule(source, options = {}) {
|
|
|
42
46
|
types,
|
|
43
47
|
styleModules,
|
|
44
48
|
runtime: options.runtime,
|
|
49
|
+
dataClasses,
|
|
45
50
|
...importedCode(program, options.importModule),
|
|
46
51
|
};
|
|
47
|
-
const
|
|
52
|
+
const sourceName = options.sourceName ?? 'main.rk';
|
|
53
|
+
const main = withoutMarks(generateJs(program, {
|
|
48
54
|
...jsOptions,
|
|
49
|
-
goroutines: {
|
|
50
|
-
|
|
55
|
+
goroutines: {
|
|
56
|
+
workerUrl: options.workerUrl ?? workerUrl('main.rk', rewriteImports),
|
|
57
|
+
nodeLoader: options.nodeLoader,
|
|
58
|
+
},
|
|
59
|
+
}), source, sourceName);
|
|
51
60
|
const targets = [
|
|
52
61
|
...new Set(goroutines(program).flatMap((node) => goTarget(program, node) ?? [])),
|
|
53
62
|
];
|
|
54
63
|
const worker = targets.length > 0
|
|
55
|
-
? generateJs(workerProgram(program, targets
|
|
64
|
+
? withoutMarks(generateJs(workerProgram(program, targets, dataClasses), {
|
|
65
|
+
...jsOptions,
|
|
66
|
+
goroutines: { targets },
|
|
67
|
+
}), source, sourceName)
|
|
56
68
|
: undefined;
|
|
57
69
|
return {
|
|
58
|
-
code,
|
|
70
|
+
code: main.code,
|
|
59
71
|
diagnostics: [],
|
|
60
72
|
warnings,
|
|
61
73
|
dependencies,
|
|
62
74
|
...(declarations ? { declarations } : {}),
|
|
63
|
-
|
|
75
|
+
map: main.map,
|
|
76
|
+
...(worker === undefined ? {} : { worker: worker.code, workerMap: worker.map }),
|
|
64
77
|
};
|
|
65
78
|
}
|
|
66
79
|
/**
|
package/dist/completion.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type Completion } from './checker/checker.ts';
|
|
1
|
+
import { type Completion, type CompletionContext } from './checker/checker.ts';
|
|
2
2
|
import { type CoreCompileOptions } from './compile.ts';
|
|
3
|
-
export type { Completion, CompletionContext } from './checker/checker.ts';
|
|
3
|
+
export type { Completion, CompletionContext, TextEdit } from './checker/checker.ts';
|
|
4
4
|
export interface CompletionList {
|
|
5
5
|
/** Offsets of what the chosen item replaces: the part of the name before the cursor. */
|
|
6
6
|
start: number;
|
|
7
7
|
end: number;
|
|
8
|
+
/** What the cursor is in; none where nothing is suggested or the check did not reach it. */
|
|
9
|
+
context?: CompletionContext;
|
|
8
10
|
items: Completion[];
|
|
9
11
|
}
|
|
10
12
|
export declare function completeModule(source: string, offset: number, options?: CoreCompileOptions): CompletionList;
|
package/dist/completion.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { check } from "./checker/checker.js";
|
|
1
|
+
import { check, } from "./checker/checker.js";
|
|
2
2
|
import { prepareCheck } from "./compile.js";
|
|
3
3
|
import { tokenize } from "./lexer/lexer.js";
|
|
4
4
|
import { KEYWORDS } from "./lexer/token.js";
|
|
5
5
|
import { parse } from "./parser/parser.js";
|
|
6
|
-
import { RESERVED } from "./parser/syntax.js";
|
|
7
6
|
import { forEachChild } from "./walk.js";
|
|
8
7
|
const CURSOR = '$$cursor';
|
|
9
8
|
const STRINGS = new Set([
|
|
@@ -15,10 +14,11 @@ const STRINGS = new Set([
|
|
|
15
14
|
'JsxText',
|
|
16
15
|
'JsxString',
|
|
17
16
|
'CssText',
|
|
17
|
+
'RegExp',
|
|
18
18
|
]);
|
|
19
|
-
const VALUE_KEYWORDS = KEYWORDS
|
|
19
|
+
const VALUE_KEYWORDS = KEYWORDS;
|
|
20
20
|
// `queue` is a type of its own only in a type: elsewhere it is a name.
|
|
21
|
-
const TYPE_KEYWORDS = ['func', 'comp', 'chan', 'queue'];
|
|
21
|
+
const TYPE_KEYWORDS = ['func', 'comp', 'chan', 'queue', 'topic'];
|
|
22
22
|
/** Keywords only at the start of a statement at the top level of a component or a decorator. */
|
|
23
23
|
const COMPONENT_KEYWORDS = ['state', 'derived', 'ref', 'style', 'effect', 'mount'];
|
|
24
24
|
export function completeModule(source, offset, options = {}) {
|
|
@@ -55,7 +55,12 @@ export function completeModule(source, offset, options = {}) {
|
|
|
55
55
|
const { program } = parse(text, { markup: options.markup ?? true });
|
|
56
56
|
const result = completeIn(program, options);
|
|
57
57
|
if (result) {
|
|
58
|
-
return {
|
|
58
|
+
return {
|
|
59
|
+
start,
|
|
60
|
+
end: offset,
|
|
61
|
+
context: result.context,
|
|
62
|
+
items: withKeywords(result, statementKeywords(program)),
|
|
63
|
+
};
|
|
59
64
|
}
|
|
60
65
|
// The cursor is where a name is declared, `let ti|`: nothing to suggest.
|
|
61
66
|
if (pathTo(program, CURSOR).length > 0)
|
package/dist/declarations.js
CHANGED
|
@@ -137,7 +137,7 @@ class DeclarationPrinter {
|
|
|
137
137
|
switch (member.kind) {
|
|
138
138
|
case 'FieldDeclaration': {
|
|
139
139
|
const found = (member.isStatic ? info.statics : info.members).get(member.name.name);
|
|
140
|
-
const modifiers = this.modifiers(member.visibility, member.isStatic);
|
|
140
|
+
const modifiers = this.modifiers(member.visibility, member.isStatic, member.readonly);
|
|
141
141
|
// As in the declaration files TypeScript writes, private members have no type.
|
|
142
142
|
if (member.visibility === 'private')
|
|
143
143
|
lines.push(`${modifiers}${member.name.name};`);
|
|
@@ -147,6 +147,17 @@ class DeclarationPrinter {
|
|
|
147
147
|
}
|
|
148
148
|
case 'ConstructorDeclaration': {
|
|
149
149
|
const modifiers = this.modifiers(member.visibility, false);
|
|
150
|
+
// The parameters that are properties are declared as fields, as TypeScript writes them.
|
|
151
|
+
member.params.forEach((param, i) => {
|
|
152
|
+
const { property } = param;
|
|
153
|
+
const type = info.ctor?.params[i];
|
|
154
|
+
if (!property)
|
|
155
|
+
return;
|
|
156
|
+
const field = `${this.modifiers(property.visibility, false, property.readonly)}${param.name.name}`;
|
|
157
|
+
lines.push(property.visibility === 'private' || !type
|
|
158
|
+
? `${field};`
|
|
159
|
+
: `${field}: ${tsType(type)};`);
|
|
160
|
+
});
|
|
150
161
|
if (info.ctor) {
|
|
151
162
|
lines.push(`${modifiers}constructor${parameters(member.params, info.ctor)};`);
|
|
152
163
|
}
|
|
@@ -154,8 +165,11 @@ class DeclarationPrinter {
|
|
|
154
165
|
}
|
|
155
166
|
case 'MethodDeclaration': {
|
|
156
167
|
const found = (member.isStatic ? info.statics : info.members).get(member.name.name);
|
|
157
|
-
const modifiers = this.modifiers(member.visibility, member.isStatic)
|
|
158
|
-
|
|
168
|
+
const modifiers = this.modifiers(member.visibility, member.isStatic) +
|
|
169
|
+
(member.abstract ? 'abstract ' : '');
|
|
170
|
+
if (member.accessor)
|
|
171
|
+
lines.push(accessor(member, modifiers, found?.type));
|
|
172
|
+
else if (member.visibility === 'private')
|
|
159
173
|
lines.push(`${modifiers}${member.name.name}();`);
|
|
160
174
|
else if (found?.type.kind === 'function') {
|
|
161
175
|
lines.push(`${modifiers}${member.name.name}${this.signature(member.params, found.type)};`);
|
|
@@ -164,10 +178,11 @@ class DeclarationPrinter {
|
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
180
|
}
|
|
167
|
-
this.lines.push(`${exported}declare class ${jsName(node.name.name)}${this.typeParams(info.typeParams)}${heritage} {`, ...lines.map((line) => ` ${line}`), '}');
|
|
181
|
+
this.lines.push(`${exported}declare ${node.abstract ? 'abstract ' : ''}class ${jsName(node.name.name)}${this.typeParams(info.typeParams)}${heritage} {`, ...lines.map((line) => ` ${line}`), '}');
|
|
168
182
|
}
|
|
169
|
-
modifiers(visibility, isStatic) {
|
|
170
|
-
return `${visibility === 'public' ? '' : `${visibility} `}${isStatic ? 'static ' : ''}
|
|
183
|
+
modifiers(visibility, isStatic, readonly) {
|
|
184
|
+
return (`${visibility === 'public' ? '' : `${visibility} `}${isStatic ? 'static ' : ''}` +
|
|
185
|
+
(readonly ? 'readonly ' : ''));
|
|
171
186
|
}
|
|
172
187
|
/** `<T, U extends Shape>` */
|
|
173
188
|
typeParams(params) {
|
|
@@ -191,6 +206,17 @@ function parameters(params, type) {
|
|
|
191
206
|
});
|
|
192
207
|
return `(${list.join(', ')})`;
|
|
193
208
|
}
|
|
209
|
+
/** `get area(): number;` or `set area(v: number);`; a private one, as TypeScript writes it, untyped. */
|
|
210
|
+
function accessor(node, modifiers, type) {
|
|
211
|
+
const head = `${modifiers}${node.accessor} ${node.name.name}`;
|
|
212
|
+
const param = jsName(node.params[0]?.name.name ?? 'value');
|
|
213
|
+
if (node.visibility === 'private' || !type) {
|
|
214
|
+
return node.accessor === 'get' ? `${head}();` : `${head}(${param});`;
|
|
215
|
+
}
|
|
216
|
+
return node.accessor === 'get'
|
|
217
|
+
? `${head}(): ${tsType(type)};`
|
|
218
|
+
: `${head}(${param}: ${tsType(type)});`;
|
|
219
|
+
}
|
|
194
220
|
/** `Base` or `events.EventEmitter` in `extends`; other expressions cannot be written in types. */
|
|
195
221
|
function expressionName(node) {
|
|
196
222
|
if (node.kind === 'Identifier')
|
package/dist/decorator-copy.js
CHANGED
|
@@ -47,7 +47,10 @@ export function renamer(renames, copied, other = {}) {
|
|
|
47
47
|
const generic = (node, hidden) => {
|
|
48
48
|
const result = {};
|
|
49
49
|
for (const [key, value] of Object.entries(node)) {
|
|
50
|
-
|
|
50
|
+
// Labels are not values: `outer: for` and `break outer` keep their names.
|
|
51
|
+
if (key === 'label')
|
|
52
|
+
result[key] = value;
|
|
53
|
+
else if (Array.isArray(value)) {
|
|
51
54
|
result[key] = value.map((item) => (isNode(item) ? copy(item, hidden) : item));
|
|
52
55
|
}
|
|
53
56
|
else {
|
|
@@ -106,7 +109,7 @@ export function renamer(renames, copied, other = {}) {
|
|
|
106
109
|
return done({
|
|
107
110
|
...node,
|
|
108
111
|
params: node.params.map((param) => copy(param, inner)),
|
|
109
|
-
body: copy(node.body, inner),
|
|
112
|
+
body: node.body && copy(node.body, inner),
|
|
110
113
|
}, node);
|
|
111
114
|
}
|
|
112
115
|
case 'FieldDeclaration':
|
package/dist/goroutines.d.ts
CHANGED
|
@@ -34,4 +34,4 @@ export declare function reach(program: ast.Program, names: Iterable<string>): Re
|
|
|
34
34
|
* The program of the worker module: the imports and the declarations that the functions `targets`
|
|
35
35
|
* reach, unexported, since the worker module is only loaded by the worker.
|
|
36
36
|
*/
|
|
37
|
-
export declare function workerProgram(program: ast.Program, targets: readonly string[]): ast.Program;
|
|
37
|
+
export declare function workerProgram(program: ast.Program, targets: readonly string[], dataClasses?: Iterable<string>): ast.Program;
|
package/dist/goroutines.js
CHANGED
|
@@ -165,9 +165,10 @@ export function reach(program, names) {
|
|
|
165
165
|
* The program of the worker module: the imports and the declarations that the functions `targets`
|
|
166
166
|
* reach, unexported, since the worker module is only loaded by the worker.
|
|
167
167
|
*/
|
|
168
|
-
export function workerProgram(program, targets) {
|
|
168
|
+
export function workerProgram(program, targets, dataClasses = []) {
|
|
169
169
|
const lifted = { ...program, body: [...program.body, ...literalFunctions(program)] };
|
|
170
|
-
|
|
170
|
+
// The data classes come too, so that their instances get their class here (runtime/classes.js).
|
|
171
|
+
const { statements, imports } = reach(lifted, [...targets, ...dataClasses]);
|
|
171
172
|
const body = [];
|
|
172
173
|
for (const [statement, names] of imports) {
|
|
173
174
|
body.push({
|
|
@@ -229,8 +230,8 @@ function usedNames(statement) {
|
|
|
229
230
|
if (member.value)
|
|
230
231
|
add(freeNames({ params: [], body: block([expression(member.value)]) }));
|
|
231
232
|
}
|
|
232
|
-
else {
|
|
233
|
-
add(freeNames(member));
|
|
233
|
+
else if (member.body) {
|
|
234
|
+
add(freeNames({ params: member.params, body: member.body }));
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
return names;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type CompileResult } from './compile.ts';
|
|
2
2
|
import { type CompletionList } from './completion.ts';
|
|
3
|
+
export { importFixes, type ImportFix } from './auto-import.ts';
|
|
3
4
|
export type { CompileResult } from './compile.ts';
|
|
4
|
-
export type { Completion, CompletionList } from './completion.ts';
|
|
5
|
+
export type { Completion, CompletionList, TextEdit } from './completion.ts';
|
|
5
6
|
export type { Diagnostic } from './diagnostics.ts';
|
|
6
7
|
export { formatDiagnostic } from './diagnostics.ts';
|
|
7
8
|
export { SourceFile } from './source.ts';
|
|
@@ -19,6 +20,8 @@ export interface CompileOptions {
|
|
|
19
20
|
declarations?: boolean;
|
|
20
21
|
/** Where the worker module of `go` is, relative to the module; see workerUrl() in compile.ts. */
|
|
21
22
|
workerUrl?: string;
|
|
23
|
+
/** A module that a worker thread of Node imports first, to load `.rk` files (vite.ts). */
|
|
24
|
+
nodeLoader?: string;
|
|
22
25
|
/** Markup and components; by default as the package.json of the file says (src/config.ts). */
|
|
23
26
|
markup?: boolean;
|
|
24
27
|
/** Import the runtime from "rooklang/runtime", the default, or put it into the module. */
|
|
@@ -27,7 +30,8 @@ export interface CompileOptions {
|
|
|
27
30
|
export declare function compile(source: string, options?: CompileOptions): CompileResult;
|
|
28
31
|
/**
|
|
29
32
|
* What can be written at `offset` in a module, for editors: names, members, types, tags and
|
|
30
|
-
* attributes
|
|
33
|
+
* attributes, and after them the names that other modules of the package export, with the imports
|
|
34
|
+
* they need. The imports are read from disk, like those of `compile`.
|
|
31
35
|
*/
|
|
32
36
|
export declare function complete(source: string, offset: number, options?: {
|
|
33
37
|
filename?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { importCompletions } from "./auto-import.js";
|
|
1
2
|
import { compileModule, workerUrl, } from "./compile.js";
|
|
2
3
|
import { completeModule } from "./completion.js";
|
|
3
4
|
import { markupFor } from "./config.js";
|
|
4
5
|
import { loadModuleExports } from "./modules.js";
|
|
5
6
|
import { readFileSync } from 'node:fs';
|
|
6
|
-
import { dirname, join, resolve } from 'node:path';
|
|
7
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
7
8
|
import { importDeclarations, libraryFor } from "./typescript/importer.js";
|
|
9
|
+
export { importFixes } from "./auto-import.js";
|
|
8
10
|
export { formatDiagnostic } from "./diagnostics.js";
|
|
9
11
|
export { SourceFile } from "./source.js";
|
|
10
12
|
export function compile(source, options = {}) {
|
|
@@ -16,20 +18,27 @@ export function compile(source, options = {}) {
|
|
|
16
18
|
markup,
|
|
17
19
|
rewriteImports,
|
|
18
20
|
workerUrl: options.workerUrl ?? workerUrl(filename ?? 'main.rk', rewriteImports),
|
|
21
|
+
nodeLoader: options.nodeLoader,
|
|
19
22
|
typeCheck: options.typeCheck ?? true,
|
|
20
23
|
declarations: options.declarations ?? false,
|
|
21
24
|
runtime: options.runtime,
|
|
25
|
+
sourceName: filename === undefined ? undefined : basename(filename),
|
|
22
26
|
});
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* What can be written at `offset` in a module, for editors: names, members, types, tags and
|
|
26
|
-
* attributes
|
|
30
|
+
* attributes, and after them the names that other modules of the package export, with the imports
|
|
31
|
+
* they need. The imports are read from disk, like those of `compile`.
|
|
27
32
|
*/
|
|
28
33
|
export function complete(source, offset, options = {}) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const { filename } = options;
|
|
35
|
+
const list = completeModule(source, offset, {
|
|
36
|
+
...filesOf(filename, true, options.markup),
|
|
37
|
+
markup: options.markup ?? markupFor(filename),
|
|
32
38
|
});
|
|
39
|
+
if (filename === undefined)
|
|
40
|
+
return list;
|
|
41
|
+
return { ...list, items: [...list.items, ...importCompletions(source, filename, list)] };
|
|
33
42
|
}
|
|
34
43
|
/** Reading what a module imports: other modules, declarations, CSS modules and the library. */
|
|
35
44
|
function filesOf(filename, typeCheck, markup) {
|