diff options
Diffstat (limited to 'docs/dev/guide.md')
-rw-r--r-- | docs/dev/guide.md | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/docs/dev/guide.md b/docs/dev/guide.md index c3252f1f6..b5a5d7c93 100644 --- a/docs/dev/guide.md +++ b/docs/dev/guide.md | |||
@@ -40,8 +40,8 @@ terms of files and offsets, and **not** in terms of Rust concepts like structs, | |||
40 | traits, etc. The "typed" API with Rust specific types is slightly lower in the | 40 | traits, etc. The "typed" API with Rust specific types is slightly lower in the |
41 | stack, we'll talk about it later. | 41 | stack, we'll talk about it later. |
42 | 42 | ||
43 | [`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L265-L284 | 43 | [`AnalysisHost`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L265-L284 |
44 | [`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L291-L478 | 44 | [`Analysis`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L291-L478 |
45 | 45 | ||
46 | The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply | 46 | The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply |
47 | changes "uniquely", but we might also want to fork an `Analysis` and send it to | 47 | changes "uniquely", but we might also want to fork an `Analysis` and send it to |
@@ -69,7 +69,7 @@ the `AnalysisHost::apply_change` method, which accepts a single argument, a | |||
69 | "transaction", so it suffices to study its methods to understand all of the | 69 | "transaction", so it suffices to study its methods to understand all of the |
70 | input data. | 70 | input data. |
71 | 71 | ||
72 | [`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L119-L167 | 72 | [`AnalysisChange`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L119-L167 |
73 | 73 | ||
74 | The `(add|change|remove)_file` methods control the set of the input files, where | 74 | The `(add|change|remove)_file` methods control the set of the input files, where |
75 | each file has an integer id (`FileId`, picked by the client), text (`String`) | 75 | each file has an integer id (`FileId`, picked by the client), text (`String`) |
@@ -253,13 +253,13 @@ All analyzer information is stored in a salsa database. `Analysis` and | |||
253 | `AnalysisHost` types are newtype wrappers for [`RootDatabase`] -- a salsa | 253 | `AnalysisHost` types are newtype wrappers for [`RootDatabase`] -- a salsa |
254 | database. | 254 | database. |
255 | 255 | ||
256 | [`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/db.rs#L88-L134 | 256 | [`RootDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/db.rs#L88-L134 |
257 | 257 | ||
258 | Salsa input queries are defined in [`FilesDatabase`] (which is a part of | 258 | Salsa input queries are defined in [`FilesDatabase`] (which is a part of |
259 | `RootDatabase`). They closely mirror the familiar `AnalysisChange` structure: | 259 | `RootDatabase`). They closely mirror the familiar `AnalysisChange` structure: |
260 | indeed, what `apply_change` does is it sets the values of input queries. | 260 | indeed, what `apply_change` does is it sets the values of input queries. |
261 | 261 | ||
262 | [`FilesDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/input.rs#L150-L174 | 262 | [`FilesDatabase`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/base_db/src/input.rs#L150-L174 |
263 | 263 | ||
264 | ## From text to semantic model | 264 | ## From text to semantic model |
265 | 265 | ||
@@ -275,7 +275,7 @@ several times, with different sets of `cfg`s enabled. The IDE-specific task of | |||
275 | mapping source code position into a semantic model is inherently imprecise for | 275 | mapping source code position into a semantic model is inherently imprecise for |
276 | this reason, and is handled by the [`source_binder`]. | 276 | this reason, and is handled by the [`source_binder`]. |
277 | 277 | ||
278 | [`source_binder`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/source_binder.rs | 278 | [`source_binder`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/source_binder.rs |
279 | 279 | ||
280 | The semantic interface is declared in the [`code_model_api`] module. Each entity is | 280 | The semantic interface is declared in the [`code_model_api`] module. Each entity is |
281 | identified by an integer ID and has a bunch of methods which take a salsa database | 281 | identified by an integer ID and has a bunch of methods which take a salsa database |
@@ -283,8 +283,8 @@ as an argument and returns other entities (which are also IDs). Internally, thes | |||
283 | methods invoke various queries on the database to build the model on demand. | 283 | methods invoke various queries on the database to build the model on demand. |
284 | Here's [the list of queries]. | 284 | Here's [the list of queries]. |
285 | 285 | ||
286 | [`code_model_api`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/code_model_api.rs | 286 | [`code_model_api`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/code_model_api.rs |
287 | [the list of queries]: https://github.com/rust-analyzer/rust-analyzer/blob/7e84440e25e19529e4ff8a66e521d1b06349c6ec/crates/ra_hir/src/db.rs#L20-L106 | 287 | [the list of queries]: https://github.com/rust-analyzer/rust-analyzer/blob/7e84440e25e19529e4ff8a66e521d1b06349c6ec/crates/hir/src/db.rs#L20-L106 |
288 | 288 | ||
289 | The first step of building the model is parsing the source code. | 289 | The first step of building the model is parsing the source code. |
290 | 290 | ||
@@ -341,7 +341,7 @@ The algorithm for building a tree of modules is to start with a crate root | |||
341 | declarations and recursively process child modules. This is handled by the | 341 | declarations and recursively process child modules. This is handled by the |
342 | [`module_tree_query`], with two slight variations. | 342 | [`module_tree_query`], with two slight variations. |
343 | 343 | ||
344 | [`module_tree_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L116-L123 | 344 | [`module_tree_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L116-L123 |
345 | 345 | ||
346 | First, rust-analyzer builds a module tree for all crates in a source root | 346 | First, rust-analyzer builds a module tree for all crates in a source root |
347 | simultaneously. The main reason for this is historical (`module_tree` predates | 347 | simultaneously. The main reason for this is historical (`module_tree` predates |
@@ -364,7 +364,7 @@ the same, we don't have to re-execute [`module_tree_query`]. In fact, we only | |||
364 | need to re-execute it when we add/remove new files or when we change mod | 364 | need to re-execute it when we add/remove new files or when we change mod |
365 | declarations. | 365 | declarations. |
366 | 366 | ||
367 | [`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41 | 367 | [`submodules_query`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L41 |
368 | 368 | ||
369 | We store the resulting modules in a `Vec`-based indexed arena. The indices in | 369 | We store the resulting modules in a `Vec`-based indexed arena. The indices in |
370 | the arena becomes module IDs. And this brings us to the next topic: | 370 | the arena becomes module IDs. And this brings us to the next topic: |
@@ -392,8 +392,8 @@ integers which can "intern" a location and return an integer ID back. The salsa | |||
392 | database we use includes a couple of [interners]. How to "garbage collect" | 392 | database we use includes a couple of [interners]. How to "garbage collect" |
393 | unused locations is an open question. | 393 | unused locations is an open question. |
394 | 394 | ||
395 | [`LocationInterner`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/loc2id.rs#L65-L71 | 395 | [`LocationInterner`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/base_db/src/loc2id.rs#L65-L71 |
396 | [interners]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/db.rs#L22-L23 | 396 | [interners]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/db.rs#L22-L23 |
397 | 397 | ||
398 | For example, we use `LocationInterner` to assign IDs to definitions of functions, | 398 | For example, we use `LocationInterner` to assign IDs to definitions of functions, |
399 | structs, enums, etc. The location, [`DefLoc`] contains two bits of information: | 399 | structs, enums, etc. The location, [`DefLoc`] contains two bits of information: |
@@ -407,7 +407,7 @@ using offsets, text ranges or syntax trees as keys and values for queries. What | |||
407 | we do instead is we store "index" of the item among all of the items of a file | 407 | we do instead is we store "index" of the item among all of the items of a file |
408 | (so, a positional based ID, but localized to a single file). | 408 | (so, a positional based ID, but localized to a single file). |
409 | 409 | ||
410 | [`DefLoc`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L127-L139 | 410 | [`DefLoc`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L127-L139 |
411 | 411 | ||
412 | One thing we've glossed over for the time being is support for macros. We have | 412 | One thing we've glossed over for the time being is support for macros. We have |
413 | only proof of concept handling of macros at the moment, but they are extremely | 413 | only proof of concept handling of macros at the moment, but they are extremely |
@@ -440,7 +440,7 @@ terms of `HirFileId`! This does not recur infinitely though: any chain of | |||
440 | `HirFileId`s bottoms out in `HirFileId::FileId`, that is, some source file | 440 | `HirFileId`s bottoms out in `HirFileId::FileId`, that is, some source file |
441 | actually written by the user. | 441 | actually written by the user. |
442 | 442 | ||
443 | [`HirFileId`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L18-L125 | 443 | [`HirFileId`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L18-L125 |
444 | 444 | ||
445 | Now that we understand how to identify a definition, in a source or in a | 445 | Now that we understand how to identify a definition, in a source or in a |
446 | macro-generated file, we can discuss name resolution a bit. | 446 | macro-generated file, we can discuss name resolution a bit. |
@@ -454,14 +454,14 @@ each module into a position-independent representation which does not change if | |||
454 | we modify bodies of the items. After that we [loop] resolving all imports until | 454 | we modify bodies of the items. After that we [loop] resolving all imports until |
455 | we've reached a fixed point. | 455 | we've reached a fixed point. |
456 | 456 | ||
457 | [lower]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L113-L117 | 457 | [lower]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L113-L117 |
458 | [loop]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres.rs#L186-L196 | 458 | [loop]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres.rs#L186-L196 |
459 | 459 | ||
460 | And, given all our preparation with IDs and a position-independent representation, | 460 | And, given all our preparation with IDs and a position-independent representation, |
461 | it is satisfying to [test] that typing inside function body does not invalidate | 461 | it is satisfying to [test] that typing inside function body does not invalidate |
462 | name resolution results. | 462 | name resolution results. |
463 | 463 | ||
464 | [test]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/tests.rs#L376 | 464 | [test]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/tests.rs#L376 |
465 | 465 | ||
466 | An interesting fact about name resolution is that it "erases" all of the | 466 | An interesting fact about name resolution is that it "erases" all of the |
467 | intermediate paths from the imports: in the end, we know which items are defined | 467 | intermediate paths from the imports: in the end, we know which items are defined |
@@ -496,10 +496,10 @@ there's an intermediate [projection query] which returns only the first | |||
496 | position-independent part of the lowering. The result of this query is stable. | 496 | position-independent part of the lowering. The result of this query is stable. |
497 | Naturally, name resolution [uses] this stable projection query. | 497 | Naturally, name resolution [uses] this stable projection query. |
498 | 498 | ||
499 | [imports]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59 | 499 | [imports]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59 |
500 | [`SourceMap`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59 | 500 | [`SourceMap`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59 |
501 | [projection query]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L97-L103 | 501 | [projection query]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L97-L103 |
502 | [uses]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/query_definitions.rs#L49 | 502 | [uses]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/query_definitions.rs#L49 |
503 | 503 | ||
504 | ## Type inference | 504 | ## Type inference |
505 | 505 | ||
@@ -521,10 +521,10 @@ construct a mapping from `ExprId`s to types. | |||
521 | 521 | ||
522 | [@flodiebold]: https://github.com/flodiebold | 522 | [@flodiebold]: https://github.com/flodiebold |
523 | [#327]: https://github.com/rust-analyzer/rust-analyzer/pull/327 | 523 | [#327]: https://github.com/rust-analyzer/rust-analyzer/pull/327 |
524 | [lower the AST]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs | 524 | [lower the AST]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs |
525 | [positional ID]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L13-L15 | 525 | [positional ID]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L13-L15 |
526 | [a source map]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L41-L44 | 526 | [a source map]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L41-L44 |
527 | [type inference]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ty.rs#L1208-L1223 | 527 | [type inference]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/hir/src/ty.rs#L1208-L1223 |
528 | 528 | ||
529 | ## Tying it all together: completion | 529 | ## Tying it all together: completion |
530 | 530 | ||
@@ -565,11 +565,11 @@ the type to completion. | |||
565 | [schedule it on the threadpool]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L428 | 565 | [schedule it on the threadpool]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L428 |
566 | [catch]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442 | 566 | [catch]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442 |
567 | [the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps | 567 | [the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps |
568 | [ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L439-L444 | 568 | [ask analysis for completion]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L439-L444 |
569 | [completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L46-L62 | 569 | [completion implementation]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L46-L62 |
570 | [`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L14-L37 | 570 | [`CompletionContext`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L14-L37 |
571 | ["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L72-L75 | 571 | ["IntelliJ Trick"]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L72-L75 |
572 | [find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L116-L120 | 572 | [find an ancestor `fn` node]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L116-L120 |
573 | [semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L123 | 573 | [semantic model]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L123 |
574 | [series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L52-L59 | 574 | [series of independent completion routines]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L52-L59 |
575 | [`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/complete_dot.rs#L6-L22 | 575 | [`complete_dot`]: https://github.com/rust-analyzer/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/complete_dot.rs#L6-L22 |