diff options
Diffstat (limited to 'docs/dev')
| -rw-r--r-- | docs/dev/architecture.md | 15 | ||||
| -rw-r--r-- | docs/dev/lsp-extensions.md | 2 | ||||
| -rw-r--r-- | docs/dev/style.md | 12 | ||||
| -rw-r--r-- | docs/dev/syntax.md | 29 |
4 files changed, 31 insertions, 27 deletions
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index feda20dd7..e97e082fc 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md | |||
| @@ -115,7 +115,7 @@ This is important because it is possible to useful tooling using only syntax tre | |||
| 115 | Without semantic information, you don't need to be able to _build_ code, which makes the tooling more robust. | 115 | Without semantic information, you don't need to be able to _build_ code, which makes the tooling more robust. |
| 116 | See also https://web.stanford.edu/~mlfbrown/paper.pdf. | 116 | See also https://web.stanford.edu/~mlfbrown/paper.pdf. |
| 117 | You can view the `syntax` crate as an entry point to rust-analyzer. | 117 | You can view the `syntax` crate as an entry point to rust-analyzer. |
| 118 | `sytax` crate is an **API Boundary**. | 118 | `syntax` crate is an **API Boundary**. |
| 119 | 119 | ||
| 120 | **Architecture Invariant:** syntax tree is a value type. | 120 | **Architecture Invariant:** syntax tree is a value type. |
| 121 | The tree is fully determined by the contents of its syntax nodes, it doesn't need global context (like an interner) and doesn't store semantic info. | 121 | The tree is fully determined by the contents of its syntax nodes, it doesn't need global context (like an interner) and doesn't store semantic info. |
| @@ -198,14 +198,14 @@ It is an **API Boundary**. | |||
| 198 | If you want to use IDE parts of rust-analyzer via LSP, custom flatbuffers-based protocol or just as a library in your text editor, this is the right API. | 198 | If you want to use IDE parts of rust-analyzer via LSP, custom flatbuffers-based protocol or just as a library in your text editor, this is the right API. |
| 199 | 199 | ||
| 200 | **Architecture Invariant:** `ide` crate's API is build out of POD types with public fields. | 200 | **Architecture Invariant:** `ide` crate's API is build out of POD types with public fields. |
| 201 | The API uses editor's terminology, it talks about offsets and string labels rathe than in terms of definitions or types. | 201 | The API uses editor's terminology, it talks about offsets and string labels rather than in terms of definitions or types. |
| 202 | It is effectively the view in MVC and viewmodel in [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel). | 202 | It is effectively the view in MVC and viewmodel in [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel). |
| 203 | All arguments and return types are conceptually serializable. | 203 | All arguments and return types are conceptually serializable. |
| 204 | In particular, syntax tress and and hir types are generally absent from the API (but are used heavily in the implementation). | 204 | In particular, syntax tress and and hir types are generally absent from the API (but are used heavily in the implementation). |
| 205 | Shout outs to LSP developers for popularizing the idea that "UI" is a good place to draw a boundary at. | 205 | Shout outs to LSP developers for popularizing the idea that "UI" is a good place to draw a boundary at. |
| 206 | 206 | ||
| 207 | `ide` is also the first crate which has the notion of change over time. | 207 | `ide` is also the first crate which has the notion of change over time. |
| 208 | `AnalysisHost` is a state to which you can transactonally `apply_change`. | 208 | `AnalysisHost` is a state to which you can transactionally `apply_change`. |
| 209 | `Analysis` is an immutable snapshot of the state. | 209 | `Analysis` is an immutable snapshot of the state. |
| 210 | 210 | ||
| 211 | Internally, `ide` is split across several crates. `ide_assists`, `ide_completion` and `ide_ssr` implement large isolated features. | 211 | Internally, `ide` is split across several crates. `ide_assists`, `ide_completion` and `ide_ssr` implement large isolated features. |
| @@ -254,6 +254,10 @@ A single `rust-analyzer` process can serve many projects, so it is important tha | |||
| 254 | These crates implement macros as token tree -> token tree transforms. | 254 | These crates implement macros as token tree -> token tree transforms. |
| 255 | They are independent from the rest of the code. | 255 | They are independent from the rest of the code. |
| 256 | 256 | ||
| 257 | ### `crates/cfg` | ||
| 258 | |||
| 259 | This crate is responsible for parsing, evaluation and general definition of `cfg` attributes. | ||
| 260 | |||
| 257 | ### `crates/vfs`, `crates/vfs-notify` | 261 | ### `crates/vfs`, `crates/vfs-notify` |
| 258 | 262 | ||
| 259 | These crates implement a virtual fils system. | 263 | These crates implement a virtual fils system. |
| @@ -265,7 +269,8 @@ For this reason, all path APIs generally take some existing path as a "file syst | |||
| 265 | 269 | ||
| 266 | ### `crates/stdx` | 270 | ### `crates/stdx` |
| 267 | 271 | ||
| 268 | This crate contains various non-rust-analyzer specific utils, which could have been in std. | 272 | This crate contains various non-rust-analyzer specific utils, which could have been in std, as well |
| 273 | as copies of unstable std items we would like to make use of already, like `std::str::split_once`. | ||
| 269 | 274 | ||
| 270 | ### `crates/profile` | 275 | ### `crates/profile` |
| 271 | 276 | ||
| @@ -285,7 +290,7 @@ There are tests to check that the generated code is fresh. | |||
| 285 | 290 | ||
| 286 | In particular, we generate: | 291 | In particular, we generate: |
| 287 | 292 | ||
| 288 | * API for working with syntax trees (`syntax::ast`, the `ungrammar` crate). | 293 | * API for working with syntax trees (`syntax::ast`, the [`ungrammar`](https://github.com/rust-analyzer/ungrammar) crate). |
| 289 | * Various sections of the manual: | 294 | * Various sections of the manual: |
| 290 | 295 | ||
| 291 | * features | 296 | * features |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index d7f287894..b2defa737 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
| @@ -238,7 +238,7 @@ As proper cursor positioning is raison-d'etat for `onEnter`, it uses `SnippetTex | |||
| 238 | * How to deal with synchronicity of the request? | 238 | * How to deal with synchronicity of the request? |
| 239 | One option is to require the client to block until the server returns the response. | 239 | One option is to require the client to block until the server returns the response. |
| 240 | Another option is to do a OT-style merging of edits from client and server. | 240 | Another option is to do a OT-style merging of edits from client and server. |
| 241 | A third option is to do a record-replay: client applies heuristic on enter immediatelly, then applies all user's keypresses. | 241 | A third option is to do a record-replay: client applies heuristic on enter immediately, then applies all user's keypresses. |
| 242 | When the server is ready with the response, the client rollbacks all the changes and applies the recorded actions on top of the correct response. | 242 | When the server is ready with the response, the client rollbacks all the changes and applies the recorded actions on top of the correct response. |
| 243 | * How to deal with multiple carets? | 243 | * How to deal with multiple carets? |
| 244 | * Should we extend this to arbitrary typed events and not just `onEnter`? | 244 | * Should we extend this to arbitrary typed events and not just `onEnter`? |
diff --git a/docs/dev/style.md b/docs/dev/style.md index e2f1b6996..0482bc190 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md | |||
| @@ -159,7 +159,7 @@ Express function preconditions in types and force the caller to provide them (ra | |||
| 159 | 159 | ||
| 160 | ```rust | 160 | ```rust |
| 161 | // GOOD | 161 | // GOOD |
| 162 | fn frbonicate(walrus: Walrus) { | 162 | fn frobnicate(walrus: Walrus) { |
| 163 | ... | 163 | ... |
| 164 | } | 164 | } |
| 165 | 165 | ||
| @@ -374,7 +374,7 @@ Avoid making a lot of code type parametric, *especially* on the boundaries betwe | |||
| 374 | 374 | ||
| 375 | ```rust | 375 | ```rust |
| 376 | // GOOD | 376 | // GOOD |
| 377 | fn frbonicate(f: impl FnMut()) { | 377 | fn frobnicate(f: impl FnMut()) { |
| 378 | frobnicate_impl(&mut f) | 378 | frobnicate_impl(&mut f) |
| 379 | } | 379 | } |
| 380 | fn frobnicate_impl(f: &mut dyn FnMut()) { | 380 | fn frobnicate_impl(f: &mut dyn FnMut()) { |
| @@ -382,7 +382,7 @@ fn frobnicate_impl(f: &mut dyn FnMut()) { | |||
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | // BAD | 384 | // BAD |
| 385 | fn frbonicate(f: impl FnMut()) { | 385 | fn frobnicate(f: impl FnMut()) { |
| 386 | // lots of code | 386 | // lots of code |
| 387 | } | 387 | } |
| 388 | ``` | 388 | ``` |
| @@ -391,11 +391,11 @@ Avoid `AsRef` polymorphism, it pays back only for widely used libraries: | |||
| 391 | 391 | ||
| 392 | ```rust | 392 | ```rust |
| 393 | // GOOD | 393 | // GOOD |
| 394 | fn frbonicate(f: &Path) { | 394 | fn frobnicate(f: &Path) { |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | // BAD | 397 | // BAD |
| 398 | fn frbonicate(f: impl AsRef<Path>) { | 398 | fn frobnicate(f: impl AsRef<Path>) { |
| 399 | } | 399 | } |
| 400 | ``` | 400 | ``` |
| 401 | 401 | ||
| @@ -705,7 +705,7 @@ fn foo() -> Option<Bar> { | |||
| 705 | } | 705 | } |
| 706 | ``` | 706 | ``` |
| 707 | 707 | ||
| 708 | **Rationale:** reduce congnitive stack usage. | 708 | **Rationale:** reduce cognitive stack usage. |
| 709 | 709 | ||
| 710 | ## Comparisons | 710 | ## Comparisons |
| 711 | 711 | ||
diff --git a/docs/dev/syntax.md b/docs/dev/syntax.md index 1edafab68..737cc7a72 100644 --- a/docs/dev/syntax.md +++ b/docs/dev/syntax.md | |||
| @@ -92,19 +92,18 @@ [email protected] | |||
| 92 | [email protected] ")" | 92 | [email protected] ")" |
| 93 | [email protected] " " | 93 | [email protected] " " |
| 94 | [email protected] | 94 | [email protected] |
| 95 | [email protected] | 95 | [email protected] "{" |
| 96 | [email protected] "{" | 96 | [email protected] " " |
| 97 | [email protected] " " | 97 | [email protected] |
| 98 | [email protected] | 98 | [email protected] |
| 99 | [email protected] | 99 | [email protected] "90" |
| 100 | [email protected] "90" | 100 | [email protected] " " |
| 101 | [email protected] " " | 101 | [email protected] "+" |
| 102 | [email protected] "+" | 102 | [email protected] " " |
| 103 | [email protected] " " | 103 | [email protected] |
| 104 | [email protected] | 104 | [email protected] "2" |
| 105 | [email protected] "2" | 105 | [email protected] " " |
| 106 | [email protected] " " | 106 | [email protected] "}" |
| 107 | [email protected] "}" | ||
| 108 | ``` | 107 | ``` |
| 109 | 108 | ||
| 110 | #### Optimizations | 109 | #### Optimizations |
| @@ -387,7 +386,7 @@ trait HasVisibility: AstNode { | |||
| 387 | fn visibility(&self) -> Option<Visibility>; | 386 | fn visibility(&self) -> Option<Visibility>; |
| 388 | } | 387 | } |
| 389 | 388 | ||
| 390 | impl HasVisbility for FnDef { | 389 | impl HasVisibility for FnDef { |
| 391 | fn visibility(&self) -> Option<Visibility> { | 390 | fn visibility(&self) -> Option<Visibility> { |
| 392 | self.syntax.children().find_map(Visibility::cast) | 391 | self.syntax.children().find_map(Visibility::cast) |
| 393 | } | 392 | } |
| @@ -527,7 +526,7 @@ In practice, incremental reparsing doesn't actually matter much for IDE use-case | |||
| 527 | 526 | ||
| 528 | ### Parsing Algorithm | 527 | ### Parsing Algorithm |
| 529 | 528 | ||
| 530 | We use a boring hand-crafted recursive descent + pratt combination, with a special effort of continuting the parsing if an error is detected. | 529 | We use a boring hand-crafted recursive descent + pratt combination, with a special effort of continuing the parsing if an error is detected. |
| 531 | 530 | ||
| 532 | ### Parser Recap | 531 | ### Parser Recap |
| 533 | 532 | ||
