aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARCHITECTURE.md133
-rw-r--r--CONTRIBUTING.md64
-rw-r--r--README.md88
3 files changed, 152 insertions, 133 deletions
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 000000000..b497cc5d7
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,133 @@
1# Architecture
2
3This document describes high-level architecture of rust-analyzer.
4If you want to familiarize yourself with the code base, you are just
5in the right place!
6
7
8## Code generation
9
10Some of the components of this repository are generated through automatic
11processes. These are outlined below:
12
13- `gen-kinds`: The kinds of tokens are reused in several places, so a generator
14 is used. We use tera templates to generate the files listed below, based on
15 the grammar described in [grammar.ron]:
16 - [ast/generated.rs][ast generated] in `ra_syntax` based on
17 [ast/generated.tera.rs][ast source]
18 - [syntax_kinds/generated.rs][syntax_kinds generated] in `ra_syntax` based on
19 [syntax_kinds/generated.tera.rs][syntax_kinds source]
20
21[tera]: https://tera.netlify.com/
22[grammar.ron]: ./crates/ra_syntax/src/grammar.ron
23[ast generated]: ./crates/ra_syntax/src/ast/generated.rs
24[ast source]: ./crates/ra_syntax/src/ast/generated.rs.tera
25[syntax_kinds generated]: ./crates/ra_syntax/src/syntax_kinds/generated.rs
26[syntax_kinds source]: ./crates/ra_syntax/src/syntax_kinds/generated.rs.tera
27
28
29## Code Walk-Through
30
31### `crates/ra_syntax`
32
33Rust syntax tree structure and parser. See
34[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design
35notes.
36
37- [rowan](https://github.com/rust-analyzer/rowan) library is used for constructing syntax trees.
38- `grammar` module is the actual parser. It is a hand-written recursive descent parsers, which
39 produces a sequence of events like "start node X", "finish not Y". It works similarly to [kotlin parser](https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java),
40 which is a good source for inspiration for dealing with syntax errors and incomplete input. Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs)
41 is what we use for the definition of the Rust language.
42- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `rowan` trees.
43 This is the thing that turns a flat list of events into a tree (see `EventProcessor`)
44- `ast` a type safe API on top of the raw `rowan` tree.
45- `grammar.ron` RON description of the grammar, which is used to
46 generate `syntax_kinds` and `ast` modules, using `cargo gen-kinds` command.
47- `algo`: generic tree algorithms, including `walk` for O(1) stack
48 space tree traversal (this is cool) and `visit` for type-driven
49 visiting the nodes (this is double plus cool, if you understand how
50 `Visitor` works, you understand rust-analyzer).
51
52Test for ra_syntax are mostly data-driven: `tests/data/parser` contains a bunch of `.rs`
53(test vectors) and `.txt` files with corresponding syntax trees. During testing, we check
54`.rs` against `.txt`. If the `.txt` file is missing, it is created (this is how you update
55tests). Additionally, running `cargo gen-tests` will walk the grammar module and collect
56all `//test test_name` comments into files inside `tests/data` directory.
57
58See [#93](https://github.com/rust-analyzer/rust-analyzer/pull/93) for an example PR which
59fixes a bug in the grammar.
60
61
62### `crates/ra_editor`
63
64All IDE features which can be implemented if you only have access to a
65single file. `ra_editor` could be used to enhance editing of Rust code
66without the need to fiddle with build-systems, file
67synchronization and such.
68
69In a sense, `ra_editor` is just a bunch of pure functions which take a
70syntax tree as an input.
71
72The tests for `ra_editor` are `#[cfg(test)] mod tests` unit-tests spread
73throughout its modules.
74
75### `crates/salsa`
76
77An implementation of red-green incremental compilation algorithm from
78rust compiler. It makes all rust-analyzer features on-demand. To be replaced
79with `salsa-rs/salsa` soon.
80
81
82### `crates/ra_analysis`
83
84A stateful library for analyzing many Rust files as they change.
85`AnalysisHost` is a mutable entity (clojure's atom) which holds
86current state, incorporates changes and handles out `Analysis` --- an
87immutable consistent snapshot of world state at a point in time, which
88actually powers analysis.
89
90
91### `crates/ra_lsp_server`
92
93An LSP implementation which uses `ra_analysis` for managing state and
94`ra_editor` for actually doing useful stuff.
95
96See [#79](https://github.com/rust-analyzer/rust-analyzer/pull/79/) as an
97example of PR which adds a new feature to `ra_editor` and exposes it
98to `ra_lsp_server`.
99
100
101### `crates/cli`
102
103A CLI interface to rust-analyzer.
104
105### `crate/tools`
106
107Custom Cargo tasks used to develop rust-analyzer:
108
109- `cargo gen-kinds` -- generate `ast` and `syntax_kinds`
110- `cargo gen-tests` -- collect inline tests from grammar
111- `cargo install-code` -- build and install VS Code extension and server
112
113### `editors/code`
114
115VS Code plugin
116
117
118## Common workflows
119
120To try out VS Code extensions, run `cargo install-code`. This installs both the
121`ra_lsp_server` binary and VS Code extension. To install only the binary, `use
122cargo install --path crates/ra_lsp_server --force`
123
124To see logs from the language server, set `RUST_LOG=info` env variable. To see
125all communication between the server and the client, use
126`RUST_LOG=gen_lsp_server=debug` (will print quite a bit of stuff).
127
128To run tests, just `cargo test`.
129
130To work on VS Code extension, launch code inside `editors/code` and use `F5` to
131launch/debug. To automatically apply formatter and linter suggestions, use `npm
132run fix`.
133
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c952078cf..a2efc7afa 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,58 +1,18 @@
1The project is in its early stages: contributions are welcome and would be 1The project is in its early stages: contributions are welcome and would be
2**very** helpful, but the project is not _yet_ optimized for contribution. 2**very** helpful, but the project is not _yet_ optimized for contribution.
3Moreover, it is doubly experimental, so there's no guarantee that any work here 3Moreover, it is doubly experimental, so there's no guarantee that any work here
4would reach production. That said, here are some areas where contributions would 4would reach production.
5be **especially** welcome:
6 5
7- Designing internal data structures: RFC only outlines the constraints, it's an 6To get an idea of how rust-analyzer works, take a look at the [ARCHITECTURE.md](./ARCHITECTURE.md)
8 open question how to satisfy them in the optimal way. See `ARCHITECTURE.md` 7document.
9 for current design questions.
10 8
11- Porting libsyntax parser to rust-analyzer: currently rust-analyzer parses only 9Useful labels on the issue tracker:
12 a tiny subset of Rust. This should be fixed by porting parsing functions from 10 * [E-mentor](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-mentor)
13 libsyntax one by one. Take a look at the [libsyntax parser] for "what to port" 11 issues have links to the code in question and tests,
14 and at the [Kotlin parser] for "how to port". 12 * [E-easy](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy),
13 [E-medium](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-medium),
14 [E-hard](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-hard),
15 labels are *estimates* for how hard would be to write a fix.
15 16
16- Writing validators: by design, rust-analyzer is very lax about the input. For 17There's no formal PR check list: everything that passes CI (we use [bors](https://bors.tech/)) is valid,
17 example, the lexer happily accepts unclosed strings. The idea is that there 18but it's a good idea to write nice commit messages, test code thoroughly, maintain consistent style, etc.
18 should be a higher level visitor, which walks the syntax tree after parsing
19 and produces all the warnings. Alas, there's no such visitor yet :( Would you
20 like to write one? :)
21
22- Creating tests: it would be tremendously helpful to read each of libsyntax and
23 rust-analyzer parser functions and crate a small separate test cases to cover
24 each and every edge case.
25
26- Building stuff with rust-analyzer: it would be really cool to compile
27 rust-analyzer to WASM and add _client side_ syntax validation to rust
28 playground!
29
30Do take a look at the issue tracker.
31
32If you don't know where to start, or have _any_ questions or suggestions, don't
33hesitate to chat at [Gitter]!
34
35# Code generation
36
37Some of the components of this repository are generated through automatic
38processes. These are outlined below:
39
40- `gen-kinds`: The kinds of tokens are reused in several places, so a generator
41 is used. This process uses [tera] to generate, using data in [grammar.ron],
42 the files:
43 - [ast/generated.rs][ast generated] in `ra_syntax` based on
44 [ast/generated.tera.rs][ast source]
45 - [syntax_kinds/generated.rs][syntax_kinds generated] in `ra_syntax` based on
46 [syntax_kinds/generated.tera.rs][syntax_kinds source]
47
48[libsyntax parser]:
49 https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs
50[kotlin parser]:
51 https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
52[gitter]: https://gitter.im/libsyntax2/Lobby
53[tera]: https://tera.netlify.com/
54[grammar.ron]: ./crates/ra_syntax/src/grammar.ron
55[ast generated]: ./crates/ra_syntax/src/ast/generated.rs
56[ast source]: ./crates/ra_syntax/src/ast/generated.tera.rs
57[syntax_kinds generated]: ./crates/ra_syntax/src/syntax_kinds/generated.rs
58[syntax_kinds source]: ./crates/ra_syntax/src/syntax_kinds/generated.tera.rs
diff --git a/README.md b/README.md
index 481d065b0..1c6facbbd 100644
--- a/README.md
+++ b/README.md
@@ -61,99 +61,20 @@ fold:
61* to quickly bootstrap usable and useful language server: solution 61* to quickly bootstrap usable and useful language server: solution
62 that covers 80% of Rust code will be useful for IDEs, and will be 62 that covers 80% of Rust code will be useful for IDEs, and will be
63 vastly simpler than 100% solution. 63 vastly simpler than 100% solution.
64 64
65* to understand how the consumer-side of compiler API should look like 65* to understand how the consumer-side of compiler API should look like
66 (especially it's on-demand aspects). If you have 66 (especially it's on-demand aspects). If you have
67 `get_expression_type` function, you can write a ton of purely-IDE 67 `get_expression_type` function, you can write a ton of purely-IDE
68 features on top of it, even if the function is only partially 68 features on top of it, even if the function is only partially
69 correct. Plugin in the precise function afterwards should just make 69 correct. Plugin in the precise function afterwards should just make
70 IDE features more reliable. 70 IDE features more reliable.
71 71
72The long term plan is to merge with the mainline rustc compiler, 72The long term plan is to merge with the mainline rustc compiler,
73probably around the HIR boundary? That is, use rust analyzer for 73probably around the HIR boundary? That is, use rust analyzer for
74parsing, macro expansion and related bits of name resolution, but 74parsing, macro expansion and related bits of name resolution, but
75leave the rest (including type inference and trait selection) to the 75leave the rest (including type inference and trait selection) to the
76existing rustc. 76existing rustc.
77 77
78## Code Walk-Through
79
80### `crates/ra_syntax`
81
82Rust syntax tree structure and parser. See
83[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design
84notes.
85
86- `yellow`, red/green syntax tree, heavily inspired [by this](https://github.com/apple/swift/tree/ab68f0d4cbf99cdfa672f8ffe18e433fddc8b371/lib/Syntax)
87- `grammar`, the actual parser
88- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `yellow` trees
89- `grammar.ron` RON description of the grammar, which is used to
90 generate `syntax_kinds` and `ast` modules.
91- `algo`: generic tree algorithms, including `walk` for O(1) stack
92 space tree traversal (this is cool) and `visit` for type-driven
93 visiting the nodes (this is double plus cool, if you understand how
94 `Visitor` works, you understand rust-analyzer).
95
96
97### `crates/ra_editor`
98
99All IDE features which can be implemented if you only have access to a
100single file. `ra_editor` could be used to enhance editing of Rust code
101without the need to fiddle with build-systems, file
102synchronization and such.
103
104In a sense, `ra_editor` is just a bunch of pure functions which take a
105syntax tree as an input.
106
107### `crates/salsa`
108
109An implementation of red-green incremental compilation algorithm from
110rust compiler. It makes all rust-analyzer features on-demand.
111
112
113### `crates/ra_analysis`
114
115A stateful library for analyzing many Rust files as they change.
116`AnalysisHost` is a mutable entity (clojure's atom) which holds
117current state, incorporates changes and handles out `Analysis` --- an
118immutable consistent snapshot of world state at a point in time, which
119actually powers analysis.
120
121
122### `crates/ra_lsp_server`
123
124An LSP implementation which uses `ra_analysis` for managing state and
125`ra_editor` for actually doing useful stuff.
126
127
128### `crates/cli`
129
130A CLI interface to libsyntax
131
132### `crate/tools`
133
134Code-gen tasks, used to develop rust-analyzer:
135
136- `cargo gen-kinds` -- generate `ast` and `syntax_kinds`
137- `cargo gen-tests` -- collect inline tests from grammar
138- `cargo install-code` -- build and install VS Code extension and server
139
140### `editors/code`
141
142VS Code plugin
143
144
145## Performance
146
147Non-incremental, but seems pretty fast:
148
149```
150$ cargo build --release --package ra_cli
151$ wc -l ~/projects/rust/src/libsyntax/parse/parser.rs
1527546 /home/matklad/projects/rust/src/libsyntax/parse/parser.rs
153$ ./target/release/ra_cli parse < ~/projects/rust/src/libsyntax/parse/parser.rs --no-dump > /dev/null
154parsing: 21.067065ms
155```
156
157## Getting in touch 78## Getting in touch
158 79
159@matklad can be found at Rust 80@matklad can be found at Rust
@@ -161,6 +82,11 @@ parsing: 21.067065ms
161#ides-and-editors. 82#ides-and-editors.
162 83
163 84
85## Contributing
86
87See [CONTRIBUTING.md](./CONTRIBUTING.md) and [ARCHITECTURE.md](./ARCHITECTURE.md)
88
89
164## License 90## License
165 91
166Rust analyzer is primarily distributed under the terms of both the MIT 92Rust analyzer is primarily distributed under the terms of both the MIT