rooklang 0.4.1 → 0.5.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/CHANGELOG.md +235 -0
- package/CHANGELOG.ru.md +235 -0
- package/dist/aliases.d.ts +2 -0
- package/dist/aliases.js +83 -0
- package/dist/ast/declarations.d.ts +18 -0
- package/dist/ast/expressions.d.ts +14 -1
- package/dist/ast/markup.d.ts +2 -0
- package/dist/ast/statements.d.ts +2 -2
- package/dist/checker/assignments.js +2 -1
- package/dist/checker/base.d.ts +3 -0
- package/dist/checker/base.js +1 -1
- package/dist/checker/builtins.js +5 -1
- package/dist/checker/calls.d.ts +2 -0
- package/dist/checker/calls.js +18 -3
- package/dist/checker/classes.js +8 -0
- package/dist/checker/component-bindings.d.ts +16 -0
- package/dist/checker/component-bindings.js +65 -2
- package/dist/checker/context.d.ts +12 -0
- package/dist/checker/declarations.d.ts +2 -0
- package/dist/checker/declarations.js +38 -3
- package/dist/checker/expressions.d.ts +1 -0
- package/dist/checker/expressions.js +17 -1
- package/dist/checker/flow.d.ts +1 -1
- package/dist/checker/flow.js +10 -0
- package/dist/checker/functions.d.ts +2 -0
- package/dist/checker/functions.js +33 -7
- package/dist/checker/goroutines.d.ts +2 -2
- package/dist/checker/goroutines.js +2 -2
- package/dist/checker/imports.d.ts +10 -0
- package/dist/checker/imports.js +73 -6
- package/dist/checker/initializers.d.ts +12 -0
- package/dist/checker/initializers.js +80 -0
- package/dist/checker/loops.js +3 -1
- package/dist/checker/members.js +1 -0
- package/dist/checker/resolution.d.ts +2 -0
- package/dist/checker/resolution.js +13 -2
- package/dist/checker/statements.d.ts +5 -0
- package/dist/checker/statements.js +26 -3
- package/dist/checker/tagged-unions.d.ts +6 -0
- package/dist/checker/tagged-unions.js +31 -1
- package/dist/checker/tags.d.ts +6 -0
- package/dist/checker/tags.js +44 -0
- package/dist/checker/types/constructors.js +10 -1
- package/dist/checker/types/params.js +33 -7
- package/dist/checker/types/printing.js +5 -1
- package/dist/checker/types/relations.js +2 -1
- package/dist/codegen/analysis.d.ts +6 -0
- package/dist/codegen/analysis.js +24 -0
- package/dist/codegen/calls.d.ts +2 -0
- package/dist/codegen/calls.js +23 -1
- package/dist/codegen/component-props.js +8 -1
- package/dist/codegen/control-flow.d.ts +3 -0
- package/dist/codegen/control-flow.js +17 -0
- package/dist/codegen/expressions.d.ts +4 -1
- package/dist/codegen/expressions.js +4 -15
- package/dist/codegen/functions.d.ts +2 -0
- package/dist/codegen/functions.js +13 -0
- package/dist/codegen/mutations.d.ts +6 -0
- package/dist/codegen/mutations.js +36 -0
- package/dist/codegen/options.d.ts +2 -0
- package/dist/codegen/reactive.js +9 -5
- package/dist/codegen/simple-statements.js +3 -1
- package/dist/codegen/statements.d.ts +4 -0
- package/dist/codegen/statements.js +37 -1
- package/dist/codegen/updates.d.ts +6 -1
- package/dist/codegen/updates.js +13 -2
- package/dist/compile.js +2 -0
- package/dist/completion.js +2 -1
- package/dist/declarations.js +18 -0
- package/dist/lexer/base.d.ts +3 -2
- package/dist/lexer/base.js +14 -5
- package/dist/lexer/lexer.js +3 -0
- package/dist/lexer/token.d.ts +6 -1
- package/dist/lexer/token.js +0 -1
- package/dist/modules.js +4 -3
- package/dist/parser/base.d.ts +5 -0
- package/dist/parser/base.js +9 -1
- package/dist/parser/classes.js +4 -3
- package/dist/parser/declarations.d.ts +2 -0
- package/dist/parser/declarations.js +25 -2
- package/dist/parser/decorators.js +1 -1
- package/dist/parser/expressions.js +6 -0
- package/dist/parser/literals.d.ts +2 -4
- package/dist/parser/literals.js +12 -24
- package/dist/parser/objects.d.ts +8 -0
- package/dist/parser/objects.js +51 -0
- package/dist/parser/params.d.ts +37 -4
- package/dist/parser/params.js +143 -9
- package/dist/parser/postfix.d.ts +5 -0
- package/dist/parser/postfix.js +36 -0
- package/dist/parser/simple-statements.d.ts +2 -0
- package/dist/parser/simple-statements.js +50 -0
- package/dist/parser/statements.js +8 -6
- package/dist/parser/syntax.js +0 -1
- package/dist/parser/types.d.ts +0 -4
- package/dist/parser/types.js +17 -32
- package/dist/project-modules.js +21 -0
- package/dist/reexports.d.ts +4 -0
- package/dist/reexports.js +56 -0
- package/dist/typescript/importer.d.ts +4 -0
- package/dist/typescript/importer.js +27 -3
- package/dist/typescript/library.js +5 -2
- package/dist/walk.js +12 -0
- package/package.json +4 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
**English** · [Русский](CHANGELOG.ru.md)
|
|
4
|
+
|
|
5
|
+
What changed in each version of `rooklang`: the language, the compiler, the runtime and the VS Code
|
|
6
|
+
extension. The road to 1.0 is in [docs/roadmap.md](docs/roadmap.md).
|
|
7
|
+
|
|
8
|
+
**Versions before 1.0.** A minor version (0.4.0) may break code that compiled before, and says how
|
|
9
|
+
to change it under **Breaking**. A patch version (0.3.5) never does: it adds and fixes only.
|
|
10
|
+
|
|
11
|
+
## 0.5.0 — 2026-10-31
|
|
12
|
+
|
|
13
|
+
What a team that builds a browser game in Rook, with Bun and Vite, found missing or broken.
|
|
14
|
+
|
|
15
|
+
### Breaking
|
|
16
|
+
|
|
17
|
+
- A component changes a property that is not bound neither by assigning it nor in place:
|
|
18
|
+
`todo.done = true`, `bind:value={todo.title}` and `items.push(x)` on a property are errors, since
|
|
19
|
+
the object is the parent's and its markup did not know of the change. Declare the property bound,
|
|
20
|
+
`comp TodoItem(bind todo Todo)`, and pass it with `bind:todo={todo}`; the item of a `{for}` loop
|
|
21
|
+
can now be bound so.
|
|
22
|
+
- `export const Rows = Inner` of a component without a type is an error: its `.d.ts` lost the
|
|
23
|
+
properties. Write `export { Rows } from "./rows.rk"`, or give the constant a component type.
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Default values of the parameters of functions, methods, constructors, `func` literals and arrow
|
|
28
|
+
functions, as properties of components have them: `func greet(name string = "you", times = 1)`.
|
|
29
|
+
- Rest parameters, `func log(level string, ...parts []any)`, and in function types,
|
|
30
|
+
`func(string, ...[]any)`.
|
|
31
|
+
- Tagged templates, `` sql`select * from users where id = ${id}` ``, checked against the parameters
|
|
32
|
+
of the tag.
|
|
33
|
+
- `export { Row, Rows } from "./rows.rk"` and `export * from "./rows.rk"`, with components,
|
|
34
|
+
decorators and state.
|
|
35
|
+
- Object destructuring in `const` and `let`: `const { name, size: bytes, ...rest } = file`.
|
|
36
|
+
- Methods in object literals: `{ fetch(req Request) Response { ... } }`.
|
|
37
|
+
- `x!` takes a value not to be `null`, as in TypeScript.
|
|
38
|
+
- `void`, for `Promise<void>` in interfaces and generics, and `never`, the result of a function
|
|
39
|
+
that never returns; a call of one narrows types as `throw` does, `process.exit(1)` included.
|
|
40
|
+
- `bind:item={item}` for the item of a `{for}` loop: changes in place update the list, and a new
|
|
41
|
+
value replaces the item in it.
|
|
42
|
+
- Imports of `.rk` and `.ts` modules by the aliases of `package.json` (`"imports"`, `#ui/button.rk`)
|
|
43
|
+
and of `tsconfig.json` (`"paths"`, `@/ui/button.rk`) are typed, and built with `.js`.
|
|
44
|
+
- A conditional expression can be split with `?` and `:` at the start of the lines.
|
|
45
|
+
- `func(a, b number) number` groups the parameters of a function type, as in Go.
|
|
46
|
+
- An object type is the result of a function when its body follows, `func names() { [string]: string } { ... }`.
|
|
47
|
+
- `type` is a keyword only before the name of a type at the start of a statement: variables,
|
|
48
|
+
parameters and fields can be named `type`.
|
|
49
|
+
- The npm package has the changelog.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- A function of a component that changes state and that markup gives to a child, `act={copy}`,
|
|
54
|
+
or that an arrow given to it calls, `act={() => show("x")}`, updates the markup: it was taken for
|
|
55
|
+
code that renders, which updates nothing.
|
|
56
|
+
- Importing `describe` and `it` from Vitest overflowed the stack, then took two minutes: the types of
|
|
57
|
+
`.d.ts` files that refer to themselves are substituted when they are used. Messages print a long
|
|
58
|
+
type inside another one as `{ ... }`.
|
|
59
|
+
- The types of `@types/bun`: the global `Bun` and the module `bun` were untyped, and the options of
|
|
60
|
+
`Bun.serve({ fetch: req => ... })` give `req` its type.
|
|
61
|
+
- A callback whose result in a `.d.ts` is `any` or `void | T`, `ws.onopen = () => { ... }`, and a
|
|
62
|
+
function whose result is `any` may end without `return`.
|
|
63
|
+
- A line that ends with `>` of type arguments, `votes Map<string, number>`, ends the declaration.
|
|
64
|
+
- A field of a class sees a constant of its module with a written type or a literal value,
|
|
65
|
+
`limit = LIMIT`.
|
|
66
|
+
- Clearer errors for `` `${x++}` ``, type arguments in a call, `load<number>(1)`, and several
|
|
67
|
+
results of a conditional expression, `a ? two() : one()`.
|
|
68
|
+
|
|
69
|
+
### The site
|
|
70
|
+
|
|
71
|
+
- The site is deployed with each release of npm, not with each push to `main`, so it describes the
|
|
72
|
+
version that `npm install` gets.
|
|
73
|
+
|
|
74
|
+
## 0.4.2 — 2026-10-31
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
|
|
78
|
+
- A function literal given to a child component, `<Plus add={() => { items++ }} />`, updates the
|
|
79
|
+
markup each time it is called. When the state it read changed, the parent gave the child the
|
|
80
|
+
function again, written without its updates: from the second call on, the state changed but the
|
|
81
|
+
page did not. A function declared with `func` in the body was not affected.
|
|
82
|
+
|
|
83
|
+
## 0.4.1 — 2026-10-30
|
|
84
|
+
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- Bun: the plugin `rooklang/bun`, preloaded with `preload = ["rooklang/bun/register"]` in
|
|
88
|
+
`bunfig.toml`, compiles `.rk` modules when they load, for `bun app.rk`, imports from TypeScript,
|
|
89
|
+
`bun --hot` and `bun test`, goroutines included. `rook run` under the runtime of Bun,
|
|
90
|
+
`bun --bun rook run app.rk`, runs the program in Bun, `--watch` too; it used to fail on
|
|
91
|
+
`registerHooks`, which Bun does not have.
|
|
92
|
+
- The VS Code extension has the version of the package it carries, 0.4.1, and the stores get each
|
|
93
|
+
release: it was 0.1.0 there, with the compiler of 17 October. When the `rooklang` installed in a
|
|
94
|
+
project is older than its copy, which then checks the files with errors for newer syntax, the
|
|
95
|
+
status bar marks it and the extension offers to install the new version with the package
|
|
96
|
+
manager of the project.
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
|
|
100
|
+
- A worker of `go` that fails before it starts, as when its module does not load, fails the calls
|
|
101
|
+
that wait for it: they used to wait forever while the pool started worker after worker.
|
|
102
|
+
|
|
103
|
+
## 0.4.0 — 2026-10-29
|
|
104
|
+
|
|
105
|
+
### Breaking
|
|
106
|
+
|
|
107
|
+
- `mount` is written without parentheses, like `effect`: `mount { ... }`. `mount() { ... }` is an
|
|
108
|
+
error that shows the new form.
|
|
109
|
+
- `mount` cleans up with `defer`, as an effect does, and returns nothing: write
|
|
110
|
+
`defer clearInterval(timer)` instead of `return () => clearInterval(timer)`. `defer f(x)` takes
|
|
111
|
+
`x` at once; for a value that comes later, `defer { editor?.dispose() }` reads it when it runs.
|
|
112
|
+
|
|
113
|
+
- A public member of a decorator is read as `@visible.shown`, without `get`: `get(@visible.shown)`
|
|
114
|
+
is now an error that shows the new form. Decorators are experimental, so the old form is not kept.
|
|
115
|
+
Write `@visible.shown` everywhere, in markup too: `{if @visible.shown { ... }}`.
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
|
|
119
|
+
- State of a module (experimental): `state items []Item = []` or `export state` at the top level
|
|
120
|
+
of a module is shared by its components. The components that read it are updated when it changes
|
|
121
|
+
anywhere in the module, through names that refer into it too (`for item in items`); they listen
|
|
122
|
+
while they are on the page. Other modules read it and change it only with the functions of its
|
|
123
|
+
module: `items.push(x)` there is an error that says so.
|
|
124
|
+
- Bound properties (experimental): `comp Drawer(bind open bool = false)` changes `open` as its
|
|
125
|
+
state, and `<Drawer bind:open={menu} />` writes the changes, in place ones too, into the parent's
|
|
126
|
+
`menu`. Without `bind:` the property is the component's own state.
|
|
127
|
+
- `class` takes a list of classes, `class={[styles.tab, active ? styles.active : null]}`: `null`s
|
|
128
|
+
and empty strings are left out.
|
|
129
|
+
- A `bool` in `aria-*` and other attributes without a DOM property is written as `"true"` or
|
|
130
|
+
`"false"`, as ARIA expects; this is now documented and tested.
|
|
131
|
+
|
|
132
|
+
- A decorator can include others: `dec card(title string) includes framed(title), likes { ... }`
|
|
133
|
+
applies them with it, above its own body, and their arguments see its parameters. The component
|
|
134
|
+
reads their public members through it, `@card.count`; `@card` counts as `@likes` applied, for
|
|
135
|
+
`needs` and for applying twice. An exported decorator cannot include others yet.
|
|
136
|
+
- `public ref` in a decorator: the component reads the element of the wrapper as `@framed.box`.
|
|
137
|
+
The ref is read-only, its element is not: `@framed.box.title = "Card"`.
|
|
138
|
+
- A `derived` of several statements is a block that returns the value:
|
|
139
|
+
`derived summary string { ...; return text }`. The type may be left out, and is then inferred
|
|
140
|
+
from the `return`s. In JS the block becomes a function, called first and by the updates of what
|
|
141
|
+
it reads; assigning state in it is an error. A `{` after the name of a `derived` now starts the
|
|
142
|
+
block, so an object type goes in parentheses there: `derived p ({ x number }) = ...`.
|
|
143
|
+
- Tagged unions (experimental): comparing a tag, a field with a literal type in every member of a
|
|
144
|
+
union, narrows the union. After `if d.kind == "courier"` the fields of `Courier` can be read, and
|
|
145
|
+
so in `else`, after a branch that returns, in `switch d.kind` and in `{if}` and `{switch}` of
|
|
146
|
+
markup. An object literal where such a union is expected is checked as the member its tag
|
|
147
|
+
chooses: `{ kind: "pickup", shop: "Main st." }` fits `Pickup | Courier`, and a kind of no member
|
|
148
|
+
is an error that lists the kinds.
|
|
149
|
+
- Paths of data fields from a variable, a parameter, `state`, `derived` or a module `const` narrow
|
|
150
|
+
like the variable: `if user.boss != null` gives `user.boss.name`, without an intermediate
|
|
151
|
+
`const`; `typeof` and `instanceof` narrow them too. An assignment to the path, its start or its
|
|
152
|
+
tag ends the narrowing, one to another field does not; getters, `a[i]` and `?.` are not paths.
|
|
153
|
+
The hint for a nullable
|
|
154
|
+
`<page.other />` now shows `{if page.other != null { <page.other /> }}`.
|
|
155
|
+
- Keys of lists in markup: `{for todo in todos with key todo.id { ... }}` finds the blocks again
|
|
156
|
+
by the key, so a list loaded again from a server keeps its blocks and the state of the
|
|
157
|
+
components in them.
|
|
158
|
+
- The browser compiler, which the playground uses, knows `AbortController`, `AbortSignal` and
|
|
159
|
+
`ImageData` as types too: `signal AbortSignal` compiles there.
|
|
160
|
+
- The VS Code extension checks a file with the `rooklang` installed next to it, so the editor shows
|
|
161
|
+
the errors of the version that `rook build` runs; in an untrusted workspace, and without an
|
|
162
|
+
installed one, it uses its own copy. The status bar shows which compiler checked the file.
|
|
163
|
+
- [docs/roadmap.md](docs/roadmap.md): where Rook stands and the road to 1.0, with what the
|
|
164
|
+
language is to have by then.
|
|
165
|
+
|
|
166
|
+
### Fixed
|
|
167
|
+
|
|
168
|
+
- The error of `decode` for a union names the member whose tag fits: `{ "kind": "square" }` of
|
|
169
|
+
`Circle | Square` gives `side: missing`, not `kind: expected "circle", got "square"`. A tag that
|
|
170
|
+
fits no member lists all of them: `kind: expected "circle" | "square", got "oval"`.
|
|
171
|
+
- A literal type or a union of them, `type Status "shown" | "aborted"`, goes into an attribute
|
|
172
|
+
without a DOM property, `data-status={status}`.
|
|
173
|
+
- With `runtime: "inline"`, as in the playground, a function of the program named like one of the
|
|
174
|
+
runtime, such as `check`, no longer replaces it.
|
|
175
|
+
|
|
176
|
+
## 0.3.4 — 2026-10-26
|
|
177
|
+
|
|
178
|
+
### Added
|
|
179
|
+
|
|
180
|
+
- `decode<T>(json)`: checks JSON from outside against a type when the program runs.
|
|
181
|
+
- `try` as an expression: what JS throws becomes the error value.
|
|
182
|
+
- `error(msg, err)` wraps an error, as `%w` of Go.
|
|
183
|
+
- `signal(...)`, `done(abortSignal)` and `abortSignal(ch)`: signals of the process and cancellation
|
|
184
|
+
as channels.
|
|
185
|
+
- Topics, `topic<T>(name)`: values between the tabs of a site.
|
|
186
|
+
- `for` over async iterables: streams of Node, `readline`, cursors.
|
|
187
|
+
- `data class`: instances that go to goroutines with their class and methods.
|
|
188
|
+
- Getters and setters, `readonly`, `abstract` classes, `if` with an initializer, labels, regular
|
|
189
|
+
expression literals.
|
|
190
|
+
- Source maps: stack traces, in goroutines too, show the lines of the `.rk` file.
|
|
191
|
+
- `rook run --watch`: runs the program again when a file of it changes.
|
|
192
|
+
- Goroutines run under Vitest, which tests `.rk` modules with the Vite plugin.
|
|
193
|
+
- The VS Code extension completes names that other `.rk` files of the package export and adds
|
|
194
|
+
their imports, and offers a quick fix that imports an undefined name.
|
|
195
|
+
|
|
196
|
+
### Fixed
|
|
197
|
+
|
|
198
|
+
- An array, a string or a `Set` goes where a `.d.ts` expects `Iterable<T>`.
|
|
199
|
+
- The type parameters of a tuple `[K, V]` of a `.d.ts` are inferred by position:
|
|
200
|
+
`new Map([["a", 1]])` is a `Map<string, number>`.
|
|
201
|
+
|
|
202
|
+
## 0.3.3 — 2026-10-18
|
|
203
|
+
|
|
204
|
+
### Breaking
|
|
205
|
+
|
|
206
|
+
- In `const user, err = load(id)` of a function of `(User, error)`, `user` is a `?User` until
|
|
207
|
+
`err` is checked: such a function may now `return null, err`. Check the error before the value,
|
|
208
|
+
`if err != null { return }`.
|
|
209
|
+
|
|
210
|
+
### Changed
|
|
211
|
+
|
|
212
|
+
- `go for` splits the array into four parts per processor, each to the first free worker.
|
|
213
|
+
- `for i, x in items` over an array goes over its indexes instead of the pairs of `entries()`,
|
|
214
|
+
which is faster.
|
|
215
|
+
|
|
216
|
+
### Fixed
|
|
217
|
+
|
|
218
|
+
- `for i, c in s` over a string numbers its characters instead of throwing a `TypeError`.
|
|
219
|
+
- The workers of `rook run` no longer load the compiler.
|
|
220
|
+
|
|
221
|
+
## 0.3.2 — 2026-10-17
|
|
222
|
+
|
|
223
|
+
### Breaking
|
|
224
|
+
|
|
225
|
+
- The compiled code imports its runtime from `rooklang/runtime` instead of having it in every
|
|
226
|
+
module, so `rooklang` is a dependency of the project, not only of the build:
|
|
227
|
+
`npm install rooklang`.
|
|
228
|
+
|
|
229
|
+
### Added
|
|
230
|
+
|
|
231
|
+
- Queues: `queue T`, made by `queue<T>()` and `queue<T>(items)`.
|
|
232
|
+
- Streams and channels: `chan(stream)` and `stream(ch)`.
|
|
233
|
+
- The VS Code extension, published from CI.
|
|
234
|
+
|
|
235
|
+
Earlier versions are in the history of the repository.
|
package/CHANGELOG.ru.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Список изменений
|
|
2
|
+
|
|
3
|
+
[English](CHANGELOG.md) · **Русский**
|
|
4
|
+
|
|
5
|
+
Что изменилось в каждой версии `rooklang`: язык, компилятор, рантайм и расширение VS Code. Путь к
|
|
6
|
+
1.0 описан в [docs/roadmap.ru.md](docs/roadmap.ru.md).
|
|
7
|
+
|
|
8
|
+
**Версии до 1.0.** Минорная версия (0.4.0) может сломать код, который раньше компилировался, и
|
|
9
|
+
говорит, как его поменять, в разделе **Ломающие изменения**. Патч (0.3.5) никогда не ломает: он
|
|
10
|
+
только добавляет и исправляет.
|
|
11
|
+
|
|
12
|
+
## 0.5.0 — 2026-10-31
|
|
13
|
+
|
|
14
|
+
Что нашла команда, которая пишет на Rook браузерную игру с Bun и Vite: чего не хватало и что не
|
|
15
|
+
работало.
|
|
16
|
+
|
|
17
|
+
### Ломающие изменения
|
|
18
|
+
|
|
19
|
+
- Компонент не меняет несвязанное свойство ни присваиванием, ни на месте: `todo.done = true`,
|
|
20
|
+
`bind:value={todo.title}` и `items.push(x)` для свойства — ошибки, потому что объект принадлежит
|
|
21
|
+
родителю, а его разметка об изменении не знала. Объявите свойство связанным,
|
|
22
|
+
`comp TodoItem(bind todo Todo)`, и передайте его через `bind:todo={todo}`; теперь так можно
|
|
23
|
+
связать и элемент цикла `{for}`.
|
|
24
|
+
- `export const Rows = Inner` для компонента без типа — ошибка: его `.d.ts` терял свойства.
|
|
25
|
+
Пишите `export { Rows } from "./rows.rk"` или дайте константе тип компонента.
|
|
26
|
+
|
|
27
|
+
### Добавлено
|
|
28
|
+
|
|
29
|
+
- Значения по умолчанию у параметров функций, методов, конструкторов, литералов `func` и стрелочных
|
|
30
|
+
функций, как у свойств компонентов: `func greet(name string = "you", times = 1)`.
|
|
31
|
+
- Остаток аргументов, `func log(level string, ...parts []any)`, и в типах функций,
|
|
32
|
+
`func(string, ...[]any)`.
|
|
33
|
+
- Теговые шаблоны, `` sql`select * from users where id = ${id}` ``, которые проверяются по
|
|
34
|
+
параметрам тега.
|
|
35
|
+
- `export { Row, Rows } from "./rows.rk"` и `export * from "./rows.rk"` — с компонентами,
|
|
36
|
+
декораторами и состоянием.
|
|
37
|
+
- Деструктуризация объектов в `const` и `let`: `const { name, size: bytes, ...rest } = file`.
|
|
38
|
+
- Методы в объектных литералах: `{ fetch(req Request) Response { ... } }`.
|
|
39
|
+
- `x!` считает значение не `null`, как в TypeScript.
|
|
40
|
+
- `void` — для `Promise<void>` в интерфейсах и обобщённых типах, и `never` — результат функции,
|
|
41
|
+
которая не возвращается; её вызов сужает типы, как `throw`, в том числе `process.exit(1)`.
|
|
42
|
+
- `bind:item={item}` для элемента цикла `{for}`: изменения на месте обновляют список, а новое
|
|
43
|
+
значение заменяет в нём элемент.
|
|
44
|
+
- Импорты `.rk`- и `.ts`-модулей по алиасам из `package.json` (`"imports"`, `#ui/button.rk`) и
|
|
45
|
+
`tsconfig.json` (`"paths"`, `@/ui/button.rk`) типизированы и собираются с `.js`.
|
|
46
|
+
- Условное выражение можно переносить, начиная строки с `?` и `:`.
|
|
47
|
+
- `func(a, b number) number` группирует параметры типа функции, как в Go.
|
|
48
|
+
- Объектный тип — результат функции, если за ним идёт тело: `func names() { [string]: string } { ... }`.
|
|
49
|
+
- `type` — ключевое слово только перед именем типа в начале оператора: переменные, параметры и
|
|
50
|
+
поля можно называть `type`.
|
|
51
|
+
- В npm-пакете есть список изменений.
|
|
52
|
+
|
|
53
|
+
### Исправлено
|
|
54
|
+
|
|
55
|
+
- Функция компонента, которая меняет состояние и которую разметка передаёт дочернему компоненту,
|
|
56
|
+
`act={copy}`, или которую вызывает переданная ему стрелка, `act={() => show("x")}`, обновляет
|
|
57
|
+
разметку: её принимали за код отрисовки, который ничего не обновляет.
|
|
58
|
+
- Импорт `describe` и `it` из Vitest переполнял стек, а затем проверялся две минуты: типы
|
|
59
|
+
`.d.ts`, которые ссылаются сами на себя, подставляются, когда используются. Длинный тип внутри
|
|
60
|
+
другого сообщения печатают как `{ ... }`.
|
|
61
|
+
- Типы `@types/bun`: глобальный `Bun` и модуль `bun` были без типов, а в
|
|
62
|
+
`Bun.serve({ fetch: req => ... })` у `req` теперь есть тип.
|
|
63
|
+
- Колбэк, у которого в `.d.ts` результат `any` или `void | T`, `ws.onopen = () => { ... }`, и
|
|
64
|
+
функция с результатом `any` могут закончиться без `return`.
|
|
65
|
+
- Строка, которая кончается на `>` аргументов типа, `votes Map<string, number>`, завершает
|
|
66
|
+
объявление.
|
|
67
|
+
- Поле класса видит константу своего модуля с записанным типом или литеральным значением,
|
|
68
|
+
`limit = LIMIT`.
|
|
69
|
+
- Понятные ошибки для `` `${x++}` ``, аргументов типа в вызове, `load<number>(1)`, и нескольких
|
|
70
|
+
результатов условного выражения, `a ? two() : one()`.
|
|
71
|
+
|
|
72
|
+
### Сайт
|
|
73
|
+
|
|
74
|
+
- Сайт выкладывается с каждым выпуском в npm, а не с каждым пушем в `main`, поэтому описывает ту
|
|
75
|
+
версию, которую ставит `npm install`.
|
|
76
|
+
|
|
77
|
+
## 0.4.2 — 2026-10-31
|
|
78
|
+
|
|
79
|
+
### Исправлено
|
|
80
|
+
|
|
81
|
+
- Функция-литерал, переданная дочернему компоненту, `<Plus add={() => { items++ }} />`, обновляет
|
|
82
|
+
разметку при каждом вызове. Когда менялось состояние, которое она читала, родитель передавал
|
|
83
|
+
ребёнку функцию заново — уже без обновлений: начиная со второго вызова состояние менялось, а
|
|
84
|
+
страница нет. Функции, объявленной в теле через `func`, это не касалось.
|
|
85
|
+
|
|
86
|
+
## 0.4.1 — 2026-10-30
|
|
87
|
+
|
|
88
|
+
### Добавлено
|
|
89
|
+
|
|
90
|
+
- Bun: плагин `rooklang/bun`, который подключают заранее строкой
|
|
91
|
+
`preload = ["rooklang/bun/register"]` в `bunfig.toml`, компилирует `.rk`-модули при загрузке —
|
|
92
|
+
для `bun app.rk`, импортов из TypeScript, `bun --hot` и `bun test`, с горутинами. `rook run` под
|
|
93
|
+
рантаймом Bun, `bun --bun rook run app.rk`, выполняет программу в Bun, и с `--watch` тоже; раньше
|
|
94
|
+
он падал на `registerHooks`, которого в Bun нет.
|
|
95
|
+
- У расширения VS Code та же версия, что у пакета, который оно несёт, — 0.4.1, и в магазины
|
|
96
|
+
попадает каждый выпуск: там была 0.1.0 с компилятором от 17 октября. Если `rooklang`,
|
|
97
|
+
установленный в проекте, старше его копии — и тогда новый синтаксис подчёркивается как ошибка, —
|
|
98
|
+
строка состояния отмечает это, а расширение предлагает поставить новую версию менеджером пакетов
|
|
99
|
+
проекта.
|
|
100
|
+
|
|
101
|
+
### Исправлено
|
|
102
|
+
|
|
103
|
+
- Воркер `go`, который упал до старта — например, потому что его модуль не загрузился, — отклоняет
|
|
104
|
+
вызовы, которые его ждут: раньше они ждали вечно, а пул запускал воркер за воркером.
|
|
105
|
+
|
|
106
|
+
## 0.4.0 — 2026-10-29
|
|
107
|
+
|
|
108
|
+
### Ломающие изменения
|
|
109
|
+
|
|
110
|
+
- `mount` пишется без скобок, как `effect`: `mount { ... }`. `mount() { ... }` — ошибка, которая
|
|
111
|
+
показывает новую запись.
|
|
112
|
+
- `mount` убирает за собой через `defer`, как эффект, и ничего не возвращает: пишите
|
|
113
|
+
`defer clearInterval(timer)` вместо `return () => clearInterval(timer)`. `defer f(x)` берёт `x`
|
|
114
|
+
сразу; для значения, которое появится позже, `defer { editor?.dispose() }` читает его при
|
|
115
|
+
выполнении.
|
|
116
|
+
|
|
117
|
+
- Публичный член декоратора читают как `@visible.shown`, без `get`: `get(@visible.shown)` теперь
|
|
118
|
+
ошибка, которая показывает новую запись. Декораторы экспериментальные, поэтому старая запись не
|
|
119
|
+
сохраняется. Пишите `@visible.shown` везде, и в разметке тоже: `{if @visible.shown { ... }}`.
|
|
120
|
+
|
|
121
|
+
### Добавлено
|
|
122
|
+
|
|
123
|
+
- Состояние модуля (экспериментально): `state items []Item = []` или `export state` на верхнем
|
|
124
|
+
уровне модуля делят его компоненты. Компоненты, которые его читают, обновляются, когда оно
|
|
125
|
+
меняется где угодно в модуле, в том числе через имена, которые указывают внутрь него
|
|
126
|
+
(`for item in items`); они слушают, пока они на странице. Другие модули его читают и меняют только
|
|
127
|
+
функциями его модуля: `items.push(x)` там — ошибка, которая это подсказывает.
|
|
128
|
+
- Связанные свойства (экспериментально): `comp Drawer(bind open bool = false)` меняет `open` как
|
|
129
|
+
своё состояние, а `<Drawer bind:open={menu} />` записывает изменения, в том числе на месте, в
|
|
130
|
+
`menu` родителя. Без `bind:` свойство — собственное состояние компонента.
|
|
131
|
+
- `class` принимает список классов, `class={[styles.tab, active ? styles.active : null]}`: `null` и
|
|
132
|
+
пустые строки выпадают.
|
|
133
|
+
- `bool` в `aria-*` и других атрибутах без DOM-свойства записывается как `"true"` или `"false"`,
|
|
134
|
+
как ждёт ARIA; теперь это описано и проверено тестом.
|
|
135
|
+
|
|
136
|
+
- Декоратор может включать другие: `dec card(title string) includes framed(title), likes { ... }`
|
|
137
|
+
применяет их вместе с собой, выше своего тела, а их аргументы видят его параметры. Компонент
|
|
138
|
+
читает их публичные члены через него, `@card.count`; `@card` считается применённым `@likes` — для
|
|
139
|
+
`needs` и для повторного применения. Экспортированный декоратор пока не может включать другие.
|
|
140
|
+
- `public ref` в декораторе: компонент читает элемент обёртки как `@framed.box`. Сам ref только для
|
|
141
|
+
чтения, его элемент — нет: `@framed.box.title = "Card"`.
|
|
142
|
+
- `derived` из нескольких операторов — блок, который возвращает значение:
|
|
143
|
+
`derived summary string { ...; return text }`. Тип можно не писать, тогда он выводится из
|
|
144
|
+
`return`. В JS блок становится функцией, которую вызывают сначала и в обновлениях того, что он
|
|
145
|
+
читает; присвоить в нём состояние — ошибка. `{` после имени `derived` теперь начинает блок,
|
|
146
|
+
поэтому объектный тип там пишут в скобках: `derived p ({ x number }) = ...`.
|
|
147
|
+
- Tagged unions (экспериментально): сравнение метки, поля с литеральным типом у каждого члена
|
|
148
|
+
union, сужает union. После `if d.kind == "courier"` можно читать поля `Courier`, и так же в
|
|
149
|
+
`else`, после ветки с `return`, в `switch d.kind` и в `{if}` и `{switch}` разметки. Объектный
|
|
150
|
+
литерал там, где ожидается такой union, проверяется как член, который выбирает его метка:
|
|
151
|
+
`{ kind: "pickup", shop: "Main st." }` подходит к `Pickup | Courier`, а вид, которого нет ни у
|
|
152
|
+
одного члена, — ошибка со списком видов.
|
|
153
|
+
- Пути полей с данными от переменной, параметра, `state`, `derived` или `const` модуля сужаются
|
|
154
|
+
так же, как переменная: `if user.boss != null` даёт `user.boss.name` без промежуточной `const`;
|
|
155
|
+
`typeof` и `instanceof` их тоже сужают. Присваивание пути, его начала или его метки сбрасывает
|
|
156
|
+
сужение, присваивание другого поля — нет; геттеры, `a[i]` и `?.` путями не считаются. Подсказка для `<page.other />`, который
|
|
157
|
+
может быть null, теперь показывает `{if page.other != null { <page.other /> }}`.
|
|
158
|
+
- Ключи списков в разметке: `{for todo in todos with key todo.id { ... }}` находит блоки заново по
|
|
159
|
+
ключу, так что список, заново загруженный с сервера, сохраняет свои блоки и состояние компонентов
|
|
160
|
+
в них.
|
|
161
|
+
- Браузерный компилятор, которым пользуется песочница, знает `AbortController`, `AbortSignal` и
|
|
162
|
+
`ImageData` и как типы: `signal AbortSignal` там компилируется.
|
|
163
|
+
- Расширение VS Code проверяет файл тем `rooklang`, который установлен рядом с ним, так что редактор
|
|
164
|
+
показывает ошибки той версии, которую запускает `rook build`; в недоверенной рабочей области и без
|
|
165
|
+
установленного пакета — своей копией. Строка состояния показывает, какой компилятор проверил файл.
|
|
166
|
+
- [docs/roadmap.ru.md](docs/roadmap.ru.md): где Rook сейчас и путь к 1.0, и что к тому времени
|
|
167
|
+
должно быть в языке.
|
|
168
|
+
|
|
169
|
+
### Исправлено
|
|
170
|
+
|
|
171
|
+
- Ошибка `decode` для union называет член, чья метка подошла: `{ "kind": "square" }` для
|
|
172
|
+
`Circle | Square` даёт `side: missing`, а не `kind: expected "circle", got "square"`. Метка, которая
|
|
173
|
+
не подошла ни к одному члену, перечисляет их все: `kind: expected "circle" | "square", got "oval"`.
|
|
174
|
+
- Литеральный тип или их объединение, `type Status "shown" | "aborted"`, можно передать в атрибут
|
|
175
|
+
без DOM-свойства, `data-status={status}`.
|
|
176
|
+
- С `runtime: "inline"`, как в песочнице, функция программы с тем же именем, что у функции
|
|
177
|
+
рантайма, например `check`, больше её не подменяет.
|
|
178
|
+
|
|
179
|
+
## 0.3.4 — 2026-10-26
|
|
180
|
+
|
|
181
|
+
### Добавлено
|
|
182
|
+
|
|
183
|
+
- `decode<T>(json)`: проверяет JSON снаружи по типу, когда программа работает.
|
|
184
|
+
- `try` как выражение: то, что бросает JS, становится значением ошибки.
|
|
185
|
+
- `error(msg, err)` оборачивает ошибку, как `%w` в Go.
|
|
186
|
+
- `signal(...)`, `done(abortSignal)` и `abortSignal(ch)`: сигналы процесса и отмена как каналы.
|
|
187
|
+
- Топики, `topic<T>(name)`: значения между вкладками сайта.
|
|
188
|
+
- `for` по асинхронным итерируемым: потоки Node, `readline`, курсоры.
|
|
189
|
+
- `data class`: экземпляры, которые уходят в горутины вместе со своим классом и методами.
|
|
190
|
+
- Геттеры и сеттеры, `readonly`, абстрактные классы, `if` с инициализатором, метки, литералы
|
|
191
|
+
регулярных выражений.
|
|
192
|
+
- Source maps: стектрейсы, в горутинах тоже, показывают строки `.rk`-файла.
|
|
193
|
+
- `rook run --watch`: запускает программу заново, когда меняется её файл.
|
|
194
|
+
- Горутины работают под Vitest, который тестирует `.rk`-модули с плагином Vite.
|
|
195
|
+
- Расширение VS Code дополняет имена, которые экспортируют другие `.rk`-файлы пакета, и добавляет
|
|
196
|
+
их импорты, а для неопределённого имени предлагает исправление, которое его импортирует.
|
|
197
|
+
|
|
198
|
+
### Исправлено
|
|
199
|
+
|
|
200
|
+
- Массив, строку или `Set` можно передать туда, где `.d.ts` ждёт `Iterable<T>`.
|
|
201
|
+
- Параметры типа кортежа `[K, V]` из `.d.ts` выводятся по позиции: `new Map([["a", 1]])` — это
|
|
202
|
+
`Map<string, number>`.
|
|
203
|
+
|
|
204
|
+
## 0.3.3 — 2026-10-18
|
|
205
|
+
|
|
206
|
+
### Ломающие изменения
|
|
207
|
+
|
|
208
|
+
- В `const user, err = load(id)` функции с `(User, error)` значение `user` имеет тип `?User`, пока
|
|
209
|
+
не проверен `err`: такая функция теперь может вернуть `return null, err`. Проверяйте ошибку раньше
|
|
210
|
+
значения: `if err != null { return }`.
|
|
211
|
+
|
|
212
|
+
### Изменено
|
|
213
|
+
|
|
214
|
+
- `go for` делит массив на четыре части на процессор, каждую — первому свободному воркеру.
|
|
215
|
+
- `for i, x in items` по массиву идёт по индексам, а не по парам `entries()`: так быстрее.
|
|
216
|
+
|
|
217
|
+
### Исправлено
|
|
218
|
+
|
|
219
|
+
- `for i, c in s` по строке нумерует её символы, а не бросает `TypeError`.
|
|
220
|
+
- Воркеры `rook run` больше не загружают компилятор.
|
|
221
|
+
|
|
222
|
+
## 0.3.2 — 2026-10-17
|
|
223
|
+
|
|
224
|
+
### Ломающие изменения
|
|
225
|
+
|
|
226
|
+
- Скомпилированный код импортирует рантайм из `rooklang/runtime`, а не держит его в каждом модуле,
|
|
227
|
+
так что `rooklang` — зависимость проекта, а не только сборки: `npm install rooklang`.
|
|
228
|
+
|
|
229
|
+
### Добавлено
|
|
230
|
+
|
|
231
|
+
- Очереди: `queue T`, создаются через `queue<T>()` и `queue<T>(items)`.
|
|
232
|
+
- Потоки и каналы: `chan(stream)` и `stream(ch)`.
|
|
233
|
+
- Расширение VS Code, которое публикуется из CI.
|
|
234
|
+
|
|
235
|
+
Более ранние версии — в истории репозитория.
|
package/dist/aliases.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
// Where a `.rk` module that an import names is: a relative path, a subpath import of package.json,
|
|
4
|
+
// `#ui/button.rk` with "imports": { "#ui/*": "./src/ui/*" }, or a path of tsconfig.json,
|
|
5
|
+
// `@/ui/button.rk` with "paths": { "@/*": ["./src/*"] }, which Vite and TypeScript resolve too.
|
|
6
|
+
/** The absolute path of the `.rk` module `specifier` imported from `fromFile`, or null. */
|
|
7
|
+
export function resolveRookModule(fromFile, specifier) {
|
|
8
|
+
if (specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
9
|
+
return resolve(dirname(fromFile), specifier);
|
|
10
|
+
}
|
|
11
|
+
if (specifier.startsWith('#')) {
|
|
12
|
+
const found = nearest(fromFile, 'package.json');
|
|
13
|
+
const imports = found?.json.imports;
|
|
14
|
+
const target = imports && match(imports, specifier);
|
|
15
|
+
return found && typeof target === 'string' ? resolve(found.dir, target) : null;
|
|
16
|
+
}
|
|
17
|
+
const found = nearest(fromFile, 'tsconfig.json');
|
|
18
|
+
const options = found?.json.compilerOptions;
|
|
19
|
+
const target = options?.paths && match(options.paths, specifier);
|
|
20
|
+
return found && typeof target === 'string'
|
|
21
|
+
? resolve(found.dir, options?.baseUrl ?? '.', target)
|
|
22
|
+
: null;
|
|
23
|
+
}
|
|
24
|
+
/** The target of the first pattern that fits, with its `*` filled in. */
|
|
25
|
+
function match(patterns, specifier) {
|
|
26
|
+
for (const [pattern, value] of Object.entries(patterns)) {
|
|
27
|
+
const target = firstTarget(value);
|
|
28
|
+
const star = pattern.indexOf('*');
|
|
29
|
+
if (target === null)
|
|
30
|
+
continue;
|
|
31
|
+
if (star === -1) {
|
|
32
|
+
if (pattern === specifier)
|
|
33
|
+
return target;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const prefix = pattern.slice(0, star);
|
|
37
|
+
const suffix = pattern.slice(star + 1);
|
|
38
|
+
if (specifier.startsWith(prefix) && specifier.endsWith(suffix)) {
|
|
39
|
+
return target.replace('*', specifier.slice(prefix.length, specifier.length - suffix.length));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/** A path, the first of a list, or that of the conditions `import` or `default`. */
|
|
45
|
+
function firstTarget(value) {
|
|
46
|
+
if (typeof value === 'string')
|
|
47
|
+
return value;
|
|
48
|
+
if (Array.isArray(value))
|
|
49
|
+
return firstTarget(value[0]);
|
|
50
|
+
if (value && typeof value === 'object') {
|
|
51
|
+
const conditions = value;
|
|
52
|
+
return firstTarget(conditions.import ?? conditions.default ?? null);
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/** The nearest file of this name above `fromFile`, read as JSON with comments, as tsconfig.json is. */
|
|
57
|
+
function nearest(fromFile, name) {
|
|
58
|
+
for (let dir = dirname(fromFile);; dir = dirname(dir)) {
|
|
59
|
+
let text = null;
|
|
60
|
+
try {
|
|
61
|
+
text = readFileSync(join(dir, name), 'utf8');
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Not in this directory.
|
|
65
|
+
}
|
|
66
|
+
if (text !== null) {
|
|
67
|
+
try {
|
|
68
|
+
return { dir, json: JSON.parse(withoutComments(text)) };
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (dirname(dir) === dir)
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** JSON without the comments and trailing commas that tsconfig.json may have. */
|
|
79
|
+
function withoutComments(text) {
|
|
80
|
+
return text
|
|
81
|
+
.replace(/"(?:\\.|[^"\\])*"|\/\/[^\n]*|\/\*[\s\S]*?\*\//g, (part) => part.startsWith('"') ? part : '')
|
|
82
|
+
.replace(/,(\s*[}\]])/g, '$1');
|
|
83
|
+
}
|
|
@@ -26,6 +26,16 @@ export interface ImportSpecifier extends NodeBase {
|
|
|
26
26
|
imported: Identifier;
|
|
27
27
|
local: Identifier;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* `export { Row, Rows } from "./rows.rk"` or `export * from "./rows.rk"`: names of another module,
|
|
31
|
+
* which this one exports but does not see itself, as in JS.
|
|
32
|
+
*/
|
|
33
|
+
export interface ExportFromDeclaration extends NodeBase {
|
|
34
|
+
kind: 'ExportFromDeclaration';
|
|
35
|
+
/** `null` for `export *`; `imported` is the name there, `local` the one it is exported under. */
|
|
36
|
+
specifiers: ImportSpecifier[] | null;
|
|
37
|
+
source: StringLiteral;
|
|
38
|
+
}
|
|
29
39
|
/** `func divide(a, b number) (number, error) { ... }` */
|
|
30
40
|
export interface FuncDeclaration extends NodeBase {
|
|
31
41
|
kind: 'FuncDeclaration';
|
|
@@ -142,6 +152,14 @@ export interface VariableDeclaration extends NodeBase {
|
|
|
142
152
|
* component stops at it, as at other functions. Its result type is `type`; `values` is empty.
|
|
143
153
|
*/
|
|
144
154
|
body: FuncExpression | null;
|
|
155
|
+
/**
|
|
156
|
+
* `const { name, size: bytes, ...rest } = file`: the key of the field that each name takes, in
|
|
157
|
+
* the order of `names`; with `rest`, the last name gets the other fields.
|
|
158
|
+
*/
|
|
159
|
+
pattern?: {
|
|
160
|
+
keys: (Identifier | StringLiteral)[];
|
|
161
|
+
rest: boolean;
|
|
162
|
+
};
|
|
145
163
|
}
|
|
146
164
|
/** `class Admin extends User implements Shape { ... }` */
|
|
147
165
|
export interface ClassDeclaration extends NodeBase {
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import type { NodeBase, Parameter } from './declarations.ts';
|
|
2
2
|
import type { ElementExpression, TypeNode } from './markup.ts';
|
|
3
3
|
import type { BlockStatement } from './statements.ts';
|
|
4
|
-
export type Expression = Identifier | NumberLiteral | BigIntLiteral | StringLiteral | RegExpLiteral | TemplateLiteral | BooleanLiteral | NullLiteral | ThisExpression | SuperExpression | ArrayLiteral | ObjectLiteral | FuncExpression | ArrowFunction | UnaryExpression | BinaryExpression | ConditionalExpression | CallExpression | NewExpression | MemberExpression | IndexExpression | ElementExpression | DecoratorMember | AsExpression | GoExpression | ChanExpression | StreamChanExpression | QueueExpression | TopicExpression | DecodeExpression | TryExpression | ConversionExpression | MakeExpression;
|
|
4
|
+
export type Expression = Identifier | NumberLiteral | BigIntLiteral | StringLiteral | RegExpLiteral | TemplateLiteral | BooleanLiteral | NullLiteral | ThisExpression | SuperExpression | ArrayLiteral | ObjectLiteral | FuncExpression | ArrowFunction | UnaryExpression | BinaryExpression | ConditionalExpression | CallExpression | NewExpression | MemberExpression | IndexExpression | ElementExpression | DecoratorMember | AsExpression | GoExpression | ChanExpression | StreamChanExpression | QueueExpression | TopicExpression | DecodeExpression | TryExpression | ConversionExpression | MakeExpression | NonNullExpression | TaggedTemplateExpression;
|
|
5
|
+
/** `user!`: the value is taken not to be null, as in TypeScript; nothing is checked at runtime. */
|
|
6
|
+
export interface NonNullExpression extends NodeBase {
|
|
7
|
+
kind: 'NonNullExpression';
|
|
8
|
+
expression: Expression;
|
|
9
|
+
}
|
|
10
|
+
/** sql`select ... ${id}`: the function gets the strings and the values, as in JS. */
|
|
11
|
+
export interface TaggedTemplateExpression extends NodeBase {
|
|
12
|
+
kind: 'TaggedTemplateExpression';
|
|
13
|
+
tag: Expression;
|
|
14
|
+
quasi: TemplateLiteral;
|
|
15
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* `[]byte("rook")`: the UTF-8 bytes of a string. `string(data)`, the way back, is a call, since
|
|
7
18
|
* `string` may be the name of a value.
|
|
@@ -156,6 +167,8 @@ export interface Property extends NodeBase {
|
|
|
156
167
|
key: Identifier | StringLiteral;
|
|
157
168
|
value: Expression;
|
|
158
169
|
shorthand: boolean;
|
|
170
|
+
/** `fetch(req Request) Response { ... }`: a method, whose value is a FuncExpression. */
|
|
171
|
+
method?: true;
|
|
159
172
|
}
|
|
160
173
|
/** `...xs` in array literals, object literals and call arguments. */
|
|
161
174
|
export interface SpreadElement extends NodeBase {
|
package/dist/ast/markup.d.ts
CHANGED
|
@@ -101,6 +101,8 @@ export interface NullableType extends NodeBase {
|
|
|
101
101
|
export interface FuncType extends NodeBase {
|
|
102
102
|
kind: 'FuncType';
|
|
103
103
|
params: TypeNode[];
|
|
104
|
+
/** `func(string, ...[]any)`: the array of the arguments after the others. */
|
|
105
|
+
rest?: TypeNode;
|
|
104
106
|
results: TypeNode[];
|
|
105
107
|
/** `func(yield func(T) bool)`: its one parameter is named `yield`, so it is an iterator. */
|
|
106
108
|
iterator?: boolean;
|
package/dist/ast/statements.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ClassDeclaration, ComponentDeclaration, DecoratorDeclaration, FuncDeclaration, ImportDeclaration, InterfaceDeclaration, NodeBase, TypeAliasDeclaration, VariableDeclaration } from './declarations.ts';
|
|
1
|
+
import type { ClassDeclaration, ComponentDeclaration, DecoratorDeclaration, ExportFromDeclaration, FuncDeclaration, ImportDeclaration, InterfaceDeclaration, NodeBase, TypeAliasDeclaration, VariableDeclaration } from './declarations.ts';
|
|
2
2
|
import type { CallExpression, Expression, Identifier, UnaryExpression } from './expressions.ts';
|
|
3
3
|
import type { JsxElementStatement } from './markup.ts';
|
|
4
|
-
export type Statement = ImportDeclaration | FuncDeclaration | ComponentDeclaration | DecoratorDeclaration | VariableDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | BlockStatement | ExpressionStatement | AssignmentStatement | IncDecStatement | ReturnStatement | IfStatement | ForStatement | ForInStatement | SwitchStatement | BreakStatement | ContinueStatement | ThrowStatement | TryStatement | DeferStatement | MountStatement | EffectStatement | StyleStatement | DeleteStatement | JsxElementStatement | SendStatement | SelectStatement;
|
|
4
|
+
export type Statement = ImportDeclaration | ExportFromDeclaration | FuncDeclaration | ComponentDeclaration | DecoratorDeclaration | VariableDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | BlockStatement | ExpressionStatement | AssignmentStatement | IncDecStatement | ReturnStatement | IfStatement | ForStatement | ForInStatement | SwitchStatement | BreakStatement | ContinueStatement | ThrowStatement | TryStatement | DeferStatement | MountStatement | EffectStatement | StyleStatement | DeleteStatement | JsxElementStatement | SendStatement | SelectStatement;
|
|
5
5
|
/** Statements allowed in the `init` and `update` parts of a `for` header. */
|
|
6
6
|
export type SimpleStatement = VariableDeclaration | ExpressionStatement | AssignmentStatement | IncDecStatement | DeleteStatement | SendStatement;
|
|
7
7
|
/**
|