aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARCHITECTURE.md45
-rw-r--r--crates/gen_lsp_server/src/lib.rs6
-rw-r--r--crates/gen_lsp_server/src/msg.rs2
-rw-r--r--crates/ra_db/src/cancellation.rs (renamed from crates/ra_db/src/cancelation.rs)6
-rw-r--r--crates/ra_db/src/input.rs22
-rw-r--r--crates/ra_db/src/lib.rs6
-rw-r--r--crates/ra_db/src/loc2id.rs4
-rw-r--r--crates/ra_hir/src/code_model_api.rs20
-rw-r--r--crates/ra_hir/src/db.rs3
-rw-r--r--crates/ra_hir/src/expr.rs8
-rw-r--r--crates/ra_hir/src/ids.rs12
-rw-r--r--crates/ra_hir/src/impl_block.rs12
-rw-r--r--crates/ra_hir/src/lib.rs6
-rw-r--r--crates/ra_hir/src/macros.rs6
-rw-r--r--crates/ra_hir/src/module_tree.rs4
-rw-r--r--crates/ra_hir/src/name.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs24
-rw-r--r--crates/ra_hir/src/source_binder.rs2
-rw-r--r--crates/ra_hir/src/ty.rs4
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs2
-rw-r--r--crates/ra_hir/src/ty/tests.rs2
-rw-r--r--crates/ra_ide_api/src/lib.rs41
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs2
23 files changed, 150 insertions, 91 deletions
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index 9c404f4c3..79adc9321 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -1,6 +1,6 @@
1# Architecture 1# Architecture
2 2
3This document describes high-level architecture of rust-analyzer. 3This document describes the 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
@@ -12,10 +12,10 @@ On 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. 12from the client and produces a structured semantic model of the code.
13 13
14More specifically, input data consists of a set of test files (`(PathBuf, 14More specifically, input data consists of a set of test files (`(PathBuf,
15String)` pairs) and an information about project structure, the so called 15String)` pairs) and information about project structure, captured in the so called
16`CrateGraph`. Crate graph specifies which files are crate roots, which cfg flags 16`CrateGraph`. The crate graph specifies which files are crate roots, which cfg
17are specified for each crate (TODO: actually implement this) and what are 17flags are specified for each crate (TODO: actually implement this) and what
18dependencies between the crates. The analyzer keeps all these input data in 18dependencies exist between the crates. The analyzer keeps all this input data in
19memory and never does any IO. Because the input data is source code, which 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 20typically measures in tens of megabytes at most, keeping all input data in
21memory is OK. 21memory is OK.
@@ -28,8 +28,8 @@ declarations, etc.
28The client can submit a small delta of input data (typically, a change to a 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. 29single file) and get a fresh code model which accounts for changes.
30 30
31Underlying engine makes sure that model is computed lazily (on-demand) and can 31The underlying engine makes sure that model is computed lazily (on-demand) and
32be quickly updated for small modifications. 32can be quickly updated for small modifications.
33 33
34 34
35## Code generation 35## Code generation
@@ -37,7 +37,7 @@ be quickly updated for small modifications.
37Some of the components of this repository are generated through automatic 37Some of the components of this repository are generated through automatic
38processes. These are outlined below: 38processes. These are outlined below:
39 39
40- `gen-syntax`: The kinds of tokens are reused in several places, so a generator 40- `gen-syntax`: The kinds of tokens that are reused in several places, so a generator
41 is used. We use tera templates to generate the files listed below, based on 41 is used. We use tera templates to generate the files listed below, based on
42 the grammar described in [grammar.ron]: 42 the grammar described in [grammar.ron]:
43 - [ast/generated.rs][ast generated] in `ra_syntax` based on 43 - [ast/generated.rs][ast generated] in `ra_syntax` based on
@@ -58,17 +58,16 @@ processes. These are outlined below:
58### `crates/ra_syntax` 58### `crates/ra_syntax`
59 59
60Rust syntax tree structure and parser. See 60Rust syntax tree structure and parser. See
61[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design 61[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design notes.
62notes.
63 62
64- [rowan](https://github.com/rust-analyzer/rowan) library is used for constructing syntax trees. 63- [rowan](https://github.com/rust-analyzer/rowan) library is used for constructing syntax trees.
65- `grammar` module is the actual parser. It is a hand-written recursive descent parsers, which 64- `grammar` module is the actual parser. It is a hand-written recursive descent parser, which
66 produces a sequence of events like "start node X", "finish not Y". It works similarly to [kotlin parser](https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java), 65 produces a sequence of events like "start node X", "finish not Y". It works similarly to [kotlin's parser](https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java),
67 which is a good source for inspiration for dealing with syntax errors and incomplete input. Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs) 66 which is a good source of inspiration for dealing with syntax errors and incomplete input. Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs)
68 is what we use for the definition of the Rust language. 67 is what we use for the definition of the Rust language.
69- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `rowan` trees. 68- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `rowan` trees.
70 This is the thing that turns a flat list of events into a tree (see `EventProcessor`) 69 This is the thing that turns a flat list of events into a tree (see `EventProcessor`)
71- `ast` a type safe API on top of the raw `rowan` tree. 70- `ast` provides a type safe API on top of the raw `rowan` tree.
72- `grammar.ron` RON description of the grammar, which is used to 71- `grammar.ron` RON description of the grammar, which is used to
73 generate `syntax_kinds` and `ast` modules, using `cargo gen-syntax` command. 72 generate `syntax_kinds` and `ast` modules, using `cargo gen-syntax` command.
74- `algo`: generic tree algorithms, including `walk` for O(1) stack 73- `algo`: generic tree algorithms, including `walk` for O(1) stack
@@ -90,7 +89,7 @@ fixes a bug in the grammar.
90We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and 89We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and
91on-demand computation. Roughly, you can think of salsa as a key-value store, but 90on-demand computation. Roughly, you can think of salsa as a key-value store, but
92it also can compute derived values using specified functions. The `ra_db` crate 91it also can compute derived values using specified functions. The `ra_db` crate
93provides a basic infrastructure for interacting with salsa. Crucially, it 92provides basic infrastructure for interacting with salsa. Crucially, it
94defines most of the "input" queries: facts supplied by the client of the 93defines most of the "input" queries: facts supplied by the client of the
95analyzer. Reading the docs of the `ra_db::input` module should be useful: 94analyzer. Reading the docs of the `ra_db::input` module should be useful:
96everything else is strictly derived from those inputs. 95everything else is strictly derived from those inputs.
@@ -102,7 +101,7 @@ HIR provides high-level "object oriented" access to Rust code.
102The principal difference between HIR and syntax trees is that HIR is bound to a 101The principal difference between HIR and syntax trees is that HIR is bound to a
103particular crate instance. That is, it has cfg flags and features applied (in 102particular crate instance. That is, it has cfg flags and features applied (in
104theory, in practice this is to be implemented). So, the relation between 103theory, in practice this is to be implemented). So, the relation between
105syntax and HIR is many-to-one. The `source_binder` modules is responsible for 104syntax and HIR is many-to-one. The `source_binder` module is responsible for
106guessing a HIR for a particular source position. 105guessing a HIR for a particular source position.
107 106
108Underneath, HIR works on top of salsa, using a `HirDatabase` trait. 107Underneath, HIR works on top of salsa, using a `HirDatabase` trait.
@@ -111,12 +110,12 @@ Underneath, HIR works on top of salsa, using a `HirDatabase` trait.
111 110
112A stateful library for analyzing many Rust files as they change. `AnalysisHost` 111A stateful library for analyzing many Rust files as they change. `AnalysisHost`
113is a mutable entity (clojure's atom) which holds the current state, incorporates 112is a mutable entity (clojure's atom) which holds the current state, incorporates
114changes and handles out `Analysis` --- an immutable and consistent snapshot of 113changes and hands out `Analysis` --- an immutable and consistent snapshot of
115world state at a point in time, which actually powers analysis. 114the world state at a point in time, which actually powers analysis.
116 115
117One interesting aspect of analysis is its support for cancellation. When a 116One interesting aspect of analysis is its support for cancellation. When a
118change is applied to `AnalysisHost`, first all currently active snapshots are 117change is applied to `AnalysisHost`, first all currently active snapshots are
119cancelled. Only after all snapshots are dropped the change actually affects the 118canceled. Only after all snapshots are dropped the change actually affects the
120database. 119database.
121 120
122APIs in this crate are IDE centric: they take text offsets as input and produce 121APIs in this crate are IDE centric: they take text offsets as input and produce
@@ -142,7 +141,7 @@ An LSP implementation which wraps `ra_ide_api` into a langauge server protocol.
142 141
143### `crates/ra_vfs` 142### `crates/ra_vfs`
144 143
145Although `hir` and `ra_ide_api` don't do any io, we need to be able to read 144Although `hir` and `ra_ide_api` don't do any IO, we need to be able to read
146files from disk at the end of the day. This is what `ra_vfs` does. It also 145files from disk at the end of the day. This is what `ra_vfs` does. It also
147manages overlays: "dirty" files in the editor, whose "true" contents is 146manages overlays: "dirty" files in the editor, whose "true" contents is
148different from data on disk. 147different from data on disk.
@@ -175,16 +174,16 @@ VS Code plugin
175## Common workflows 174## Common workflows
176 175
177To try out VS Code extensions, run `cargo install-code`. This installs both the 176To try out VS Code extensions, run `cargo install-code`. This installs both the
178`ra_lsp_server` binary and VS Code extension. To install only the binary, use 177`ra_lsp_server` binary and the VS Code extension. To install only the binary, use
179`cargo install --path crates/ra_lsp_server --force` 178`cargo install --path crates/ra_lsp_server --force`
180 179
181To see logs from the language server, set `RUST_LOG=info` env variable. To see 180To see logs from the language server, set `RUST_LOG=info` env variable. To see
182all communication between the server and the client, use 181all communication between the server and the client, use
183`RUST_LOG=gen_lsp_server=debug` (will print quite a bit of stuff). 182`RUST_LOG=gen_lsp_server=debug` (this will print quite a bit of stuff).
184 183
185To run tests, just `cargo test`. 184To run tests, just `cargo test`.
186 185
187To work on VS Code extension, launch code inside `editors/code` and use `F5` to 186To work on the VS Code extension, launch code inside `editors/code` and use `F5` to
188launch/debug. To automatically apply formatter and linter suggestions, use `npm 187launch/debug. To automatically apply formatter and linter suggestions, use `npm
189run fix`. 188run fix`.
190 189
diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
index b20652928..16ac799ac 100644
--- a/crates/gen_lsp_server/src/lib.rs
+++ b/crates/gen_lsp_server/src/lib.rs
@@ -78,10 +78,10 @@ pub use crate::{
78}; 78};
79 79
80/// Main entry point: runs the server from initialization to shutdown. 80/// Main entry point: runs the server from initialization to shutdown.
81/// To attach server to standard input/output streams, use `stdio_transport` 81/// To attach server to standard input/output streams, use the `stdio_transport`
82/// function to create corresponding `sender` and `receiver` pair. 82/// function to create corresponding `sender` and `receiver` pair.
83/// 83///
84///`server` should use `handle_shutdown` function to handle the `Shutdown` 84/// `server` should use the `handle_shutdown` function to handle the `Shutdown`
85/// request. 85/// request.
86pub fn run_server( 86pub fn run_server(
87 caps: ServerCapabilities, 87 caps: ServerCapabilities,
@@ -104,7 +104,7 @@ pub fn run_server(
104 Ok(()) 104 Ok(())
105} 105}
106 106
107/// if `req` is `Shutdown`, respond to it and return `None`, otherwise return `Some(req)` 107/// If `req` is `Shutdown`, respond to it and return `None`, otherwise return `Some(req)`
108pub fn handle_shutdown(req: RawRequest, sender: &Sender<RawMessage>) -> Option<RawRequest> { 108pub fn handle_shutdown(req: RawRequest, sender: &Sender<RawMessage>) -> Option<RawRequest> {
109 match req.cast::<Shutdown>() { 109 match req.cast::<Shutdown>() {
110 Ok((id, ())) => { 110 Ok((id, ())) => {
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs
index f68cbc541..94bef374c 100644
--- a/crates/gen_lsp_server/src/msg.rs
+++ b/crates/gen_lsp_server/src/msg.rs
@@ -54,7 +54,7 @@ pub enum ErrorCode {
54 ServerErrorEnd = -32000, 54 ServerErrorEnd = -32000,
55 ServerNotInitialized = -32002, 55 ServerNotInitialized = -32002,
56 UnknownErrorCode = -32001, 56 UnknownErrorCode = -32001,
57 RequestCancelled = -32800, 57 RequestCanceled = -32800,
58 ContentModified = -32801, 58 ContentModified = -32801,
59} 59}
60 60
diff --git a/crates/ra_db/src/cancelation.rs b/crates/ra_db/src/cancellation.rs
index 56ce27bff..8d38eebfb 100644
--- a/crates/ra_db/src/cancelation.rs
+++ b/crates/ra_db/src/cancellation.rs
@@ -8,11 +8,11 @@
8//! * user types next character, while syntax highlighting *is still in 8//! * user types next character, while syntax highlighting *is still in
9//! progress*. 9//! progress*.
10//! 10//!
11//! In this situation, we want to react to modification as quckly as possible. 11//! In this situation, we want to react to modification as quickly as possible.
12//! At the same time, in-progress results are not very interesting, because they 12//! At the same time, in-progress results are not very interesting, because they
13//! are invalidated by the edit anyway. So, we first cancel all in-flight 13//! are invalidated by the edit anyway. So, we first cancel all in-flight
14//! requests, and then apply modification knowing that it won't intrfere with 14//! requests, and then apply modification knowing that it won't interfere with
15//! any background processing (this bit is handled by salsa, see 15//! any background processing (this bit is handled by salsa, see the
16//! `BaseDatabase::check_canceled` method). 16//! `BaseDatabase::check_canceled` method).
17 17
18/// An "error" signifing that the operation was canceled. 18/// An "error" signifing that the operation was canceled.
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 7c3dd9296..023183e29 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -1,9 +1,9 @@
1/// This modules specifies the input to rust-analyzer. In some sense, this is 1/// This module specifies the input to rust-analyzer. In some sense, this is
2/// **the** most important module, because all other fancy stuff is strictly 2/// **the** most important module, because all other fancy stuff is strictly
3/// derived from this input. 3/// derived from this input.
4/// 4///
5/// Note that neither this module, nor any other part of the analyzer's core do 5/// Note that neither this module, nor any other part of the analyzer's core do
6/// actual IO. See `vfs` and `project_model` in `ra_lsp_server` crate for how 6/// actual IO. See `vfs` and `project_model` in the `ra_lsp_server` crate for how
7/// actual IO is done and lowered to input. 7/// actual IO is done and lowered to input.
8use std::sync::Arc; 8use std::sync::Arc;
9 9
@@ -17,17 +17,17 @@ use rustc_hash::FxHashSet;
17/// `FileId` is an integer which uniquely identifies a file. File paths are 17/// `FileId` is an integer which uniquely identifies a file. File paths are
18/// messy and system-dependent, so most of the code should work directly with 18/// messy and system-dependent, so most of the code should work directly with
19/// `FileId`, without inspecting the path. The mapping between `FileId` and path 19/// `FileId`, without inspecting the path. The mapping between `FileId` and path
20/// and `SourceRoot` is constant. File rename is represented as a pair of 20/// and `SourceRoot` is constant. A file rename is represented as a pair of
21/// deletion/creation. 21/// deletion/creation.
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct FileId(pub u32); 23pub struct FileId(pub u32);
24 24
25/// Files are grouped into source roots. A source root is a directory on the 25/// Files are grouped into source roots. A source root is a directory on the
26/// file systems which is watched for changes. Typically it corresponds to a 26/// file systems which is watched for changes. Typically it corresponds to a
27/// Cargo package. Source roots *might* be nested: in this case, file belongs to 27/// Rust crate. Source roots *might* be nested: in this case, a file belongs to
28/// the nearest enclosing source root. Path to files are always relative to a 28/// the nearest enclosing source root. Paths to files are always relative to a
29/// source root, and analyzer does not know the root path of the source root at 29/// source root, and the analyzer does not know the root path of the source root at
30/// all. So, a file from one source root can't refere a file in another source 30/// all. So, a file from one source root can't refer to a file in another source
31/// root by path. 31/// root by path.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
33pub struct SourceRootId(pub u32); 33pub struct SourceRootId(pub u32);
@@ -38,15 +38,15 @@ pub struct SourceRoot {
38} 38}
39 39
40/// `CrateGraph` is a bit of information which turns a set of text files into a 40/// `CrateGraph` is a bit of information which turns a set of text files into a
41/// number of Rust crates. Each Crate is the `FileId` of it's root module, the 41/// number of Rust crates. Each crate is defined by the `FileId` of its root module,
42/// set of cfg flags (not yet implemented) and the set of dependencies. Note 42/// the set of cfg flags (not yet implemented) and the set of dependencies. Note
43/// that, due to cfg's, there might be several crates for a single `FileId`! As 43/// that, due to cfg's, there might be several crates for a single `FileId`! As
44/// in the rust-lang proper, a crate does not have a name. Instead, names are 44/// in the rust-lang proper, a crate does not have a name. Instead, names are
45/// specified on dependency edges. That is, a crate might be known under 45/// specified on dependency edges. That is, a crate might be known under
46/// different names in different dependant crates. 46/// different names in different dependent crates.
47/// 47///
48/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust 48/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
49/// langauge proper, not a concept of the build system. In practice, we get 49/// language proper, not a concept of the build system. In practice, we get
50/// `CrateGraph` by lowering `cargo metadata` output. 50/// `CrateGraph` by lowering `cargo metadata` output.
51#[derive(Debug, Clone, Default, PartialEq, Eq)] 51#[derive(Debug, Clone, Default, PartialEq, Eq)]
52pub struct CrateGraph { 52pub struct CrateGraph {
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
index e680d9fc3..fb8ea2496 100644
--- a/crates/ra_db/src/lib.rs
+++ b/crates/ra_db/src/lib.rs
@@ -1,5 +1,5 @@
1//! ra_db defines basic database traits. Concrete DB is defined by ra_ide_api. 1//! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api.
2mod cancelation; 2mod cancellation;
3mod syntax_ptr; 3mod syntax_ptr;
4mod input; 4mod input;
5mod loc2id; 5mod loc2id;
@@ -8,7 +8,7 @@ pub mod mock;
8use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; 8use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr};
9 9
10pub use crate::{ 10pub use crate::{
11 cancelation::{Canceled, Cancelable}, 11 cancellation::{Canceled, Cancelable},
12 syntax_ptr::LocalSyntaxPtr, 12 syntax_ptr::LocalSyntaxPtr,
13 input::{ 13 input::{
14 FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, 14 FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs
index 1d6761897..254c52629 100644
--- a/crates/ra_db/src/loc2id.rs
+++ b/crates/ra_db/src/loc2id.rs
@@ -5,7 +5,7 @@ use rustc_hash::FxHashMap;
5use ra_arena::{Arena, ArenaId}; 5use ra_arena::{Arena, ArenaId};
6 6
7/// There are two principle ways to refer to things: 7/// There are two principle ways to refer to things:
8/// - by their locatinon (module in foo/bar/baz.rs at line 42) 8/// - by their location (module in foo/bar/baz.rs at line 42)
9/// - by their numeric id (module `ModuleId(42)`) 9/// - by their numeric id (module `ModuleId(42)`)
10/// 10///
11/// The first one is more powerful (you can actually find the thing in question 11/// The first one is more powerful (you can actually find the thing in question
@@ -13,7 +13,7 @@ use ra_arena::{Arena, ArenaId};
13/// 13///
14/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a 14/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
15/// bidirectional mapping between positional and numeric ids, we can use compact 15/// bidirectional mapping between positional and numeric ids, we can use compact
16/// representation wich still allows us to get the actual item 16/// representation which still allows us to get the actual item.
17#[derive(Debug)] 17#[derive(Debug)]
18struct Loc2IdMap<LOC, ID> 18struct Loc2IdMap<LOC, ID>
19where 19where
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 343d06a5b..66c016180 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -13,8 +13,8 @@ use crate::{
13 ty::InferenceResult, 13 ty::InferenceResult,
14}; 14};
15 15
16/// hir::Crate describes a single crate. It's the main inteface with which 16/// hir::Crate describes a single crate. It's the main interface with which
17/// crate's dependencies interact. Mostly, it should be just a proxy for the 17/// a crate's dependencies interact. Mostly, it should be just a proxy for the
18/// root module. 18/// root module.
19#[derive(Debug, Clone, PartialEq, Eq, Hash)] 19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct Crate { 20pub struct Crate {
@@ -78,6 +78,7 @@ impl Module {
78 pub fn definition_source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, ModuleSource)> { 78 pub fn definition_source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, ModuleSource)> {
79 self.definition_source_impl(db) 79 self.definition_source_impl(db)
80 } 80 }
81
81 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 82 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
82 /// `None` for the crate root. 83 /// `None` for the crate root.
83 pub fn declaration_source( 84 pub fn declaration_source(
@@ -91,20 +92,24 @@ impl Module {
91 pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { 92 pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
92 self.krate_impl(db) 93 self.krate_impl(db)
93 } 94 }
95
94 /// Topmost parent of this module. Every module has a `crate_root`, but some 96 /// Topmost parent of this module. Every module has a `crate_root`, but some
95 /// might miss `krate`. This can happen if a module's file is not included 97 /// might be missing `krate`. This can happen if a module's file is not included
96 /// into any module tree of any target from Cargo.toml. 98 /// in the module tree of any target in Cargo.toml.
97 pub fn crate_root(&self, db: &impl HirDatabase) -> Cancelable<Module> { 99 pub fn crate_root(&self, db: &impl HirDatabase) -> Cancelable<Module> {
98 self.crate_root_impl(db) 100 self.crate_root_impl(db)
99 } 101 }
102
100 /// Finds a child module with the specified name. 103 /// Finds a child module with the specified name.
101 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { 104 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
102 self.child_impl(db, name) 105 self.child_impl(db, name)
103 } 106 }
107
104 /// Finds a parent module. 108 /// Finds a parent module.
105 pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { 109 pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
106 self.parent_impl(db) 110 self.parent_impl(db)
107 } 111 }
112
108 pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable<Vec<Module>> { 113 pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable<Vec<Module>> {
109 let mut res = vec![self.clone()]; 114 let mut res = vec![self.clone()];
110 let mut curr = self.clone(); 115 let mut curr = self.clone();
@@ -114,13 +119,16 @@ impl Module {
114 } 119 }
115 Ok(res) 120 Ok(res)
116 } 121 }
122
117 /// Returns a `ModuleScope`: a set of items, visible in this module. 123 /// Returns a `ModuleScope`: a set of items, visible in this module.
118 pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { 124 pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
119 self.scope_impl(db) 125 self.scope_impl(db)
120 } 126 }
127
121 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { 128 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
122 self.resolve_path_impl(db, path) 129 self.resolve_path_impl(db, path)
123 } 130 }
131
124 pub fn problems( 132 pub fn problems(
125 &self, 133 &self,
126 db: &impl HirDatabase, 134 db: &impl HirDatabase,
@@ -140,6 +148,7 @@ impl StructField {
140 pub fn name(&self) -> &Name { 148 pub fn name(&self) -> &Name {
141 &self.name 149 &self.name
142 } 150 }
151
143 pub fn type_ref(&self) -> &TypeRef { 152 pub fn type_ref(&self) -> &TypeRef {
144 &self.type_ref 153 &self.type_ref
145 } 154 }
@@ -160,18 +169,21 @@ impl VariantData {
160 _ => &[], 169 _ => &[],
161 } 170 }
162 } 171 }
172
163 pub fn is_struct(&self) -> bool { 173 pub fn is_struct(&self) -> bool {
164 match self { 174 match self {
165 VariantData::Struct(..) => true, 175 VariantData::Struct(..) => true,
166 _ => false, 176 _ => false,
167 } 177 }
168 } 178 }
179
169 pub fn is_tuple(&self) -> bool { 180 pub fn is_tuple(&self) -> bool {
170 match self { 181 match self {
171 VariantData::Tuple(..) => true, 182 VariantData::Tuple(..) => true,
172 _ => false, 183 _ => false,
173 } 184 }
174 } 185 }
186
175 pub fn is_unit(&self) -> bool { 187 pub fn is_unit(&self) -> bool {
176 match self { 188 match self {
177 VariantData::Unit => true, 189 VariantData::Unit => true,
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 07cf0d10a..7dbe93f2b 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -26,6 +26,7 @@ pub trait HirDatabase: SyntaxDatabase
26 type HirSourceFileQuery; 26 type HirSourceFileQuery;
27 use fn HirFileId::hir_source_file; 27 use fn HirFileId::hir_source_file;
28 } 28 }
29
29 fn expand_macro_invocation(invoc: MacroCallId) -> Option<Arc<MacroExpansion>> { 30 fn expand_macro_invocation(invoc: MacroCallId) -> Option<Arc<MacroExpansion>> {
30 type ExpandMacroCallQuery; 31 type ExpandMacroCallQuery;
31 use fn crate::macros::expand_macro_invocation; 32 use fn crate::macros::expand_macro_invocation;
@@ -80,10 +81,12 @@ pub trait HirDatabase: SyntaxDatabase
80 type InputModuleItemsQuery; 81 type InputModuleItemsQuery;
81 use fn query_definitions::input_module_items; 82 use fn query_definitions::input_module_items;
82 } 83 }
84
83 fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> { 85 fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> {
84 type ItemMapQuery; 86 type ItemMapQuery;
85 use fn query_definitions::item_map; 87 use fn query_definitions::item_map;
86 } 88 }
89
87 fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> { 90 fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> {
88 type ModuleTreeQuery; 91 type ModuleTreeQuery;
89 use fn crate::module_tree::ModuleTree::module_tree_query; 92 use fn crate::module_tree::ModuleTree::module_tree_query;
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index a31f086f7..ebb83d084 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -33,8 +33,7 @@ pub struct Body {
33/// IDs. This is needed to go from e.g. a position in a file to the HIR 33/// IDs. This is needed to go from e.g. a position in a file to the HIR
34/// expression containing it; but for type inference etc., we want to operate on 34/// expression containing it; but for type inference etc., we want to operate on
35/// a structure that is agnostic to the actual positions of expressions in the 35/// a structure that is agnostic to the actual positions of expressions in the
36/// file, so that we don't recompute the type inference whenever some whitespace 36/// file, so that we don't recompute types whenever some whitespace is typed.
37/// is typed.
38#[derive(Debug, Eq, PartialEq)] 37#[derive(Debug, Eq, PartialEq)]
39pub struct BodySyntaxMapping { 38pub struct BodySyntaxMapping {
40 body: Arc<Body>, 39 body: Arc<Body>,
@@ -74,20 +73,25 @@ impl BodySyntaxMapping {
74 pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> { 73 pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> {
75 self.expr_syntax_mapping_back.get(expr).cloned() 74 self.expr_syntax_mapping_back.get(expr).cloned()
76 } 75 }
76
77 pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { 77 pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> {
78 self.expr_syntax_mapping.get(&ptr).cloned() 78 self.expr_syntax_mapping.get(&ptr).cloned()
79 } 79 }
80
80 pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { 81 pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
81 self.expr_syntax_mapping 82 self.expr_syntax_mapping
82 .get(&LocalSyntaxPtr::new(node.syntax())) 83 .get(&LocalSyntaxPtr::new(node.syntax()))
83 .cloned() 84 .cloned()
84 } 85 }
86
85 pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> { 87 pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> {
86 self.pat_syntax_mapping_back.get(pat).cloned() 88 self.pat_syntax_mapping_back.get(pat).cloned()
87 } 89 }
90
88 pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { 91 pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> {
89 self.pat_syntax_mapping.get(&ptr).cloned() 92 self.pat_syntax_mapping.get(&ptr).cloned()
90 } 93 }
94
91 pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { 95 pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> {
92 self.pat_syntax_mapping 96 self.pat_syntax_mapping
93 .get(&LocalSyntaxPtr::new(node.syntax())) 97 .get(&LocalSyntaxPtr::new(node.syntax()))
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 3db757778..2e10e5516 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -9,25 +9,25 @@ use crate::{
9 9
10use crate::code_model_api::Module; 10use crate::code_model_api::Module;
11 11
12/// hir makes a heavy use of ids: integer (u32) handlers to various things. You 12/// hir makes heavy use of ids: integer (u32) handlers to various things. You
13/// can think of id as a pointer (but without a lifetime) or a file descriptor 13/// can think of id as a pointer (but without a lifetime) or a file descriptor
14/// (but for hir objects). 14/// (but for hir objects).
15/// 15///
16/// This module defines a bunch of ids we are using. The most important ones are 16/// This module defines a bunch of ids we are using. The most important ones are
17/// probably `HirFileId` and `DefId`. 17/// probably `HirFileId` and `DefId`.
18 18
19/// Input to the analyzer is a set of file, where each file is indetified by 19/// Input to the analyzer is a set of files, where each file is indentified by
20/// `FileId` and contains source code. However, another source of source code in 20/// `FileId` and contains source code. However, another source of source code in
21/// Rust are macros: each macro can be thought of as producing a "temporary 21/// Rust are macros: each macro can be thought of as producing a "temporary
22/// file". To assign id to such file, we use the id of a macro call that 22/// file". To assign an id to such a file, we use the id of the macro call that
23/// produced the file. So, a `HirFileId` is either a `FileId` (source code 23/// produced the file. So, a `HirFileId` is either a `FileId` (source code
24/// written by user), or a `MacroCallId` (source code produced by macro). 24/// written by user), or a `MacroCallId` (source code produced by macro).
25/// 25///
26/// What is a `MacroCallId`? Simplifying, it's a `HirFileId` of a file containin 26/// What is a `MacroCallId`? Simplifying, it's a `HirFileId` of a file containin
27/// the call plus the offset of the macro call in the file. Note that this is a 27/// the call plus the offset of the macro call in the file. Note that this is a
28/// recursive definition! Nethetheless, size_of of `HirFileId` is finite 28/// recursive definition! However, the size_of of `HirFileId` is finite
29/// (because everything bottoms out at the real `FileId`) and small 29/// (because everything bottoms out at the real `FileId`) and small
30/// (`MacroCallId` uses location interner). 30/// (`MacroCallId` uses the location interner).
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32pub struct HirFileId(HirFileIdRepr); 32pub struct HirFileId(HirFileIdRepr);
33 33
@@ -235,7 +235,7 @@ pub struct SourceItemId {
235 pub(crate) item_id: Option<SourceFileItemId>, 235 pub(crate) item_id: Option<SourceFileItemId>,
236} 236}
237 237
238/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back. 238/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back.
239#[derive(Debug, PartialEq, Eq)] 239#[derive(Debug, PartialEq, Eq)]
240pub struct SourceFileItems { 240pub struct SourceFileItems {
241 file_id: HirFileId, 241 file_id: HirFileId,
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 0fbbdc8eb..4acda9af3 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -128,13 +128,13 @@ impl ImplItem {
128pub struct ImplId(pub RawId); 128pub struct ImplId(pub RawId);
129impl_arena_id!(ImplId); 129impl_arena_id!(ImplId);
130 130
131/// Collection of impl blocks is a two-step process: First we collect the blocks 131/// The collection of impl blocks is a two-step process: first we collect the
132/// per-module; then we build an index of all impl blocks in the crate. This 132/// blocks per-module; then we build an index of all impl blocks in the crate.
133/// way, we avoid having to do this process for the whole crate whenever someone 133/// This way, we avoid having to do this process for the whole crate whenever
134/// types in any file; as long as the impl blocks in the file don't change, we 134/// a file is changed; as long as the impl blocks in the file don't change,
135/// don't need to do the second step again. 135/// we don't need to do the second step again.
136/// 136///
137/// (The second step does not yet exist currently.) 137/// (The second step does not yet exist.)
138#[derive(Debug, PartialEq, Eq)] 138#[derive(Debug, PartialEq, Eq)]
139pub struct ModuleImplBlocks { 139pub struct ModuleImplBlocks {
140 impls: Arena<ImplId, ImplData>, 140 impls: Arena<ImplId, ImplData>,
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index eb19d8be1..ca7f395a8 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -1,9 +1,9 @@
1//! HIR (previsouly known as descriptors) provides a high-level OO acess to Rust 1//! HIR (previously known as descriptors) provides a high-level object oriented
2//! code. 2//! access to Rust code.
3//! 3//!
4//! The principal difference between HIR and syntax trees is that HIR is bound 4//! The principal difference between HIR and syntax trees is that HIR is bound
5//! to a particular crate instance. That is, it has cfg flags and features 5//! to a particular crate instance. That is, it has cfg flags and features
6//! applied. So, there relation between syntax and HIR is many-to-one. 6//! applied. So, the relation between syntax and HIR is many-to-one.
7 7
8macro_rules! ctry { 8macro_rules! ctry {
9 ($expr:expr) => { 9 ($expr:expr) => {
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs
index eb1c86091..e455b2ad5 100644
--- a/crates/ra_hir/src/macros.rs
+++ b/crates/ra_hir/src/macros.rs
@@ -4,9 +4,9 @@
4/// that is produced after expansion. See `HirFileId` and `MacroCallId` for how 4/// that is produced after expansion. See `HirFileId` and `MacroCallId` for how
5/// do we do that. 5/// do we do that.
6/// 6///
7/// When file-management question is resolved, all that is left is a token tree 7/// When the file-management question is resolved, all that is left is a
8/// to token tree transformation plus hygent. We don't have either of thouse 8/// token-tree-to-token-tree transformation plus hygiene. We don't have either of
9/// yet, so all macros are string based at the moment! 9/// those yet, so all macros are string based at the moment!
10use std::sync::Arc; 10use std::sync::Arc;
11 11
12use ra_db::LocalSyntaxPtr; 12use ra_db::LocalSyntaxPtr;
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs
index 91aab5c74..d2c92f150 100644
--- a/crates/ra_hir/src/module_tree.rs
+++ b/crates/ra_hir/src/module_tree.rs
@@ -85,9 +85,9 @@ impl_arena_id!(LinkId);
85 85
86/// Physically, rust source is organized as a set of files, but logically it is 86/// Physically, rust source is organized as a set of files, but logically it is
87/// organized as a tree of modules. Usually, a single file corresponds to a 87/// organized as a tree of modules. Usually, a single file corresponds to a
88/// single module, but it is not nessary the case. 88/// single module, but it is not neccessarily always the case.
89/// 89///
90/// Module encapsulate the logic of transitioning from the fuzzy world of files 90/// `ModuleTree` encapsulates the logic of transitioning from the fuzzy world of files
91/// (which can have multiple parents) to the precise world of modules (which 91/// (which can have multiple parents) to the precise world of modules (which
92/// always have one parent). 92/// always have one parent).
93#[derive(Default, Debug, PartialEq, Eq)] 93#[derive(Default, Debug, PartialEq, Eq)]
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 3e6ce8b95..d9683549c 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -3,7 +3,7 @@ use std::fmt;
3use ra_syntax::{ast, SmolStr}; 3use ra_syntax::{ast, SmolStr};
4 4
5/// `Name` is a wrapper around string, which is used in hir for both references 5/// `Name` is a wrapper around string, which is used in hir for both references
6/// and declarations. In theory, names should also carry hygene info, but we are 6/// and declarations. In theory, names should also carry hygiene info, but we are
7/// not there yet! 7/// not there yet!
8#[derive(Clone, PartialEq, Eq, Hash)] 8#[derive(Clone, PartialEq, Eq, Hash)]
9pub struct Name { 9pub struct Name {
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 20adc9ec4..6bf949654 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -1,18 +1,18 @@
1//! Name resolution algorithm. The end result of the algorithm is `ItemMap`: a 1//! Name resolution algorithm. The end result of the algorithm is an `ItemMap`:
2//! map with maps each module to it's scope: the set of items, visible in the 2//! a map which maps each module to its scope: the set of items visible in the
3//! module. That is, we only resolve imports here, name resolution of item 3//! module. That is, we only resolve imports here, name resolution of item
4//! bodies will be done in a separate step. 4//! bodies will be done in a separate step.
5//! 5//!
6//! Like Rustc, we use an interative per-crate algorithm: we start with scopes 6//! Like Rustc, we use an interactive per-crate algorithm: we start with scopes
7//! containing only directly defined items, and then iteratively resolve 7//! containing only directly defined items, and then iteratively resolve
8//! imports. 8//! imports.
9//! 9//!
10//! To make this work nicely in the IDE scenarios, we place `InputModuleItems` 10//! To make this work nicely in the IDE scenario, we place `InputModuleItems`
11//! in between raw syntax and name resolution. `InputModuleItems` are computed 11//! in between raw syntax and name resolution. `InputModuleItems` are computed
12//! using only the module's syntax, and it is all directly defined items plus 12//! using only the module's syntax, and it is all directly defined items plus
13//! imports. The plain is to make `InputModuleItems` independent of local 13//! imports. The plan is to make `InputModuleItems` independent of local
14//! modifications (that is, typing inside a function shold not change IMIs), 14//! modifications (that is, typing inside a function should not change IMIs),
15//! such that the results of name resolution can be preserved unless the module 15//! so that the results of name resolution can be preserved unless the module
16//! structure itself is modified. 16//! structure itself is modified.
17use std::sync::Arc; 17use std::sync::Arc;
18 18
@@ -34,7 +34,7 @@ use crate::{
34 module_tree::{ModuleId, ModuleTree}, 34 module_tree::{ModuleId, ModuleTree},
35}; 35};
36 36
37/// Item map is the result of the name resolution. Item map contains, for each 37/// `ItemMap` is the result of name resolution. It contains, for each
38/// module, the set of visible items. 38/// module, the set of visible items.
39// FIXME: currenty we compute item map per source-root. We should do it per crate instead. 39// FIXME: currenty we compute item map per source-root. We should do it per crate instead.
40#[derive(Default, Debug, PartialEq, Eq)] 40#[derive(Default, Debug, PartialEq, Eq)]
@@ -59,9 +59,9 @@ impl ModuleScope {
59/// A set of items and imports declared inside a module, without relation to 59/// A set of items and imports declared inside a module, without relation to
60/// other modules. 60/// other modules.
61/// 61///
62/// This stands in-between raw syntax and name resolution and alow us to avoid 62/// This sits in-between raw syntax and name resolution and allows us to avoid
63/// recomputing name res: if `InputModuleItems` are the same, we can avoid 63/// recomputing name res: if two instance of `InputModuleItems` are the same, we
64/// running name resolution. 64/// can avoid redoing name resolution.
65#[derive(Debug, Default, PartialEq, Eq)] 65#[derive(Debug, Default, PartialEq, Eq)]
66pub struct InputModuleItems { 66pub struct InputModuleItems {
67 pub(crate) items: Vec<ModuleItem>, 67 pub(crate) items: Vec<ModuleItem>,
@@ -114,7 +114,7 @@ enum ImportKind {
114 Named(NamedImport), 114 Named(NamedImport),
115} 115}
116 116
117/// Resolution is basically `DefId` atm, but it should account for stuff like 117/// `Resolution` is basically `DefId` atm, but it should account for stuff like
118/// multiple namespaces, ambiguity and errors. 118/// multiple namespaces, ambiguity and errors.
119#[derive(Debug, Clone, PartialEq, Eq)] 119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct Resolution { 120pub struct Resolution {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 4b0400cd0..1f149a366 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -1,4 +1,4 @@
1/// Lookup hir elements using position in the source code. This is a lossy 1/// Lookup hir elements using positions in the source code. This is a lossy
2/// transformation: in general, a single source might correspond to several 2/// transformation: in general, a single source might correspond to several
3/// modules, functions, etc, due to macros, cfgs and `#[path=]` attributes on 3/// modules, functions, etc, due to macros, cfgs and `#[path=]` attributes on
4/// modules. 4/// modules.
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 90ba393ce..3b2bfd67a 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -144,7 +144,7 @@ pub enum Ty {
144 Bool, 144 Bool,
145 145
146 /// The primitive character type; holds a Unicode scalar value 146 /// The primitive character type; holds a Unicode scalar value
147 /// (a non-surrogate code point). Written as `char`. 147 /// (a non-surrogate code point). Written as `char`.
148 Char, 148 Char,
149 149
150 /// A primitive signed integer type. For example, `i32`. 150 /// A primitive signed integer type. For example, `i32`.
@@ -204,7 +204,7 @@ pub enum Ty {
204 // `|a| yield a`. 204 // `|a| yield a`.
205 // Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability), 205 // Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
206 206
207 // A type representin the types stored inside a generator. 207 // A type representing the types stored inside a generator.
208 // This should only appear in GeneratorInteriors. 208 // This should only appear in GeneratorInteriors.
209 // GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>), 209 // GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
210 /// The never type `!`. 210 /// The never type `!`.
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 24a386558..d95879e46 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -1,4 +1,4 @@
1//! In certain situations, rust automatically inserts derefs as necessary: For 1//! In certain situations, rust automatically inserts derefs as necessary: for
2//! example, field accesses `foo.bar` still work when `foo` is actually a 2//! example, field accesses `foo.bar` still work when `foo` is actually a
3//! reference to a type with the field `bar`. This is an approximation of the 3//! reference to a type with the field `bar`. This is an approximation of the
4//! logic in rustc (which lives in librustc_typeck/check/autoderef.rs). 4//! logic in rustc (which lives in librustc_typeck/check/autoderef.rs).
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 2749d740c..ba2a44474 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -15,7 +15,7 @@ use crate::{
15}; 15};
16 16
17// These tests compare the inference results for all expressions in a file 17// These tests compare the inference results for all expressions in a file
18// against snapshots of the current results. If you change something and these 18// against snapshots of the expected results. If you change something and these
19// tests fail expectedly, you can update the comparison files by deleting them 19// tests fail expectedly, you can update the comparison files by deleting them
20// and running the tests again. Similarly, to add a new test, just write the 20// and running the tests again. Similarly, to add a new test, just write the
21// test here in the same pattern and it will automatically write the snapshot. 21// test here in the same pattern and it will automatically write the snapshot.
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 762731268..fbe1421a4 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -121,9 +121,11 @@ impl AnalysisChange {
121 pub fn new() -> AnalysisChange { 121 pub fn new() -> AnalysisChange {
122 AnalysisChange::default() 122 AnalysisChange::default()
123 } 123 }
124
124 pub fn add_root(&mut self, root_id: SourceRootId, is_local: bool) { 125 pub fn add_root(&mut self, root_id: SourceRootId, is_local: bool) {
125 self.new_roots.push((root_id, is_local)); 126 self.new_roots.push((root_id, is_local));
126 } 127 }
128
127 pub fn add_file( 129 pub fn add_file(
128 &mut self, 130 &mut self,
129 root_id: SourceRootId, 131 root_id: SourceRootId,
@@ -142,9 +144,11 @@ impl AnalysisChange {
142 .added 144 .added
143 .push(file); 145 .push(file);
144 } 146 }
147
145 pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { 148 pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) {
146 self.files_changed.push((file_id, new_text)) 149 self.files_changed.push((file_id, new_text))
147 } 150 }
151
148 pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { 152 pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) {
149 let file = RemoveFile { file_id, path }; 153 let file = RemoveFile { file_id, path };
150 self.roots_changed 154 self.roots_changed
@@ -153,9 +157,11 @@ impl AnalysisChange {
153 .removed 157 .removed
154 .push(file); 158 .push(file);
155 } 159 }
160
156 pub fn add_library(&mut self, data: LibraryData) { 161 pub fn add_library(&mut self, data: LibraryData) {
157 self.libraries_added.push(data) 162 self.libraries_added.push(data)
158 } 163 }
164
159 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 165 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
160 self.crate_graph = Some(graph); 166 self.crate_graph = Some(graph);
161 } 167 }
@@ -218,15 +224,19 @@ impl Query {
218 limit: usize::max_value(), 224 limit: usize::max_value(),
219 } 225 }
220 } 226 }
227
221 pub fn only_types(&mut self) { 228 pub fn only_types(&mut self) {
222 self.only_types = true; 229 self.only_types = true;
223 } 230 }
231
224 pub fn libs(&mut self) { 232 pub fn libs(&mut self) {
225 self.libs = true; 233 self.libs = true;
226 } 234 }
235
227 pub fn exact(&mut self) { 236 pub fn exact(&mut self) {
228 self.exact = true; 237 self.exact = true;
229 } 238 }
239
230 pub fn limit(&mut self, limit: usize) { 240 pub fn limit(&mut self, limit: usize) {
231 self.limit = limit 241 self.limit = limit
232 } 242 }
@@ -257,15 +267,19 @@ impl NavigationTarget {
257 ptr: Some(symbol.ptr.clone()), 267 ptr: Some(symbol.ptr.clone()),
258 } 268 }
259 } 269 }
270
260 pub fn name(&self) -> &SmolStr { 271 pub fn name(&self) -> &SmolStr {
261 &self.name 272 &self.name
262 } 273 }
274
263 pub fn kind(&self) -> SyntaxKind { 275 pub fn kind(&self) -> SyntaxKind {
264 self.kind 276 self.kind
265 } 277 }
278
266 pub fn file_id(&self) -> FileId { 279 pub fn file_id(&self) -> FileId {
267 self.file_id 280 self.file_id
268 } 281 }
282
269 pub fn range(&self) -> TextRange { 283 pub fn range(&self) -> TextRange {
270 self.range 284 self.range
271 } 285 }
@@ -305,6 +319,7 @@ impl AnalysisHost {
305 db: self.db.snapshot(), 319 db: self.db.snapshot(),
306 } 320 }
307 } 321 }
322
308 /// Applies changes to the current state of the world. If there are 323 /// Applies changes to the current state of the world. If there are
309 /// outstanding snapshots, they will be canceled. 324 /// outstanding snapshots, they will be canceled.
310 pub fn apply_change(&mut self, change: AnalysisChange) { 325 pub fn apply_change(&mut self, change: AnalysisChange) {
@@ -326,30 +341,36 @@ impl Analysis {
326 pub fn file_text(&self, file_id: FileId) -> Arc<String> { 341 pub fn file_text(&self, file_id: FileId) -> Arc<String> {
327 self.db.file_text(file_id) 342 self.db.file_text(file_id)
328 } 343 }
344
329 /// Gets the syntax tree of the file. 345 /// Gets the syntax tree of the file.
330 pub fn file_syntax(&self, file_id: FileId) -> TreePtr<SourceFile> { 346 pub fn file_syntax(&self, file_id: FileId) -> TreePtr<SourceFile> {
331 self.db.source_file(file_id).clone() 347 self.db.source_file(file_id).clone()
332 } 348 }
349
333 /// Gets the file's `LineIndex`: data structure to convert between absolute 350 /// Gets the file's `LineIndex`: data structure to convert between absolute
334 /// offsets and line/column representation. 351 /// offsets and line/column representation.
335 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { 352 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> {
336 self.db.line_index(file_id) 353 self.db.line_index(file_id)
337 } 354 }
355
338 /// Selects the next syntactic nodes encopasing the range. 356 /// Selects the next syntactic nodes encopasing the range.
339 pub fn extend_selection(&self, frange: FileRange) -> TextRange { 357 pub fn extend_selection(&self, frange: FileRange) -> TextRange {
340 extend_selection::extend_selection(&self.db, frange) 358 extend_selection::extend_selection(&self.db, frange)
341 } 359 }
360
342 /// Returns position of the mathcing brace (all types of braces are 361 /// Returns position of the mathcing brace (all types of braces are
343 /// supported). 362 /// supported).
344 pub fn matching_brace(&self, file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { 363 pub fn matching_brace(&self, file: &SourceFile, offset: TextUnit) -> Option<TextUnit> {
345 ra_ide_api_light::matching_brace(file, offset) 364 ra_ide_api_light::matching_brace(file, offset)
346 } 365 }
366
347 /// Returns a syntax tree represented as `String`, for debug purposes. 367 /// Returns a syntax tree represented as `String`, for debug purposes.
348 // FIXME: use a better name here. 368 // FIXME: use a better name here.
349 pub fn syntax_tree(&self, file_id: FileId) -> String { 369 pub fn syntax_tree(&self, file_id: FileId) -> String {
350 let file = self.db.source_file(file_id); 370 let file = self.db.source_file(file_id);
351 ra_ide_api_light::syntax_tree(&file) 371 ra_ide_api_light::syntax_tree(&file)
352 } 372 }
373
353 /// Returns an edit to remove all newlines in the range, cleaning up minor 374 /// Returns an edit to remove all newlines in the range, cleaning up minor
354 /// stuff like trailing commas. 375 /// stuff like trailing commas.
355 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 376 pub fn join_lines(&self, frange: FileRange) -> SourceChange {
@@ -359,6 +380,7 @@ impl Analysis {
359 ra_ide_api_light::join_lines(&file, frange.range), 380 ra_ide_api_light::join_lines(&file, frange.range),
360 ) 381 )
361 } 382 }
383
362 /// Returns an edit which should be applied when opening a new line, fixing 384 /// Returns an edit which should be applied when opening a new line, fixing
363 /// up minor stuff like continuing the comment. 385 /// up minor stuff like continuing the comment.
364 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { 386 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> {
@@ -366,6 +388,7 @@ impl Analysis {
366 let edit = ra_ide_api_light::on_enter(&file, position.offset)?; 388 let edit = ra_ide_api_light::on_enter(&file, position.offset)?;
367 Some(SourceChange::from_local_edit(position.file_id, edit)) 389 Some(SourceChange::from_local_edit(position.file_id, edit))
368 } 390 }
391
369 /// Returns an edit which should be applied after `=` was typed. Primarily, 392 /// Returns an edit which should be applied after `=` was typed. Primarily,
370 /// this works when adding `let =`. 393 /// this works when adding `let =`.
371 // FIXME: use a snippet completion instead of this hack here. 394 // FIXME: use a snippet completion instead of this hack here.
@@ -374,23 +397,27 @@ impl Analysis {
374 let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?; 397 let edit = ra_ide_api_light::on_eq_typed(&file, position.offset)?;
375 Some(SourceChange::from_local_edit(position.file_id, edit)) 398 Some(SourceChange::from_local_edit(position.file_id, edit))
376 } 399 }
400
377 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. 401 /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
378 pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> { 402 pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> {
379 let file = self.db.source_file(position.file_id); 403 let file = self.db.source_file(position.file_id);
380 let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?; 404 let edit = ra_ide_api_light::on_dot_typed(&file, position.offset)?;
381 Some(SourceChange::from_local_edit(position.file_id, edit)) 405 Some(SourceChange::from_local_edit(position.file_id, edit))
382 } 406 }
407
383 /// Returns a tree representation of symbols in the file. Useful to draw a 408 /// Returns a tree representation of symbols in the file. Useful to draw a
384 /// file outline. 409 /// file outline.
385 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { 410 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
386 let file = self.db.source_file(file_id); 411 let file = self.db.source_file(file_id);
387 ra_ide_api_light::file_structure(&file) 412 ra_ide_api_light::file_structure(&file)
388 } 413 }
414
389 /// Returns the set of folding ranges. 415 /// Returns the set of folding ranges.
390 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 416 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
391 let file = self.db.source_file(file_id); 417 let file = self.db.source_file(file_id);
392 ra_ide_api_light::folding_ranges(&file) 418 ra_ide_api_light::folding_ranges(&file)
393 } 419 }
420
394 /// Fuzzy searches for a symbol. 421 /// Fuzzy searches for a symbol.
395 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { 422 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
396 let res = symbol_index::world_symbols(&*self.db, query)? 423 let res = symbol_index::world_symbols(&*self.db, query)?
@@ -399,62 +426,76 @@ impl Analysis {
399 .collect(); 426 .collect();
400 Ok(res) 427 Ok(res)
401 } 428 }
429
402 pub fn goto_definition( 430 pub fn goto_definition(
403 &self, 431 &self,
404 position: FilePosition, 432 position: FilePosition,
405 ) -> Cancelable<Option<Vec<NavigationTarget>>> { 433 ) -> Cancelable<Option<Vec<NavigationTarget>>> {
406 goto_definition::goto_definition(&*self.db, position) 434 goto_definition::goto_definition(&*self.db, position)
407 } 435 }
436
408 /// Finds all usages of the reference at point. 437 /// Finds all usages of the reference at point.
409 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 438 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
410 self.db.find_all_refs(position) 439 self.db.find_all_refs(position)
411 } 440 }
441
412 /// Returns a short text descrbing element at position. 442 /// Returns a short text descrbing element at position.
413 pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> { 443 pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> {
414 hover::hover(&*self.db, position) 444 hover::hover(&*self.db, position)
415 } 445 }
446
416 /// Computes parameter information for the given call expression. 447 /// Computes parameter information for the given call expression.
417 pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> { 448 pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> {
418 call_info::call_info(&*self.db, position) 449 call_info::call_info(&*self.db, position)
419 } 450 }
451
420 /// Returns a `mod name;` declaration which created the current module. 452 /// Returns a `mod name;` declaration which created the current module.
421 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 453 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
422 self.db.parent_module(position) 454 self.db.parent_module(position)
423 } 455 }
456
424 /// Returns crates this file belongs too. 457 /// Returns crates this file belongs too.
425 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 458 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
426 self.db.crate_for(file_id) 459 self.db.crate_for(file_id)
427 } 460 }
461
428 /// Returns the root file of the given crate. 462 /// Returns the root file of the given crate.
429 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { 463 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> {
430 Ok(self.db.crate_graph().crate_root(crate_id)) 464 Ok(self.db.crate_graph().crate_root(crate_id))
431 } 465 }
466
432 /// Returns the set of possible targets to run for the current file. 467 /// Returns the set of possible targets to run for the current file.
433 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { 468 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> {
434 runnables::runnables(&*self.db, file_id) 469 runnables::runnables(&*self.db, file_id)
435 } 470 }
471
436 /// Computes syntax highlighting for the given file. 472 /// Computes syntax highlighting for the given file.
437 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { 473 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> {
438 syntax_highlighting::highlight(&*self.db, file_id) 474 syntax_highlighting::highlight(&*self.db, file_id)
439 } 475 }
476
440 /// Computes completions at the given position. 477 /// Computes completions at the given position.
441 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { 478 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
442 let completions = completion::completions(&self.db, position)?; 479 let completions = completion::completions(&self.db, position)?;
443 Ok(completions.map(|it| it.into())) 480 Ok(completions.map(|it| it.into()))
444 } 481 }
482
445 /// Computes assists (aks code actons aka intentions) for the given 483 /// Computes assists (aks code actons aka intentions) for the given
446 /// position. 484 /// position.
447 pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<SourceChange>> { 485 pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<SourceChange>> {
448 Ok(self.db.assists(frange)) 486 Ok(self.db.assists(frange))
449 } 487 }
488
450 /// Computes the set of diagnostics for the given file. 489 /// Computes the set of diagnostics for the given file.
451 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 490 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
452 self.db.diagnostics(file_id) 491 self.db.diagnostics(file_id)
453 } 492 }
493
454 /// Computes the type of the expression at the given position. 494 /// Computes the type of the expression at the given position.
455 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { 495 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
456 hover::type_of(&*self.db, frange) 496 hover::type_of(&*self.db, frange)
457 } 497 }
498
458 /// Returns the edit required to rename reference at the position to the new 499 /// Returns the edit required to rename reference at the position to the new
459 /// name. 500 /// name.
460 pub fn rename( 501 pub fn rename(
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 96923fac7..7fc0b8f50 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -326,7 +326,7 @@ fn on_notification(
326 if pending_requests.remove(&id) { 326 if pending_requests.remove(&id) {
327 let response = RawResponse::err( 327 let response = RawResponse::err(
328 id, 328 id,
329 ErrorCode::RequestCancelled as i32, 329 ErrorCode::RequestCanceled as i32,
330 "canceled by client".to_string(), 330 "canceled by client".to_string(),
331 ); 331 );
332 msg_sender.send(RawMessage::Response(response)).unwrap() 332 msg_sender.send(RawMessage::Response(response)).unwrap()