diff options
-rw-r--r-- | ARCHITECTURE.md | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index a6b1bf873..3b200bbc8 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md | |||
@@ -4,6 +4,33 @@ This document describes high-level architecture of rust-analyzer. | |||
4 | If you want to familiarize yourself with the code base, you are just | 4 | If you want to familiarize yourself with the code base, you are just |
5 | in the right place! | 5 | in the right place! |
6 | 6 | ||
7 | ## The Big Picture | ||
8 | |||
9 | ![](https://user-images.githubusercontent.com/1711539/50114578-e8a34280-0255-11e9-902c-7cfc70747966.png) | ||
10 | |||
11 | On the highest level, rust-analyzer is a thing which accepts input source code | ||
12 | from the client and produces a structured semantic model of the code. | ||
13 | |||
14 | More specifically, input data consists of a set of test files (`(PathBuf, | ||
15 | String)` pairs) and an information about project structure, the so called | ||
16 | `CrateGraph`. Crate graph specifies which files are crate roots, which cfg flags | ||
17 | are specified for each crate (TODO: actually implement this) and what are | ||
18 | dependencies between the crate. The analyzer keeps all these input data in | ||
19 | memory and never does any IO. Because the input data is source code, which | ||
20 | typically measures in tens of megabytes at most, keeping all input data in | ||
21 | memory is OK. | ||
22 | |||
23 | A "structured semantic model" is basically an object-oriented representations of | ||
24 | modules, functions and types which appear in the source code. This representation | ||
25 | is fully "resolved": all expressions have types, all references are bound to | ||
26 | declarations, etc. | ||
27 | |||
28 | The client can submit a small delta of input data (typically, a change to a | ||
29 | single file) and get a fresh code model which accounts for changes. | ||
30 | |||
31 | Underlying engine makes sure that model is computed lazily (on-demand) and can | ||
32 | be quickly updated for small modifications. | ||
33 | |||
7 | 34 | ||
8 | ## Code generation | 35 | ## Code generation |
9 | 36 | ||
@@ -58,27 +85,25 @@ all `//test test_name` comments into files inside `tests/data` directory. | |||
58 | See [#93](https://github.com/rust-analyzer/rust-analyzer/pull/93) for an example PR which | 85 | See [#93](https://github.com/rust-analyzer/rust-analyzer/pull/93) for an example PR which |
59 | fixes a bug in the grammar. | 86 | fixes a bug in the grammar. |
60 | 87 | ||
61 | ### `crates/ra_hir` | 88 | ### `crates/ra_db` |
62 | |||
63 | HIR (previsouly known as descriptors) provides a high-level OO acess to Rust | ||
64 | code. | ||
65 | 89 | ||
66 | The principal difference between HIR and syntax trees is that HIR is bound | 90 | We use [salsa][https://github.com/salsa-rs/salsa] crate for incremental and |
67 | to a particular crate instance. That is, it has cfg flags and features | 91 | on-demand computation. Roughly, you can think of salsa as a key-value store, but |
68 | applied. So, there relation between syntax and HIR is many-to-one. | 92 | it also can compute derived values using specified functions. The `ra_db` crate |
93 | provides a basic infrastructure for interracting with salsa. Crucially, it | ||
94 | defines most of the "input" queries: facts supplied by the client of the analyzer. | ||
69 | 95 | ||
70 | ### `crates/ra_editor` | 96 | ### `crates/ra_hir` |
71 | 97 | ||
72 | All IDE features which can be implemented if you only have access to a | 98 | HIR provides a high-level "object oriented" acess to Rust code. |
73 | single file. `ra_editor` could be used to enhance editing of Rust code | ||
74 | without the need to fiddle with build-systems, file | ||
75 | synchronization and such. | ||
76 | 99 | ||
77 | In a sense, `ra_editor` is just a bunch of pure functions which take a | 100 | The principal difference between HIR and syntax trees is that HIR is bound to a |
78 | syntax tree as an input. | 101 | particular crate instance. That is, it has cfg flags and features applied (in |
102 | theory, in practice this is to be implemented). So, there relation between | ||
103 | syntax and HIR is many-to-one. The `source_binder` modules is responsible for | ||
104 | guessing a hir for a particular source position. | ||
79 | 105 | ||
80 | The tests for `ra_editor` are `#[cfg(test)] mod tests` unit-tests spread | 106 | Underneath, hir works on top of salsa, using a `HirDatabase` trait. |
81 | throughout its modules. | ||
82 | 107 | ||
83 | ### `crates/ra_analysis` | 108 | ### `crates/ra_analysis` |
84 | 109 | ||
@@ -88,8 +113,10 @@ current state, incorporates changes and handles out `Analysis` --- an | |||
88 | immutable consistent snapshot of world state at a point in time, which | 113 | immutable consistent snapshot of world state at a point in time, which |
89 | actually powers analysis. | 114 | actually powers analysis. |
90 | 115 | ||
91 | ### `crates/ra_db` | 116 | One interesting aspect of analysis is its support for cancellation. When a change |
92 | This defines basic database traits. Concrete DB is defined by ra_analysis. | 117 | is applied to `AnalysisHost`, first all currently active snapshots are |
118 | cancelled. Only after all snapshots are dropped the change actually affects the | ||
119 | database. | ||
93 | 120 | ||
94 | ### `crates/ra_lsp_server` | 121 | ### `crates/ra_lsp_server` |
95 | 122 | ||
@@ -100,6 +127,19 @@ See [#79](https://github.com/rust-analyzer/rust-analyzer/pull/79/) as an | |||
100 | example of PR which adds a new feature to `ra_editor` and exposes it | 127 | example of PR which adds a new feature to `ra_editor` and exposes it |
101 | to `ra_lsp_server`. | 128 | to `ra_lsp_server`. |
102 | 129 | ||
130 | ### `crates/ra_editor` | ||
131 | |||
132 | All IDE features which can be implemented if you only have access to a | ||
133 | single file. `ra_editor` could be used to enhance editing of Rust code | ||
134 | without the need to fiddle with build-systems, file | ||
135 | synchronization and such. | ||
136 | |||
137 | In a sense, `ra_editor` is just a bunch of pure functions which take a | ||
138 | syntax tree as an input. | ||
139 | |||
140 | The tests for `ra_editor` are `#[cfg(test)] mod tests` unit-tests spread | ||
141 | throughout its modules. | ||
142 | |||
103 | ### `crates/gen_lsp_server` | 143 | ### `crates/gen_lsp_server` |
104 | 144 | ||
105 | A language server scaffold, exposing a synchronous crossbeam-channel based API. | 145 | A language server scaffold, exposing a synchronous crossbeam-channel based API. |