diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/dev/architecture.md | 13 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 14 | ||||
-rw-r--r-- | docs/dev/style.md | 10 | ||||
-rw-r--r-- | docs/dev/syntax.md | 8 |
4 files changed, 23 insertions, 22 deletions
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index fb991133a..3ffd9e8cb 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md | |||
@@ -42,7 +42,7 @@ The underlying engine makes sure that model is computed lazily (on-demand) and c | |||
42 | ## Entry Points | 42 | ## Entry Points |
43 | 43 | ||
44 | `crates/rust-analyzer/src/bin/main.rs` contains the main function which spawns LSP. | 44 | `crates/rust-analyzer/src/bin/main.rs` contains the main function which spawns LSP. |
45 | This is *the* entry point, but it front-loads a lot of complexity, so its fine to just skim through it. | 45 | This is *the* entry point, but it front-loads a lot of complexity, so it's fine to just skim through it. |
46 | 46 | ||
47 | `crates/rust-analyzer/src/handlers.rs` implements all LSP requests and is a great place to start if you are already familiar with LSP. | 47 | `crates/rust-analyzer/src/handlers.rs` implements all LSP requests and is a great place to start if you are already familiar with LSP. |
48 | 48 | ||
@@ -67,7 +67,7 @@ They are handled by Rust code in the xtask directory. | |||
67 | 67 | ||
68 | VS Code plugin. | 68 | VS Code plugin. |
69 | 69 | ||
70 | ### `libs/` | 70 | ### `lib/` |
71 | 71 | ||
72 | rust-analyzer independent libraries which we publish to crates.io. | 72 | rust-analyzer independent libraries which we publish to crates.io. |
73 | It's not heavily utilized at the moment. | 73 | It's not heavily utilized at the moment. |
@@ -139,7 +139,8 @@ If an AST method returns an `Option`, it *can* be `None` at runtime, even if thi | |||
139 | ### `crates/base_db` | 139 | ### `crates/base_db` |
140 | 140 | ||
141 | We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and on-demand computation. | 141 | We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and on-demand computation. |
142 | Roughly, you can think of salsa as a key-value store, but it can also compute derived values using specified functions. The `base_db` crate provides basic infrastructure for interacting with salsa. | 142 | Roughly, you can think of salsa as a key-value store, but it can also compute derived values using specified functions. |
143 | The `base_db` crate provides basic infrastructure for interacting with salsa. | ||
143 | Crucially, it defines most of the "input" queries: facts supplied by the client of the analyzer. | 144 | Crucially, it defines most of the "input" queries: facts supplied by the client of the analyzer. |
144 | Reading the docs of the `base_db::input` module should be useful: everything else is strictly derived from those inputs. | 145 | Reading the docs of the `base_db::input` module should be useful: everything else is strictly derived from those inputs. |
145 | 146 | ||
@@ -221,7 +222,7 @@ Internally, `ide` is split across several crates. `ide_assists`, `ide_completion | |||
221 | The `ide` contains a public API/façade, as well as implementation for a plethora of smaller features. | 222 | The `ide` contains a public API/façade, as well as implementation for a plethora of smaller features. |
222 | 223 | ||
223 | **Architecture Invariant:** `ide` crate strives to provide a _perfect_ API. | 224 | **Architecture Invariant:** `ide` crate strives to provide a _perfect_ API. |
224 | Although at the moment it has only one consumer, the LSP server, LSP *does not* influence it's API design. | 225 | Although at the moment it has only one consumer, the LSP server, LSP *does not* influence its API design. |
225 | Instead, we keep in mind a hypothetical _ideal_ client -- an IDE tailored specifically for rust, every nook and cranny of which is packed with Rust-specific goodies. | 226 | Instead, we keep in mind a hypothetical _ideal_ client -- an IDE tailored specifically for rust, every nook and cranny of which is packed with Rust-specific goodies. |
226 | 227 | ||
227 | ### `crates/rust-analyzer` | 228 | ### `crates/rust-analyzer` |
@@ -307,7 +308,7 @@ This sections talks about the things which are everywhere and nowhere in particu | |||
307 | 308 | ||
308 | ### Code generation | 309 | ### Code generation |
309 | 310 | ||
310 | Some of the components of this repository are generated through automatic processes. | 311 | Some ]components in this repository are generated through automatic processes. |
311 | Generated code is updated automatically on `cargo test`. | 312 | Generated code is updated automatically on `cargo test`. |
312 | Generated code is generally committed to the git repository. | 313 | Generated code is generally committed to the git repository. |
313 | 314 | ||
@@ -389,7 +390,7 @@ fn spam() { | |||
389 | ``` | 390 | ``` |
390 | 391 | ||
391 | To specify input data, we use a single string literal in a special format, which can describe a set of rust files. | 392 | To specify input data, we use a single string literal in a special format, which can describe a set of rust files. |
392 | See the `Fixture` type. | 393 | See the `Fixture` its module for fixture examples and documentation. |
393 | 394 | ||
394 | **Architecture Invariant:** all code invariants are tested by `#[test]` tests. | 395 | **Architecture Invariant:** all code invariants are tested by `#[test]` tests. |
395 | There's no additional checks in CI, formatting and tidy tests are run with `cargo test`. | 396 | There's no additional checks in CI, formatting and tidy tests are run with `cargo test`. |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 989771ac6..a46121bb2 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -51,8 +51,8 @@ interface SnippetTextEdit extends TextEdit { | |||
51 | 51 | ||
52 | ```typescript | 52 | ```typescript |
53 | export interface TextDocumentEdit { | 53 | export interface TextDocumentEdit { |
54 | textDocument: OptionalVersionedTextDocumentIdentifier; | 54 | textDocument: OptionalVersionedTextDocumentIdentifier; |
55 | edits: (TextEdit | SnippetTextEdit)[]; | 55 | edits: (TextEdit | SnippetTextEdit)[]; |
56 | } | 56 | } |
57 | ``` | 57 | ``` |
58 | 58 | ||
@@ -145,9 +145,9 @@ mod foo; | |||
145 | ### Unresolved Question | 145 | ### Unresolved Question |
146 | 146 | ||
147 | * An alternative would be to use a more general "gotoSuper" request, which would work for super methods, super classes and super modules. | 147 | * An alternative would be to use a more general "gotoSuper" request, which would work for super methods, super classes and super modules. |
148 | This is the approach IntelliJ Rust is takeing. | 148 | This is the approach IntelliJ Rust is taking. |
149 | However, experience shows that super module (which generally has a feeling of navigation between files) should be separate. | 149 | However, experience shows that super module (which generally has a feeling of navigation between files) should be separate. |
150 | If you want super module, but the cursor happens to be inside an overriden function, the behavior with single "gotoSuper" request is surprising. | 150 | If you want super module, but the cursor happens to be inside an overridden function, the behavior with single "gotoSuper" request is surprising. |
151 | 151 | ||
152 | ## Join Lines | 152 | ## Join Lines |
153 | 153 | ||
@@ -193,7 +193,7 @@ fn main() { | |||
193 | ### Unresolved Question | 193 | ### Unresolved Question |
194 | 194 | ||
195 | * What is the position of the cursor after `joinLines`? | 195 | * What is the position of the cursor after `joinLines`? |
196 | Currently this is left to editor's discretion, but it might be useful to specify on the server via snippets. | 196 | Currently, this is left to editor's discretion, but it might be useful to specify on the server via snippets. |
197 | However, it then becomes unclear how it works with multi cursor. | 197 | However, it then becomes unclear how it works with multi cursor. |
198 | 198 | ||
199 | ## On Enter | 199 | ## On Enter |
@@ -330,7 +330,7 @@ Moreover, it would be cool if editors didn't need to implement even basic langua | |||
330 | 330 | ||
331 | ### Unresolved Question | 331 | ### Unresolved Question |
332 | 332 | ||
333 | * Should we return a a nested brace structure, to allow paredit-like actions of jump *out* of the current brace pair? | 333 | * Should we return a nested brace structure, to allow paredit-like actions of jump *out* of the current brace pair? |
334 | This is how `SelectionRange` request works. | 334 | This is how `SelectionRange` request works. |
335 | * Alternatively, should we perhaps flag certain `SelectionRange`s as being brace pairs? | 335 | * Alternatively, should we perhaps flag certain `SelectionRange`s as being brace pairs? |
336 | 336 | ||
@@ -511,7 +511,7 @@ Expands macro call at a given position. | |||
511 | This request is sent from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types. | 511 | This request is sent from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types. |
512 | Generally, the client should re-query inlay hints after every modification. | 512 | Generally, the client should re-query inlay hints after every modification. |
513 | Note that we plan to move this request to `experimental/inlayHints`, as it is not really Rust-specific, but the current API is not necessary the right one. | 513 | Note that we plan to move this request to `experimental/inlayHints`, as it is not really Rust-specific, but the current API is not necessary the right one. |
514 | Upstream issue: https://github.com/microsoft/language-server-protocol/issues/956 | 514 | Upstream issues: https://github.com/microsoft/language-server-protocol/issues/956 , https://github.com/rust-analyzer/rust-analyzer/issues/2797 |
515 | 515 | ||
516 | **Request:** | 516 | **Request:** |
517 | 517 | ||
diff --git a/docs/dev/style.md b/docs/dev/style.md index 48ce4b92a..468dedff2 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md | |||
@@ -53,9 +53,9 @@ https://www.tedinski.com/2018/02/06/system-boundaries.html | |||
53 | ## Crates.io Dependencies | 53 | ## Crates.io Dependencies |
54 | 54 | ||
55 | We try to be very conservative with usage of crates.io dependencies. | 55 | We try to be very conservative with usage of crates.io dependencies. |
56 | Don't use small "helper" crates (exception: `itertools` is allowed). | 56 | Don't use small "helper" crates (exception: `itertools` and `either` are allowed). |
57 | If there's some general reusable bit of code you need, consider adding it to the `stdx` crate. | 57 | If there's some general reusable bit of code you need, consider adding it to the `stdx` crate. |
58 | A useful exercise is to read Cargo.lock and see if some of the *transitive* dependencies do not make sense for rust-analyzer. | 58 | A useful exercise is to read Cargo.lock and see if some *transitive* dependencies do not make sense for rust-analyzer. |
59 | 59 | ||
60 | **Rationale:** keep compile times low, create ecosystem pressure for faster compiles, reduce the number of things which might break. | 60 | **Rationale:** keep compile times low, create ecosystem pressure for faster compiles, reduce the number of things which might break. |
61 | 61 | ||
@@ -330,7 +330,7 @@ When implementing `do_thing`, it might be very useful to create a context object | |||
330 | 330 | ||
331 | ```rust | 331 | ```rust |
332 | pub fn do_thing(arg1: Arg1, arg2: Arg2) -> Res { | 332 | pub fn do_thing(arg1: Arg1, arg2: Arg2) -> Res { |
333 | let mut ctx = Ctx { arg1, arg2 } | 333 | let mut ctx = Ctx { arg1, arg2 }; |
334 | ctx.run() | 334 | ctx.run() |
335 | } | 335 | } |
336 | 336 | ||
@@ -586,7 +586,7 @@ use super::{} | |||
586 | 586 | ||
587 | **Rationale:** consistency. | 587 | **Rationale:** consistency. |
588 | Reading order is important for new contributors. | 588 | Reading order is important for new contributors. |
589 | Grouping by crate allows to spot unwanted dependencies easier. | 589 | Grouping by crate allows spotting unwanted dependencies easier. |
590 | 590 | ||
591 | ## Import Style | 591 | ## Import Style |
592 | 592 | ||
@@ -779,7 +779,7 @@ assert!(x < y); | |||
779 | assert!(x > 0); | 779 | assert!(x > 0); |
780 | 780 | ||
781 | // BAD | 781 | // BAD |
782 | assert!(x >= lo && x <= hi>); | 782 | assert!(x >= lo && x <= hi); |
783 | assert!(r1 < l2 || l1 > r2); | 783 | assert!(r1 < l2 || l1 > r2); |
784 | assert!(y > x); | 784 | assert!(y > x); |
785 | assert!(0 > x); | 785 | assert!(0 > x); |
diff --git a/docs/dev/syntax.md b/docs/dev/syntax.md index 737cc7a72..f7a0c09fc 100644 --- a/docs/dev/syntax.md +++ b/docs/dev/syntax.md | |||
@@ -145,7 +145,7 @@ Another alternative (used by swift and roslyn) is to explicitly divide the set o | |||
145 | 145 | ||
146 | ```rust | 146 | ```rust |
147 | struct Token { | 147 | struct Token { |
148 | kind: NonTriviaTokenKind | 148 | kind: NonTriviaTokenKind, |
149 | text: String, | 149 | text: String, |
150 | leading_trivia: Vec<TriviaToken>, | 150 | leading_trivia: Vec<TriviaToken>, |
151 | trailing_trivia: Vec<TriviaToken>, | 151 | trailing_trivia: Vec<TriviaToken>, |
@@ -240,7 +240,7 @@ impl SyntaxNode { | |||
240 | let child_offset = offset; | 240 | let child_offset = offset; |
241 | offset += green_child.text_len; | 241 | offset += green_child.text_len; |
242 | Arc::new(SyntaxData { | 242 | Arc::new(SyntaxData { |
243 | offset: child_offset; | 243 | offset: child_offset, |
244 | parent: Some(Arc::clone(self)), | 244 | parent: Some(Arc::clone(self)), |
245 | green: Arc::clone(green_child), | 245 | green: Arc::clone(green_child), |
246 | }) | 246 | }) |
@@ -249,7 +249,7 @@ impl SyntaxNode { | |||
249 | } | 249 | } |
250 | 250 | ||
251 | impl PartialEq for SyntaxNode { | 251 | impl PartialEq for SyntaxNode { |
252 | fn eq(&self, other: &SyntaxNode) { | 252 | fn eq(&self, other: &SyntaxNode) -> bool { |
253 | self.offset == other.offset | 253 | self.offset == other.offset |
254 | && Arc::ptr_eq(&self.green, &other.green) | 254 | && Arc::ptr_eq(&self.green, &other.green) |
255 | } | 255 | } |
@@ -273,7 +273,7 @@ This is OK because trees traversals mostly (always, in case of rust-analyzer) ru | |||
273 | The other thread can restore the `SyntaxNode` by traversing from the root green node and looking for a node with specified range. | 273 | The other thread can restore the `SyntaxNode` by traversing from the root green node and looking for a node with specified range. |
274 | You can also use the similar trick to store a `SyntaxNode`. | 274 | You can also use the similar trick to store a `SyntaxNode`. |
275 | That is, a data structure that holds a `(GreenNode, Range<usize>)` will be `Sync`. | 275 | That is, a data structure that holds a `(GreenNode, Range<usize>)` will be `Sync`. |
276 | However rust-analyzer goes even further. | 276 | However, rust-analyzer goes even further. |
277 | It treats trees as semi-transient and instead of storing a `GreenNode`, it generally stores just the id of the file from which the tree originated: `(FileId, Range<usize>)`. | 277 | It treats trees as semi-transient and instead of storing a `GreenNode`, it generally stores just the id of the file from which the tree originated: `(FileId, Range<usize>)`. |
278 | The `SyntaxNode` is the restored by reparsing the file and traversing it from root. | 278 | The `SyntaxNode` is the restored by reparsing the file and traversing it from root. |
279 | With this trick, rust-analyzer holds only a small amount of trees in memory at the same time, which reduces memory usage. | 279 | With this trick, rust-analyzer holds only a small amount of trees in memory at the same time, which reduces memory usage. |