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