aboutsummaryrefslogtreecommitdiff
path: root/docs/dev
diff options
context:
space:
mode:
Diffstat (limited to 'docs/dev')
-rw-r--r--docs/dev/architecture.md11
-rw-r--r--docs/dev/lsp-extensions.md14
-rw-r--r--docs/dev/style.md10
-rw-r--r--docs/dev/syntax.md8
4 files changed, 22 insertions, 21 deletions
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index fb991133a..8a12381ab 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.
45This is *the* entry point, but it front-loads a lot of complexity, so its fine to just skim through it. 45This 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
68VS Code plugin. 68VS Code plugin.
69 69
70### `libs/` 70### `lib/`
71 71
72rust-analyzer independent libraries which we publish to crates.io. 72rust-analyzer independent libraries which we publish to crates.io.
73It's not heavily utilized at the moment. 73It'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
141We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and on-demand computation. 141We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and on-demand computation.
142Roughly, 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. 142Roughly, you can think of salsa as a key-value store, but it can also compute derived values using specified functions.
143The `base_db` crate provides basic infrastructure for interacting with salsa.
143Crucially, it defines most of the "input" queries: facts supplied by the client of the analyzer. 144Crucially, it defines most of the "input" queries: facts supplied by the client of the analyzer.
144Reading the docs of the `base_db::input` module should be useful: everything else is strictly derived from those inputs. 145Reading 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
221The `ide` contains a public API/façade, as well as implementation for a plethora of smaller features. 222The `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.
224Although at the moment it has only one consumer, the LSP server, LSP *does not* influence it's API design. 225Although at the moment it has only one consumer, the LSP server, LSP *does not* influence its API design.
225Instead, 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. 226Instead, 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
310Some of the components of this repository are generated through automatic processes. 311Some ]components in this repository are generated through automatic processes.
311Generated code is updated automatically on `cargo test`. 312Generated code is updated automatically on `cargo test`.
312Generated code is generally committed to the git repository. 313Generated code is generally committed to the git repository.
313 314
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
53export interface TextDocumentEdit { 53export 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.
511This request is sent from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types. 511This request is sent from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types.
512Generally, the client should re-query inlay hints after every modification. 512Generally, the client should re-query inlay hints after every modification.
513Note 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. 513Note 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.
514Upstream issue: https://github.com/microsoft/language-server-protocol/issues/956 514Upstream 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
55We try to be very conservative with usage of crates.io dependencies. 55We try to be very conservative with usage of crates.io dependencies.
56Don't use small "helper" crates (exception: `itertools` is allowed). 56Don't use small "helper" crates (exception: `itertools` and `either` are allowed).
57If there's some general reusable bit of code you need, consider adding it to the `stdx` crate. 57If there's some general reusable bit of code you need, consider adding it to the `stdx` crate.
58A useful exercise is to read Cargo.lock and see if some of the *transitive* dependencies do not make sense for rust-analyzer. 58A 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
332pub fn do_thing(arg1: Arg1, arg2: Arg2) -> Res { 332pub 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.
588Reading order is important for new contributors. 588Reading order is important for new contributors.
589Grouping by crate allows to spot unwanted dependencies easier. 589Grouping by crate allows spotting unwanted dependencies easier.
590 590
591## Import Style 591## Import Style
592 592
@@ -779,7 +779,7 @@ assert!(x < y);
779assert!(x > 0); 779assert!(x > 0);
780 780
781// BAD 781// BAD
782assert!(x >= lo && x <= hi>); 782assert!(x >= lo && x <= hi);
783assert!(r1 < l2 || l1 > r2); 783assert!(r1 < l2 || l1 > r2);
784assert!(y > x); 784assert!(y > x);
785assert!(0 > x); 785assert!(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
147struct Token { 147struct 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
251impl PartialEq for SyntaxNode { 251impl 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
273The other thread can restore the `SyntaxNode` by traversing from the root green node and looking for a node with specified range. 273The other thread can restore the `SyntaxNode` by traversing from the root green node and looking for a node with specified range.
274You can also use the similar trick to store a `SyntaxNode`. 274You can also use the similar trick to store a `SyntaxNode`.
275That is, a data structure that holds a `(GreenNode, Range<usize>)` will be `Sync`. 275That is, a data structure that holds a `(GreenNode, Range<usize>)` will be `Sync`.
276However rust-analyzer goes even further. 276However, rust-analyzer goes even further.
277It 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>)`. 277It 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>)`.
278The `SyntaxNode` is the restored by reparsing the file and traversing it from root. 278The `SyntaxNode` is the restored by reparsing the file and traversing it from root.
279With this trick, rust-analyzer holds only a small amount of trees in memory at the same time, which reduces memory usage. 279With this trick, rust-analyzer holds only a small amount of trees in memory at the same time, which reduces memory usage.