]> git.lizzy.rs Git - rust.git/blob - docs/dev/README.md
732e4bdd30d30f47fc3042a452280c82cced0bbd
[rust.git] / docs / dev / README.md
1 # Contributing Quick Start
2
3 Rust Analyzer is just a usual rust project, which is organized as a Cargo
4 workspace, builds on stable and doesn't depend on C libraries. So, just
5
6 ```
7 $ cargo test
8 ```
9
10 should be enough to get you started!
11
12 To learn more about how rust-analyzer works, see
13 [./architecture.md](./architecture.md) document.
14
15 We also publish rustdoc docs to pages:
16
17 https://rust-analyzer.github.io/rust-analyzer/ra_ide/
18
19 Various organizational and process issues are discussed in this document.
20
21 # Getting in Touch
22
23 Rust Analyzer is a part of [RLS-2.0 working
24 group](https://github.com/rust-lang/compiler-team/tree/6a769c13656c0a6959ebc09e7b1f7c09b86fb9c0/working-groups/rls-2.0).
25 Discussion happens in this Zulip stream:
26
27 https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0
28
29 # Issue Labels
30
31 * [good-first-issue](https://github.com/rust-analyzer/rust-analyzer/labels/good%20first%20issue)
32   are good issues to get into the project.
33 * [E-mentor](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-mentor)
34   issues have links to the code in question and tests.
35 * [E-easy](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy),
36   [E-medium](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-medium),
37   [E-hard](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3AE-hard),
38   labels are *estimates* for how hard would be to write a fix.
39 * [fun](https://github.com/rust-analyzer/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3Afun)
40   is for cool, but probably hard stuff.
41
42 # CI
43
44 We use GitHub Actions for CI. Most of the things, including formatting, are checked by
45 `cargo test` so, if `cargo test` passes locally, that's a good sign that CI will
46 be green as well. The only exception is that some long-running tests are skipped locally by default.
47 Use `env RUN_SLOW_TESTS=1 cargo test` to run the full suite.
48
49 We use bors-ng to enforce the [not rocket science](https://graydon2.dreamwidth.org/1597.html) rule.
50
51 You can run `cargo xtask install-pre-commit-hook` to install git-hook to run rustfmt on commit.
52
53 # Code organization
54
55 All Rust code lives in the `crates` top-level directory, and is organized as a
56 single Cargo workspace. The `editors` top-level directory contains code for
57 integrating with editors. Currently, it contains the plugin for VS Code (in
58 typescript). The `docs` top-level directory contains both developer and user
59 documentation.
60
61 We have some automation infra in Rust in the `xtask` package. It contains
62 stuff like formatting checking, code generation and powers `cargo xtask install`.
63 The latter syntax is achieved with the help of cargo aliases (see `.cargo`
64 directory).
65
66 # Launching rust-analyzer
67
68 Debugging language server can be tricky: LSP is rather chatty, so driving it
69 from the command line is not really feasible, driving it via VS Code requires
70 interacting with two processes.
71
72 For this reason, the best way to see how rust-analyzer works is to find a
73 relevant test and execute it (VS Code includes an action for running a single
74 test).
75
76 However, launching a VS Code instance with locally build language server is
77 possible. There's "Run Extension (Dev Server)" launch configuration for this.
78
79 In general, I use one of the following workflows for fixing bugs and
80 implementing features.
81
82 If the problem concerns only internal parts of rust-analyzer (ie, I don't need
83 to touch `ra_lsp_server` crate or typescript code), there is a unit-test for it.
84 So, I use **Rust Analyzer: Run** action in VS Code to run this single test, and
85 then just do printf-driven development/debugging. As a sanity check after I'm
86 done, I use `cargo xtask install --server` and **Reload Window** action in VS
87 Code to sanity check that the thing works as I expect.
88
89 If the problem concerns only the VS Code extension, I use **Run Extension**
90 launch configuration from `launch.json`. Notably, this uses the usual
91 `ra_lsp_server` binary from `PATH`. After I am done with the fix, I use `cargo
92 xtask install --client-code` to try the new extension for real.
93
94 If I need to fix something in the `ra_lsp_server` crate, I feel sad because it's
95 on the boundary between the two processes, and working there is slow. I usually
96 just `cargo xtask install --server` and poke changes from my live environment.
97 Note that this uses `--release`, which is usually faster overall, because
98 loading stdlib into debug version of rust-analyzer takes a lot of time. To speed
99 things up, sometimes I open a temporary hello-world project which has
100 `"rust-analyzer.withSysroot": false` in `.code/settings.json`. This flag causes
101 rust-analyzer to skip loading the sysroot, which greatly reduces the amount of
102 things rust-analyzer needs to do, and makes printf's more useful. Note that you
103 should only use `eprint!` family of macros for debugging: stdout is used for LSP
104 communication, and `print!` would break it.
105
106 If I need to fix something simultaneously in the server and in the client, I
107 feel even more sad. I don't have a specific workflow for this case.
108
109 Additionally, I use `cargo run --release -p ra_cli -- analysis-stats
110 path/to/some/rust/crate` to run a batch analysis. This is primarily useful for
111 performance optimizations, or for bug minimization.
112
113 # Logging
114
115 Logging is done by both rust-analyzer and VS Code, so it might be tricky to
116 figure out where logs go.
117
118 Inside rust-analyzer, we use the standard `log` crate for logging, and
119 `env_logger` for logging frontend. By default, log goes to stderr, but the
120 stderr itself is processed by VS Code.
121
122 To see stderr in the running VS Code instance, go to the "Output" tab of the
123 panel and select `rust-analyzer`. This shows `eprintln!` as well. Note that
124 `stdout` is used for the actual protocol, so `println!` will break things.
125
126 To log all communication between the server and the client, there are two choices:
127
128 * you can log on the server side, by running something like
129   ```
130   env RUST_LOG=gen_lsp_server=trace code .
131   ```
132
133 * you can log on the client side, by enabling `"rust-analyzer.trace.server":
134   "verbose"` workspace setting. These logs are shown in a separate tab in the
135   output and could be used with LSP inspector. Kudos to
136   [@DJMcNab](https://github.com/DJMcNab) for setting this awesome infra up!
137
138
139 There's also two VS Code commands which might be of interest:
140
141 * `Rust Analyzer: Status` shows some memory-usage statistics. To take full
142   advantage of it, you need to compile rust-analyzer with jemalloc support:
143   ```
144   $ cargo install --path crates/ra_lsp_server --force --features jemalloc
145   ```
146
147   There's an alias for this: `cargo xtask install --server --jemalloc`.
148
149 * `Rust Analyzer: Syntax Tree` shows syntax tree of the current file/selection.
150
151 # Profiling
152
153 We have a built-in hierarchical profiler, you can enable it by using `RA_PROF` env-var:
154
155 ```
156 RA_PROFILE=*             // dump everything
157 RA_PROFILE=foo|bar|baz   // enabled only selected entries
158 RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more than 10 ms
159 ```
160
161 In particular, I have `export RA_PROFILE='*>10' in my shell profile.
162
163 To measure time for from-scratch analysis, use something like this:
164
165 ```
166 $ cargo run --release -p ra_cli -- analysis-stats ../chalk/
167 ```
168
169 For measuring time of incremental analysis, use either of these:
170
171 ```
172 $ cargo run --release -p ra_cli -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs
173 $ cargo run --release -p ra_cli -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0
174 ```