diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/dev/README.md | 89 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 62 |
2 files changed, 148 insertions, 3 deletions
diff --git a/docs/dev/README.md b/docs/dev/README.md index 1de5a2aab..46ee030fc 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md | |||
@@ -170,7 +170,7 @@ https://www.tedinski.com/2018/02/06/system-boundaries.html | |||
170 | 170 | ||
171 | We separate import groups with blank lines | 171 | We separate import groups with blank lines |
172 | 172 | ||
173 | ``` | 173 | ```rust |
174 | mod x; | 174 | mod x; |
175 | mod y; | 175 | mod y; |
176 | 176 | ||
@@ -184,6 +184,27 @@ use crate::{} | |||
184 | use super::{} // but prefer `use crate::` | 184 | use super::{} // but prefer `use crate::` |
185 | ``` | 185 | ``` |
186 | 186 | ||
187 | ## Import Style | ||
188 | |||
189 | Items from `hir` and `ast` should be used qualified: | ||
190 | |||
191 | ```rust | ||
192 | // Good | ||
193 | use ra_syntax::ast; | ||
194 | |||
195 | fn frobnicate(func: hir::Function, strukt: ast::StructDef) {} | ||
196 | |||
197 | // Not as good | ||
198 | use hir::Function; | ||
199 | use ra_syntax::ast::StructDef; | ||
200 | |||
201 | fn frobnicate(func: Function, strukt: StructDef) {} | ||
202 | ``` | ||
203 | |||
204 | Avoid local `use MyEnum::*` imports. | ||
205 | |||
206 | Prefer `use crate::foo::bar` to `use super::bar`. | ||
207 | |||
187 | ## Order of Items | 208 | ## Order of Items |
188 | 209 | ||
189 | Optimize for the reader who sees the file for the first time, and wants to get the general idea about what's going on. | 210 | Optimize for the reader who sees the file for the first time, and wants to get the general idea about what's going on. |
@@ -195,7 +216,7 @@ Put `struct`s and `enum`s first, functions and impls last. | |||
195 | 216 | ||
196 | Do | 217 | Do |
197 | 218 | ||
198 | ``` | 219 | ```rust |
199 | // Good | 220 | // Good |
200 | struct Foo { | 221 | struct Foo { |
201 | bars: Vec<Bar> | 222 | bars: Vec<Bar> |
@@ -206,7 +227,7 @@ struct Bar; | |||
206 | 227 | ||
207 | rather than | 228 | rather than |
208 | 229 | ||
209 | ``` | 230 | ```rust |
210 | // Not as good | 231 | // Not as good |
211 | struct Bar; | 232 | struct Bar; |
212 | 233 | ||
@@ -220,6 +241,68 @@ struct Foo { | |||
220 | For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. | 241 | For `.md` and `.adoc` files, prefer a sentence-per-line format, don't wrap lines. |
221 | If the line is too long, you want to split the sentence in two :-) | 242 | If the line is too long, you want to split the sentence in two :-) |
222 | 243 | ||
244 | ## Preconditions | ||
245 | |||
246 | Function preconditions should generally be expressed in types and provided by the caller (rather than checked by callee): | ||
247 | |||
248 | ```rust | ||
249 | // Good | ||
250 | fn frbonicate(walrus: Walrus) { | ||
251 | ... | ||
252 | } | ||
253 | |||
254 | // Not as good | ||
255 | fn frobnicate(walrus: Option<Walrus>) { | ||
256 | let walrus = match walrus { | ||
257 | Some(it) => it, | ||
258 | None => return, | ||
259 | }; | ||
260 | ... | ||
261 | } | ||
262 | ``` | ||
263 | |||
264 | ## Commit Style | ||
265 | |||
266 | We don't have specific rules around git history hygiene. | ||
267 | Maintaining clean git history is encouraged, but not enforced. | ||
268 | We use rebase workflow, it's OK to rewrite history during PR review process. | ||
269 | |||
270 | Avoid @mentioning people in commit messages, as such messages create a lot of duplicate notification traffic during rebases. | ||
271 | |||
272 | # Architecture Invariants | ||
273 | |||
274 | This section tries to document high-level design constraints, which are not | ||
275 | always obvious from the low-level code. | ||
276 | |||
277 | ## Incomplete syntax trees | ||
278 | |||
279 | Syntax trees are by design incomplete and do not enforce well-formedness. | ||
280 | If ast method returns an `Option`, it *can* be `None` at runtime, even if this is forbidden by the grammar. | ||
281 | |||
282 | ## LSP indenpendence | ||
283 | |||
284 | rust-analyzer is independent from LSP. | ||
285 | It provides features for a hypothetical perfect Rust-specific IDE client. | ||
286 | Internal representations are lowered to LSP in the `rust-analyzer` crate (the only crate which is allowed to use LSP types). | ||
287 | |||
288 | ## IDE/Compiler split | ||
289 | |||
290 | There's a semi-hard split between "compiler" and "IDE", at the `ra_hir` crate. | ||
291 | Compiler derives new facts about source code. | ||
292 | It explicitly acknowledges that not all info is available (ie, you can't look at types during name resolution). | ||
293 | |||
294 | IDE assumes that all information is available at all times. | ||
295 | |||
296 | IDE should use only types from `ra_hir`, and should not depend on the underling compiler types. | ||
297 | `ra_hir` is a facade. | ||
298 | |||
299 | ## IDE API | ||
300 | |||
301 | The main IDE crate (`ra_ide`) uses "Plain Old Data" for the API. | ||
302 | Rather than talking in definitions and references, it talks in Strings and textual offsets. | ||
303 | In general, API is centered around UI concerns -- the result of the call is what the user sees in the editor, and not what the compiler sees underneath. | ||
304 | The results are 100% Rust specific though. | ||
305 | |||
223 | # Logging | 306 | # Logging |
224 | 307 | ||
225 | Logging is done by both rust-analyzer and VS Code, so it might be tricky to | 308 | Logging is done by both rust-analyzer and VS Code, so it might be tricky to |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 647cf6107..a0847dad3 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -97,6 +97,30 @@ Invoking code action at this position will yield two code actions for importing | |||
97 | * Is a fixed two-level structure enough? | 97 | * Is a fixed two-level structure enough? |
98 | * Should we devise a general way to encode custom interaction protocols for GUI refactorings? | 98 | * Should we devise a general way to encode custom interaction protocols for GUI refactorings? |
99 | 99 | ||
100 | ## Lazy assists with `ResolveCodeAction` | ||
101 | |||
102 | **Issue:** https://github.com/microsoft/language-server-protocol/issues/787 | ||
103 | |||
104 | **Client Capability** `{ "resolveCodeAction": boolean }` | ||
105 | |||
106 | If this capability is set, the assists will be computed lazily. Thus `CodeAction` returned from the server will only contain `id` but not `edit` or `command` fields. The only exclusion from the rule is the diagnostic edits. | ||
107 | |||
108 | After the client got the id, it should then call `experimental/resolveCodeAction` command on the server and provide the following payload: | ||
109 | |||
110 | ```typescript | ||
111 | interface ResolveCodeActionParams { | ||
112 | id: string; | ||
113 | codeActionParams: lc.CodeActionParams; | ||
114 | } | ||
115 | ``` | ||
116 | |||
117 | As a result of the command call the client will get the respective workspace edit (`lc.WorkspaceEdit`). | ||
118 | |||
119 | ### Unresolved Questions | ||
120 | |||
121 | * Apply smarter filtering for ids? | ||
122 | * Upon `resolveCodeAction` command only call the assits which should be resolved and not all of them? | ||
123 | |||
100 | ## Parent Module | 124 | ## Parent Module |
101 | 125 | ||
102 | **Issue:** https://github.com/microsoft/language-server-protocol/issues/1002 | 126 | **Issue:** https://github.com/microsoft/language-server-protocol/issues/1002 |
@@ -443,3 +467,41 @@ interface InlayHint { | |||
443 | label: string, | 467 | label: string, |
444 | } | 468 | } |
445 | ``` | 469 | ``` |
470 | |||
471 | ## Hover Actions | ||
472 | |||
473 | **Client Capability:** `{ "hoverActions": boolean }` | ||
474 | |||
475 | If this capability is set, `Hover` request returned from the server might contain an additional field, `actions`: | ||
476 | |||
477 | ```typescript | ||
478 | interface Hover { | ||
479 | ... | ||
480 | actions?: CommandLinkGroup[]; | ||
481 | } | ||
482 | |||
483 | interface CommandLink extends Command { | ||
484 | /** | ||
485 | * A tooltip for the command, when represented in the UI. | ||
486 | */ | ||
487 | tooltip?: string; | ||
488 | } | ||
489 | |||
490 | interface CommandLinkGroup { | ||
491 | title?: string; | ||
492 | commands: CommandLink[]; | ||
493 | } | ||
494 | ``` | ||
495 | |||
496 | Such actions on the client side are appended to a hover bottom as command links: | ||
497 | ``` | ||
498 | +-----------------------------+ | ||
499 | | Hover content | | ||
500 | | | | ||
501 | +-----------------------------+ | ||
502 | | _Action1_ | _Action2_ | <- first group, no TITLE | ||
503 | +-----------------------------+ | ||
504 | | TITLE _Action1_ | _Action2_ | <- second group | ||
505 | +-----------------------------+ | ||
506 | ... | ||
507 | ``` \ No newline at end of file | ||