diff options
author | Aleksey Kladov <[email protected]> | 2019-02-08 11:49:43 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-02-08 11:49:43 +0000 |
commit | 12e3b4c70b5ef23b2fdfc197296d483680e125f9 (patch) | |
tree | 71baa0e0a62f9f6b61450501c5f821f67badf9e4 | |
parent | 5cb1d41a30d25cbe136402644bf5434dd667f1e5 (diff) |
reformat the world
129 files changed, 728 insertions, 2510 deletions
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs index 818111fe7..02c7a1858 100644 --- a/crates/gen_lsp_server/src/msg.rs +++ b/crates/gen_lsp_server/src/msg.rs | |||
@@ -80,10 +80,7 @@ impl RawMessage { | |||
80 | #[serde(flatten)] | 80 | #[serde(flatten)] |
81 | msg: RawMessage, | 81 | msg: RawMessage, |
82 | } | 82 | } |
83 | let text = to_string(&JsonRpc { | 83 | let text = to_string(&JsonRpc { jsonrpc: "2.0", msg: self })?; |
84 | jsonrpc: "2.0", | ||
85 | msg: self, | ||
86 | })?; | ||
87 | write_msg_text(w, &text)?; | 84 | write_msg_text(w, &text)?; |
88 | Ok(()) | 85 | Ok(()) |
89 | } | 86 | } |
@@ -95,11 +92,7 @@ impl RawRequest { | |||
95 | R: Request, | 92 | R: Request, |
96 | R::Params: serde::Serialize, | 93 | R::Params: serde::Serialize, |
97 | { | 94 | { |
98 | RawRequest { | 95 | RawRequest { id, method: R::METHOD.to_string(), params: to_value(params).unwrap() } |
99 | id, | ||
100 | method: R::METHOD.to_string(), | ||
101 | params: to_value(params).unwrap(), | ||
102 | } | ||
103 | } | 96 | } |
104 | pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest> | 97 | pub fn cast<R>(self) -> ::std::result::Result<(u64, R::Params), RawRequest> |
105 | where | 98 | where |
@@ -121,23 +114,11 @@ impl RawResponse { | |||
121 | R: Request, | 114 | R: Request, |
122 | R::Result: serde::Serialize, | 115 | R::Result: serde::Serialize, |
123 | { | 116 | { |
124 | RawResponse { | 117 | RawResponse { id, result: Some(to_value(&result).unwrap()), error: None } |
125 | id, | ||
126 | result: Some(to_value(&result).unwrap()), | ||
127 | error: None, | ||
128 | } | ||
129 | } | 118 | } |
130 | pub fn err(id: u64, code: i32, message: String) -> RawResponse { | 119 | pub fn err(id: u64, code: i32, message: String) -> RawResponse { |
131 | let error = RawResponseError { | 120 | let error = RawResponseError { code, message, data: None }; |
132 | code, | 121 | RawResponse { id, result: None, error: Some(error) } |
133 | message, | ||
134 | data: None, | ||
135 | }; | ||
136 | RawResponse { | ||
137 | id, | ||
138 | result: None, | ||
139 | error: Some(error), | ||
140 | } | ||
141 | } | 122 | } |
142 | } | 123 | } |
143 | 124 | ||
@@ -147,10 +128,7 @@ impl RawNotification { | |||
147 | N: Notification, | 128 | N: Notification, |
148 | N::Params: serde::Serialize, | 129 | N::Params: serde::Serialize, |
149 | { | 130 | { |
150 | RawNotification { | 131 | RawNotification { method: N::METHOD.to_string(), params: to_value(params).unwrap() } |
151 | method: N::METHOD.to_string(), | ||
152 | params: to_value(params).unwrap(), | ||
153 | } | ||
154 | } | 132 | } |
155 | pub fn is<N>(&self) -> bool | 133 | pub fn is<N>(&self) -> bool |
156 | where | 134 | where |
@@ -187,9 +165,8 @@ fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> { | |||
187 | } | 165 | } |
188 | let mut parts = buf.splitn(2, ": "); | 166 | let mut parts = buf.splitn(2, ": "); |
189 | let header_name = parts.next().unwrap(); | 167 | let header_name = parts.next().unwrap(); |
190 | let header_value = parts | 168 | let header_value = |
191 | .next() | 169 | parts.next().ok_or_else(|| format_err!("malformed header: {:?}", buf))?; |
192 | .ok_or_else(|| format_err!("malformed header: {:?}", buf))?; | ||
193 | if header_name == "Content-Length" { | 170 | if header_name == "Content-Length" { |
194 | size = Some(header_value.parse::<usize>()?); | 171 | size = Some(header_value.parse::<usize>()?); |
195 | } | 172 | } |
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs index 5c8e33854..dab2d8da8 100644 --- a/crates/gen_lsp_server/src/stdio.rs +++ b/crates/gen_lsp_server/src/stdio.rs | |||
@@ -13,9 +13,7 @@ pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) | |||
13 | let writer = thread::spawn(move || { | 13 | let writer = thread::spawn(move || { |
14 | let stdout = stdout(); | 14 | let stdout = stdout(); |
15 | let mut stdout = stdout.lock(); | 15 | let mut stdout = stdout.lock(); |
16 | writer_receiver | 16 | writer_receiver.into_iter().try_for_each(|it| it.write(&mut stdout))?; |
17 | .into_iter() | ||
18 | .try_for_each(|it| it.write(&mut stdout))?; | ||
19 | Ok(()) | 17 | Ok(()) |
20 | }); | 18 | }); |
21 | let (reader_sender, reader_receiver) = bounded::<RawMessage>(16); | 19 | let (reader_sender, reader_receiver) = bounded::<RawMessage>(16); |
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs index 97f554838..1c97c2662 100644 --- a/crates/ra_arena/src/lib.rs +++ b/crates/ra_arena/src/lib.rs | |||
@@ -44,10 +44,7 @@ pub struct Arena<ID: ArenaId, T> { | |||
44 | 44 | ||
45 | impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> { | 45 | impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> { |
46 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 46 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
47 | fmt.debug_struct("Arena") | 47 | fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish() |
48 | .field("len", &self.len()) | ||
49 | .field("data", &self.data) | ||
50 | .finish() | ||
51 | } | 48 | } |
52 | } | 49 | } |
53 | 50 | ||
@@ -80,19 +77,13 @@ impl<ID: ArenaId, T> Arena<ID, T> { | |||
80 | ID::from_raw(id) | 77 | ID::from_raw(id) |
81 | } | 78 | } |
82 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { | 79 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { |
83 | self.data | 80 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) |
84 | .iter() | ||
85 | .enumerate() | ||
86 | .map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) | ||
87 | } | 81 | } |
88 | } | 82 | } |
89 | 83 | ||
90 | impl<ID: ArenaId, T> Default for Arena<ID, T> { | 84 | impl<ID: ArenaId, T> Default for Arena<ID, T> { |
91 | fn default() -> Arena<ID, T> { | 85 | fn default() -> Arena<ID, T> { |
92 | Arena { | 86 | Arena { data: Vec::new(), _ty: PhantomData } |
93 | data: Vec::new(), | ||
94 | _ty: PhantomData, | ||
95 | } | ||
96 | } | 87 | } |
97 | } | 88 | } |
98 | 89 | ||
@@ -116,9 +107,6 @@ impl<ID: ArenaId, T> FromIterator<T> for Arena<ID, T> { | |||
116 | where | 107 | where |
117 | I: IntoIterator<Item = T>, | 108 | I: IntoIterator<Item = T>, |
118 | { | 109 | { |
119 | Arena { | 110 | Arena { data: Vec::from_iter(iter), _ty: PhantomData } |
120 | data: Vec::from_iter(iter), | ||
121 | _ty: PhantomData, | ||
122 | } | ||
123 | } | 111 | } |
124 | } | 112 | } |
diff --git a/crates/ra_arena/src/map.rs b/crates/ra_arena/src/map.rs index be80edaf3..b73d4e365 100644 --- a/crates/ra_arena/src/map.rs +++ b/crates/ra_arena/src/map.rs | |||
@@ -42,10 +42,7 @@ impl<ID: ArenaId, T> ArenaMap<ID, T> { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> { | 44 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> { |
45 | self.v | 45 | self.v.iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?))) |
46 | .iter() | ||
47 | .enumerate() | ||
48 | .filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?))) | ||
49 | } | 46 | } |
50 | 47 | ||
51 | fn to_idx(id: ID) -> usize { | 48 | fn to_idx(id: ID) -> usize { |
@@ -66,9 +63,6 @@ impl<ID: ArenaId, T> std::ops::Index<ID> for ArenaMap<ID, T> { | |||
66 | 63 | ||
67 | impl<ID, T> Default for ArenaMap<ID, T> { | 64 | impl<ID, T> Default for ArenaMap<ID, T> { |
68 | fn default() -> Self { | 65 | fn default() -> Self { |
69 | ArenaMap { | 66 | ArenaMap { v: Vec::new(), _ty: PhantomData } |
70 | v: Vec::new(), | ||
71 | _ty: PhantomData, | ||
72 | } | ||
73 | } | 67 | } |
74 | } | 68 | } |
diff --git a/crates/ra_assists/src/add_derive.rs b/crates/ra_assists/src/add_derive.rs index 01a4079f6..caf21e079 100644 --- a/crates/ra_assists/src/add_derive.rs +++ b/crates/ra_assists/src/add_derive.rs | |||
@@ -30,10 +30,8 @@ pub(crate) fn add_derive(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
30 | 30 | ||
31 | // Insert `derive` after doc comments. | 31 | // Insert `derive` after doc comments. |
32 | fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> { | 32 | fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> { |
33 | let non_ws_child = nominal | 33 | let non_ws_child = |
34 | .syntax() | 34 | nominal.syntax().children().find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; |
35 | .children() | ||
36 | .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; | ||
37 | Some(non_ws_child.range().start()) | 35 | Some(non_ws_child.range().start()) |
38 | } | 36 | } |
39 | 37 | ||
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs index 699508f91..f2360bc89 100644 --- a/crates/ra_assists/src/add_impl.rs +++ b/crates/ra_assists/src/add_impl.rs | |||
@@ -21,17 +21,11 @@ pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
21 | buf.push_str(" "); | 21 | buf.push_str(" "); |
22 | buf.push_str(name.text().as_str()); | 22 | buf.push_str(name.text().as_str()); |
23 | if let Some(type_params) = type_params { | 23 | if let Some(type_params) = type_params { |
24 | let lifetime_params = type_params | 24 | let lifetime_params = |
25 | .lifetime_params() | 25 | type_params.lifetime_params().filter_map(|it| it.lifetime()).map(|it| it.text()); |
26 | .filter_map(|it| it.lifetime()) | 26 | let type_params = |
27 | .map(|it| it.text()); | 27 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text()); |
28 | let type_params = type_params | 28 | join(lifetime_params.chain(type_params)).surround_with("<", ">").to_buf(&mut buf); |
29 | .type_params() | ||
30 | .filter_map(|it| it.name()) | ||
31 | .map(|it| it.text()); | ||
32 | join(lifetime_params.chain(type_params)) | ||
33 | .surround_with("<", ">") | ||
34 | .to_buf(&mut buf); | ||
35 | } | 29 | } |
36 | buf.push_str(" {\n"); | 30 | buf.push_str(" {\n"); |
37 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); | 31 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); |
@@ -47,11 +41,7 @@ mod tests { | |||
47 | 41 | ||
48 | #[test] | 42 | #[test] |
49 | fn test_add_impl() { | 43 | fn test_add_impl() { |
50 | check_assist( | 44 | check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n<|>\n}\n"); |
51 | add_impl, | ||
52 | "struct Foo {<|>}\n", | ||
53 | "struct Foo {}\n\nimpl Foo {\n<|>\n}\n", | ||
54 | ); | ||
55 | check_assist( | 45 | check_assist( |
56 | add_impl, | 46 | add_impl, |
57 | "struct Foo<T: Clone> {<|>}", | 47 | "struct Foo<T: Clone> {<|>}", |
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 6d09bde52..0bf640241 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -69,12 +69,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
69 | F: FnOnce(AssistCtx<DB>) -> T, | 69 | F: FnOnce(AssistCtx<DB>) -> T, |
70 | { | 70 | { |
71 | let source_file = &db.parse(frange.file_id); | 71 | let source_file = &db.parse(frange.file_id); |
72 | let ctx = AssistCtx { | 72 | let ctx = AssistCtx { db, frange, source_file, should_compute_edit }; |
73 | db, | ||
74 | frange, | ||
75 | source_file, | ||
76 | should_compute_edit, | ||
77 | }; | ||
78 | f(ctx) | 73 | f(ctx) |
79 | } | 74 | } |
80 | 75 | ||
@@ -83,9 +78,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
83 | label: impl Into<String>, | 78 | label: impl Into<String>, |
84 | f: impl FnOnce(&mut AssistBuilder), | 79 | f: impl FnOnce(&mut AssistBuilder), |
85 | ) -> Option<Assist> { | 80 | ) -> Option<Assist> { |
86 | let label = AssistLabel { | 81 | let label = AssistLabel { label: label.into() }; |
87 | label: label.into(), | ||
88 | }; | ||
89 | if !self.should_compute_edit { | 82 | if !self.should_compute_edit { |
90 | return Some(Assist::Unresolved(label)); | 83 | return Some(Assist::Unresolved(label)); |
91 | } | 84 | } |
@@ -146,9 +139,6 @@ impl AssistBuilder { | |||
146 | } | 139 | } |
147 | 140 | ||
148 | fn build(self) -> AssistAction { | 141 | fn build(self) -> AssistAction { |
149 | AssistAction { | 142 | AssistAction { edit: self.edit.finish(), cursor_position: self.cursor_position } |
150 | edit: self.edit.finish(), | ||
151 | cursor_position: self.cursor_position, | ||
152 | } | ||
153 | } | 143 | } |
154 | } | 144 | } |
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs index 4cd32985e..fa5f231c8 100644 --- a/crates/ra_assists/src/change_visibility.rs +++ b/crates/ra_assists/src/change_visibility.rs | |||
@@ -81,31 +81,11 @@ mod tests { | |||
81 | 81 | ||
82 | #[test] | 82 | #[test] |
83 | fn change_visibility_adds_pub_crate_to_items() { | 83 | fn change_visibility_adds_pub_crate_to_items() { |
84 | check_assist( | 84 | check_assist(change_visibility, "<|>fn foo() {}", "<|>pub(crate) fn foo() {}"); |
85 | change_visibility, | 85 | check_assist(change_visibility, "f<|>n foo() {}", "<|>pub(crate) fn foo() {}"); |
86 | "<|>fn foo() {}", | 86 | check_assist(change_visibility, "<|>struct Foo {}", "<|>pub(crate) struct Foo {}"); |
87 | "<|>pub(crate) fn foo() {}", | 87 | check_assist(change_visibility, "<|>mod foo {}", "<|>pub(crate) mod foo {}"); |
88 | ); | 88 | check_assist(change_visibility, "<|>trait Foo {}", "<|>pub(crate) trait Foo {}"); |
89 | check_assist( | ||
90 | change_visibility, | ||
91 | "f<|>n foo() {}", | ||
92 | "<|>pub(crate) fn foo() {}", | ||
93 | ); | ||
94 | check_assist( | ||
95 | change_visibility, | ||
96 | "<|>struct Foo {}", | ||
97 | "<|>pub(crate) struct Foo {}", | ||
98 | ); | ||
99 | check_assist( | ||
100 | change_visibility, | ||
101 | "<|>mod foo {}", | ||
102 | "<|>pub(crate) mod foo {}", | ||
103 | ); | ||
104 | check_assist( | ||
105 | change_visibility, | ||
106 | "<|>trait Foo {}", | ||
107 | "<|>pub(crate) trait Foo {}", | ||
108 | ); | ||
109 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); | 89 | check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); |
110 | check_assist( | 90 | check_assist( |
111 | change_visibility, | 91 | change_visibility, |
@@ -125,20 +105,12 @@ mod tests { | |||
125 | 105 | ||
126 | #[test] | 106 | #[test] |
127 | fn change_visibility_pub_to_pub_crate() { | 107 | fn change_visibility_pub_to_pub_crate() { |
128 | check_assist( | 108 | check_assist(change_visibility, "<|>pub fn foo() {}", "<|>pub(crate) fn foo() {}") |
129 | change_visibility, | ||
130 | "<|>pub fn foo() {}", | ||
131 | "<|>pub(crate) fn foo() {}", | ||
132 | ) | ||
133 | } | 109 | } |
134 | 110 | ||
135 | #[test] | 111 | #[test] |
136 | fn change_visibility_pub_crate_to_pub() { | 112 | fn change_visibility_pub_crate_to_pub() { |
137 | check_assist( | 113 | check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "<|>pub fn foo() {}") |
138 | change_visibility, | ||
139 | "<|>pub(crate) fn foo() {}", | ||
140 | "<|>pub fn foo() {}", | ||
141 | ) | ||
142 | } | 114 | } |
143 | 115 | ||
144 | #[test] | 116 | #[test] |
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index 9aa37d94c..741f75e2a 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs | |||
@@ -27,10 +27,7 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
27 | let node_expr = syntax_mapping.node_expr(expr)?; | 27 | let node_expr = syntax_mapping.node_expr(expr)?; |
28 | let match_expr_ty = infer_result[node_expr].clone(); | 28 | let match_expr_ty = infer_result[node_expr].clone(); |
29 | let enum_def = match match_expr_ty { | 29 | let enum_def = match match_expr_ty { |
30 | Ty::Adt { | 30 | Ty::Adt { def_id: AdtDef::Enum(e), .. } => e, |
31 | def_id: AdtDef::Enum(e), | ||
32 | .. | ||
33 | } => e, | ||
34 | _ => return None, | 31 | _ => return None, |
35 | }; | 32 | }; |
36 | let enum_name = enum_def.name(ctx.db)?; | 33 | let enum_name = enum_def.name(ctx.db)?; |
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index f587b4fe6..4f7c9f3c2 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs | |||
@@ -81,11 +81,7 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> { | |||
81 | return Some((node, false)); | 81 | return Some((node, false)); |
82 | } | 82 | } |
83 | 83 | ||
84 | if let Some(expr) = node | 84 | if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { |
85 | .parent() | ||
86 | .and_then(ast::Block::cast) | ||
87 | .and_then(|it| it.expr()) | ||
88 | { | ||
89 | if expr.syntax() == node { | 85 | if expr.syntax() == node { |
90 | return Some((node, false)); | 86 | return Some((node, false)); |
91 | } | 87 | } |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 555af51bc..881db6347 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -89,9 +89,7 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis | |||
89 | } | 89 | } |
90 | 90 | ||
91 | fn non_trivia_sibling(node: &SyntaxNode, direction: Direction) -> Option<&SyntaxNode> { | 91 | fn non_trivia_sibling(node: &SyntaxNode, direction: Direction) -> Option<&SyntaxNode> { |
92 | node.siblings(direction) | 92 | node.siblings(direction).skip(1).find(|node| !node.kind().is_trivia()) |
93 | .skip(1) | ||
94 | .find(|node| !node.kind().is_trivia()) | ||
95 | } | 93 | } |
96 | 94 | ||
97 | #[cfg(test)] | 95 | #[cfg(test)] |
@@ -110,10 +108,8 @@ mod helpers { | |||
110 | ) { | 108 | ) { |
111 | let (before_cursor_pos, before) = extract_offset(before); | 109 | let (before_cursor_pos, before) = extract_offset(before); |
112 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); | 110 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); |
113 | let frange = FileRange { | 111 | let frange = |
114 | file_id, | 112 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; |
115 | range: TextRange::offset_len(before_cursor_pos, 0.into()), | ||
116 | }; | ||
117 | let assist = | 113 | let assist = |
118 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 114 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
119 | let action = match assist { | 115 | let action = match assist { |
@@ -161,10 +157,8 @@ mod helpers { | |||
161 | ) { | 157 | ) { |
162 | let (before_cursor_pos, before) = extract_offset(before); | 158 | let (before_cursor_pos, before) = extract_offset(before); |
163 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); | 159 | let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); |
164 | let frange = FileRange { | 160 | let frange = |
165 | file_id, | 161 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; |
166 | range: TextRange::offset_len(before_cursor_pos, 0.into()), | ||
167 | }; | ||
168 | let assist = AssistCtx::with_ctx(&db, frange, true, assist); | 162 | let assist = AssistCtx::with_ctx(&db, frange, true, assist); |
169 | assert!(assist.is_none()); | 163 | assert!(assist.is_none()); |
170 | } | 164 | } |
diff --git a/crates/ra_assists/src/replace_if_let_with_match.rs b/crates/ra_assists/src/replace_if_let_with_match.rs index f6af47ec9..683f0d119 100644 --- a/crates/ra_assists/src/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/replace_if_let_with_match.rs | |||
@@ -30,11 +30,7 @@ fn build_match_expr( | |||
30 | ) -> String { | 30 | ) -> String { |
31 | let mut buf = String::new(); | 31 | let mut buf = String::new(); |
32 | buf.push_str(&format!("match {} {{\n", expr.syntax().text())); | 32 | buf.push_str(&format!("match {} {{\n", expr.syntax().text())); |
33 | buf.push_str(&format!( | 33 | buf.push_str(&format!(" {} => {}\n", pat1.syntax().text(), format_arm(arm1))); |
34 | " {} => {}\n", | ||
35 | pat1.syntax().text(), | ||
36 | format_arm(arm1) | ||
37 | )); | ||
38 | buf.push_str(&format!(" _ => {}\n", format_arm(arm2))); | 34 | buf.push_str(&format!(" _ => {}\n", format_arm(arm2))); |
39 | buf.push_str("}"); | 35 | buf.push_str("}"); |
40 | buf | 36 | buf |
diff --git a/crates/ra_assists/src/split_import.rs b/crates/ra_assists/src/split_import.rs index 7e34be087..fb69cef9c 100644 --- a/crates/ra_assists/src/split_import.rs +++ b/crates/ra_assists/src/split_import.rs | |||
@@ -8,9 +8,7 @@ use ra_syntax::{ | |||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist}; |
9 | 9 | ||
10 | pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let colon_colon = ctx | 11 | let colon_colon = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; |
12 | .leaf_at_offset() | ||
13 | .find(|leaf| leaf.kind() == COLONCOLON)?; | ||
14 | let path = colon_colon.parent().and_then(ast::Path::cast)?; | 12 | let path = colon_colon.parent().and_then(ast::Path::cast)?; |
15 | let top_path = generate(Some(path), |it| it.parent_path()).last()?; | 13 | let top_path = generate(Some(path), |it| it.parent_path()).last()?; |
16 | 14 | ||
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 6b5be27be..a4debeb48 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -13,18 +13,8 @@ fn main() -> Result<()> { | |||
13 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) | 13 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) |
14 | .subcommand( | 14 | .subcommand( |
15 | SubCommand::with_name("render-test") | 15 | SubCommand::with_name("render-test") |
16 | .arg( | 16 | .arg(Arg::with_name("line").long("--line").required(true).takes_value(true)) |
17 | Arg::with_name("line") | 17 | .arg(Arg::with_name("file").long("--file").required(true).takes_value(true)), |
18 | .long("--line") | ||
19 | .required(true) | ||
20 | .takes_value(true), | ||
21 | ) | ||
22 | .arg( | ||
23 | Arg::with_name("file") | ||
24 | .long("--file") | ||
25 | .required(true) | ||
26 | .takes_value(true), | ||
27 | ), | ||
28 | ) | 18 | ) |
29 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) | 19 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) |
30 | .subcommand(SubCommand::with_name("symbols")) | 20 | .subcommand(SubCommand::with_name("symbols")) |
@@ -108,8 +98,5 @@ fn selections(file: &SourceFile, start: u32, end: u32) -> String { | |||
108 | .iter() | 98 | .iter() |
109 | .map(|r| (1 + u32::from(r.start()), 1 + u32::from(r.end()))) | 99 | .map(|r| (1 + u32::from(r.start()), 1 + u32::from(r.end()))) |
110 | .map(|(s, e)| format!("({} {})", s, e)); | 100 | .map(|(s, e)| format!("({} {})", s, e)); |
111 | join(ranges) | 101 | join(ranges).separator(" ").surround_with("(", ")").to_string() |
112 | .separator(" ") | ||
113 | .surround_with("(", ")") | ||
114 | .to_string() | ||
115 | } | 102 | } |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 275894252..614325a0f 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -64,10 +64,7 @@ struct CrateData { | |||
64 | 64 | ||
65 | impl CrateData { | 65 | impl CrateData { |
66 | fn new(file_id: FileId) -> CrateData { | 66 | fn new(file_id: FileId) -> CrateData { |
67 | CrateData { | 67 | CrateData { file_id, dependencies: Vec::new() } |
68 | file_id, | ||
69 | dependencies: Vec::new(), | ||
70 | } | ||
71 | } | 68 | } |
72 | 69 | ||
73 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 70 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
@@ -112,10 +109,7 @@ impl CrateGraph { | |||
112 | self.arena[&crate_id].file_id | 109 | self.arena[&crate_id].file_id |
113 | } | 110 | } |
114 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 111 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
115 | let (&crate_id, _) = self | 112 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; |
116 | .arena | ||
117 | .iter() | ||
118 | .find(|(_crate_id, data)| data.file_id == file_id)?; | ||
119 | Some(crate_id) | 113 | Some(crate_id) |
120 | } | 114 | } |
121 | pub fn dependencies<'a>( | 115 | pub fn dependencies<'a>( |
@@ -153,15 +147,9 @@ mod tests { | |||
153 | let crate1 = graph.add_crate_root(FileId(1u32)); | 147 | let crate1 = graph.add_crate_root(FileId(1u32)); |
154 | let crate2 = graph.add_crate_root(FileId(2u32)); | 148 | let crate2 = graph.add_crate_root(FileId(2u32)); |
155 | let crate3 = graph.add_crate_root(FileId(3u32)); | 149 | let crate3 = graph.add_crate_root(FileId(3u32)); |
156 | assert!(graph | 150 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
157 | .add_dep(crate1, SmolStr::new("crate2"), crate2) | 151 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
158 | .is_ok()); | 152 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); |
159 | assert!(graph | ||
160 | .add_dep(crate2, SmolStr::new("crate3"), crate3) | ||
161 | .is_ok()); | ||
162 | assert!(graph | ||
163 | .add_dep(crate3, SmolStr::new("crate1"), crate1) | ||
164 | .is_err()); | ||
165 | } | 153 | } |
166 | 154 | ||
167 | #[test] | 155 | #[test] |
@@ -170,11 +158,7 @@ mod tests { | |||
170 | let crate1 = graph.add_crate_root(FileId(1u32)); | 158 | let crate1 = graph.add_crate_root(FileId(1u32)); |
171 | let crate2 = graph.add_crate_root(FileId(2u32)); | 159 | let crate2 = graph.add_crate_root(FileId(2u32)); |
172 | let crate3 = graph.add_crate_root(FileId(3u32)); | 160 | let crate3 = graph.add_crate_root(FileId(3u32)); |
173 | assert!(graph | 161 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
174 | .add_dep(crate1, SmolStr::new("crate2"), crate2) | 162 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
175 | .is_ok()); | ||
176 | assert!(graph | ||
177 | .add_dep(crate2, SmolStr::new("crate3"), crate3) | ||
178 | .is_ok()); | ||
179 | } | 163 | } |
180 | } | 164 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 66634e05b..31442713d 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -94,11 +94,8 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { | |||
94 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { | 94 | fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { |
95 | let root = db.source_root(id); | 95 | let root = db.source_root(id); |
96 | let graph = db.crate_graph(); | 96 | let graph = db.crate_graph(); |
97 | let res = root | 97 | let res = |
98 | .files | 98 | root.files.values().filter_map(|&it| graph.crate_id_for_crate_root(it)).collect::<Vec<_>>(); |
99 | .values() | ||
100 | .filter_map(|&it| graph.crate_id_for_crate_root(it)) | ||
101 | .collect::<Vec<_>>(); | ||
102 | Arc::new(res) | 99 | Arc::new(res) |
103 | } | 100 | } |
104 | 101 | ||
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 359cd893d..d27fa7682 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs | |||
@@ -30,10 +30,7 @@ where | |||
30 | LOC: Clone + Eq + Hash, | 30 | LOC: Clone + Eq + Hash, |
31 | { | 31 | { |
32 | fn default() -> Self { | 32 | fn default() -> Self { |
33 | Loc2IdMap { | 33 | Loc2IdMap { id2loc: Arena::default(), loc2id: FxHashMap::default() } |
34 | id2loc: Arena::default(), | ||
35 | loc2id: FxHashMap::default(), | ||
36 | } | ||
37 | } | 34 | } |
38 | } | 35 | } |
39 | 36 | ||
@@ -85,9 +82,7 @@ where | |||
85 | LOC: Clone + Eq + Hash, | 82 | LOC: Clone + Eq + Hash, |
86 | { | 83 | { |
87 | fn default() -> Self { | 84 | fn default() -> Self { |
88 | LocationIntener { | 85 | LocationIntener { map: Default::default() } |
89 | map: Default::default(), | ||
90 | } | ||
91 | } | 86 | } |
92 | } | 87 | } |
93 | 88 | ||
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index c549e2126..6d917bb1b 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -62,10 +62,7 @@ impl StructData { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> { | 64 | fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = &ast::EnumVariant> { |
65 | enum_def | 65 | enum_def.variant_list().into_iter().flat_map(|it| it.variants()) |
66 | .variant_list() | ||
67 | .into_iter() | ||
68 | .flat_map(|it| it.variants()) | ||
69 | } | 66 | } |
70 | 67 | ||
71 | impl EnumVariant { | 68 | impl EnumVariant { |
@@ -83,9 +80,7 @@ impl EnumVariant { | |||
83 | (file_id, var) | 80 | (file_id, var) |
84 | } | 81 | } |
85 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { | 82 | pub(crate) fn variant_data(&self, db: &impl PersistentHirDatabase) -> Arc<VariantData> { |
86 | db.enum_data(self.parent).variants[self.id] | 83 | db.enum_data(self.parent).variants[self.id].variant_data.clone() |
87 | .variant_data | ||
88 | .clone() | ||
89 | } | 84 | } |
90 | } | 85 | } |
91 | 86 | ||
@@ -222,14 +217,12 @@ impl StructField { | |||
222 | }; | 217 | }; |
223 | 218 | ||
224 | let field_sources = match struct_flavor { | 219 | let field_sources = match struct_flavor { |
225 | ast::StructFlavor::Tuple(fl) => fl | 220 | ast::StructFlavor::Tuple(fl) => { |
226 | .fields() | 221 | fl.fields().map(|it| FieldSource::Pos(it.to_owned())).collect() |
227 | .map(|it| FieldSource::Pos(it.to_owned())) | 222 | } |
228 | .collect(), | 223 | ast::StructFlavor::Named(fl) => { |
229 | ast::StructFlavor::Named(fl) => fl | 224 | fl.fields().map(|it| FieldSource::Named(it.to_owned())).collect() |
230 | .fields() | 225 | } |
231 | .map(|it| FieldSource::Named(it.to_owned())) | ||
232 | .collect(), | ||
233 | ast::StructFlavor::Unit => Vec::new(), | 226 | ast::StructFlavor::Unit => Vec::new(), |
234 | }; | 227 | }; |
235 | let field = field_sources | 228 | let field = field_sources |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index a58bf8f87..cafc5279d 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -71,17 +71,7 @@ pub enum ModuleDef { | |||
71 | Trait(Trait), | 71 | Trait(Trait), |
72 | Type(Type), | 72 | Type(Type), |
73 | } | 73 | } |
74 | impl_froms!( | 74 | impl_froms!(ModuleDef: Module, Function, Struct, Enum, EnumVariant, Const, Static, Trait, Type); |
75 | ModuleDef: Module, | ||
76 | Function, | ||
77 | Struct, | ||
78 | Enum, | ||
79 | EnumVariant, | ||
80 | Const, | ||
81 | Static, | ||
82 | Trait, | ||
83 | Type | ||
84 | ); | ||
85 | 75 | ||
86 | pub enum ModuleSource { | 76 | pub enum ModuleSource { |
87 | SourceFile(TreeArc<ast::SourceFile>), | 77 | SourceFile(TreeArc<ast::SourceFile>), |
@@ -90,13 +80,8 @@ pub enum ModuleSource { | |||
90 | 80 | ||
91 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | 81 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] |
92 | pub enum Problem { | 82 | pub enum Problem { |
93 | UnresolvedModule { | 83 | UnresolvedModule { candidate: RelativePathBuf }, |
94 | candidate: RelativePathBuf, | 84 | NotDirOwner { move_to: RelativePathBuf, candidate: RelativePathBuf }, |
95 | }, | ||
96 | NotDirOwner { | ||
97 | move_to: RelativePathBuf, | ||
98 | candidate: RelativePathBuf, | ||
99 | }, | ||
100 | } | 85 | } |
101 | 86 | ||
102 | impl Module { | 87 | impl Module { |
@@ -187,8 +172,7 @@ impl Module { | |||
187 | 172 | ||
188 | impl Docs for Module { | 173 | impl Docs for Module { |
189 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | 174 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { |
190 | self.declaration_source(db) | 175 | self.declaration_source(db).and_then(|it| docs_from_ast(&*it.1)) |
191 | .and_then(|it| docs_from_ast(&*it.1)) | ||
192 | } | 176 | } |
193 | } | 177 | } |
194 | 178 | ||
@@ -206,9 +190,7 @@ pub enum FieldSource { | |||
206 | 190 | ||
207 | impl StructField { | 191 | impl StructField { |
208 | pub fn name(&self, db: &impl HirDatabase) -> Name { | 192 | pub fn name(&self, db: &impl HirDatabase) -> Name { |
209 | self.parent.variant_data(db).fields().unwrap()[self.id] | 193 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() |
210 | .name | ||
211 | .clone() | ||
212 | } | 194 | } |
213 | 195 | ||
214 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { | 196 | pub fn source(&self, db: &impl PersistentHirDatabase) -> (HirFileId, FieldSource) { |
@@ -257,10 +239,7 @@ impl Struct { | |||
257 | .fields() | 239 | .fields() |
258 | .into_iter() | 240 | .into_iter() |
259 | .flat_map(|it| it.iter()) | 241 | .flat_map(|it| it.iter()) |
260 | .map(|(id, _)| StructField { | 242 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
261 | parent: (*self).into(), | ||
262 | id, | ||
263 | }) | ||
264 | .collect() | 243 | .collect() |
265 | } | 244 | } |
266 | 245 | ||
@@ -271,10 +250,7 @@ impl Struct { | |||
271 | .into_iter() | 250 | .into_iter() |
272 | .flat_map(|it| it.iter()) | 251 | .flat_map(|it| it.iter()) |
273 | .find(|(_id, data)| data.name == *name) | 252 | .find(|(_id, data)| data.name == *name) |
274 | .map(|(id, _)| StructField { | 253 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
275 | parent: (*self).into(), | ||
276 | id, | ||
277 | }) | ||
278 | } | 254 | } |
279 | 255 | ||
280 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { | 256 | pub fn generic_params(&self, db: &impl PersistentHirDatabase) -> Arc<GenericParams> { |
@@ -292,11 +268,7 @@ impl Struct { | |||
292 | let r = self.module(db).resolver(db); | 268 | let r = self.module(db).resolver(db); |
293 | // ...and add generic params, if present | 269 | // ...and add generic params, if present |
294 | let p = self.generic_params(db); | 270 | let p = self.generic_params(db); |
295 | let r = if !p.params.is_empty() { | 271 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
296 | r.push_generic_params_scope(p) | ||
297 | } else { | ||
298 | r | ||
299 | }; | ||
300 | r | 272 | r |
301 | } | 273 | } |
302 | } | 274 | } |
@@ -356,11 +328,7 @@ impl Enum { | |||
356 | let r = self.module(db).resolver(db); | 328 | let r = self.module(db).resolver(db); |
357 | // ...and add generic params, if present | 329 | // ...and add generic params, if present |
358 | let p = self.generic_params(db); | 330 | let p = self.generic_params(db); |
359 | let r = if !p.params.is_empty() { | 331 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
360 | r.push_generic_params_scope(p) | ||
361 | } else { | ||
362 | r | ||
363 | }; | ||
364 | r | 332 | r |
365 | } | 333 | } |
366 | } | 334 | } |
@@ -400,10 +368,7 @@ impl EnumVariant { | |||
400 | .fields() | 368 | .fields() |
401 | .into_iter() | 369 | .into_iter() |
402 | .flat_map(|it| it.iter()) | 370 | .flat_map(|it| it.iter()) |
403 | .map(|(id, _)| StructField { | 371 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
404 | parent: (*self).into(), | ||
405 | id, | ||
406 | }) | ||
407 | .collect() | 372 | .collect() |
408 | } | 373 | } |
409 | 374 | ||
@@ -413,10 +378,7 @@ impl EnumVariant { | |||
413 | .into_iter() | 378 | .into_iter() |
414 | .flat_map(|it| it.iter()) | 379 | .flat_map(|it| it.iter()) |
415 | .find(|(_id, data)| data.name == *name) | 380 | .find(|(_id, data)| data.name == *name) |
416 | .map(|(id, _)| StructField { | 381 | .map(|(id, _)| StructField { parent: (*self).into(), id }) |
417 | parent: (*self).into(), | ||
418 | id, | ||
419 | }) | ||
420 | } | 382 | } |
421 | } | 383 | } |
422 | 384 | ||
@@ -488,10 +450,7 @@ impl Function { | |||
488 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { | 450 | pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { |
489 | let scopes = db.expr_scopes(*self); | 451 | let scopes = db.expr_scopes(*self); |
490 | let syntax_mapping = db.body_syntax_mapping(*self); | 452 | let syntax_mapping = db.body_syntax_mapping(*self); |
491 | ScopesWithSyntaxMapping { | 453 | ScopesWithSyntaxMapping { scopes, syntax_mapping } |
492 | scopes, | ||
493 | syntax_mapping, | ||
494 | } | ||
495 | } | 454 | } |
496 | 455 | ||
497 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { | 456 | pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> { |
@@ -516,11 +475,7 @@ impl Function { | |||
516 | .unwrap_or_else(|| self.module(db).resolver(db)); | 475 | .unwrap_or_else(|| self.module(db).resolver(db)); |
517 | // ...and add generic params, if present | 476 | // ...and add generic params, if present |
518 | let p = self.generic_params(db); | 477 | let p = self.generic_params(db); |
519 | let r = if !p.params.is_empty() { | 478 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
520 | r.push_generic_params_scope(p) | ||
521 | } else { | ||
522 | r | ||
523 | }; | ||
524 | r | 479 | r |
525 | } | 480 | } |
526 | } | 481 | } |
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs index 8326c02c7..b9438fdb7 100644 --- a/crates/ra_hir/src/code_model_impl/function.rs +++ b/crates/ra_hir/src/code_model_impl/function.rs | |||
@@ -25,10 +25,7 @@ impl FnSignature { | |||
25 | func: Function, | 25 | func: Function, |
26 | ) -> Arc<FnSignature> { | 26 | ) -> Arc<FnSignature> { |
27 | let (_, node) = func.source(db); | 27 | let (_, node) = func.source(db); |
28 | let name = node | 28 | let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); |
29 | .name() | ||
30 | .map(|n| n.as_name()) | ||
31 | .unwrap_or_else(Name::missing); | ||
32 | let mut params = Vec::new(); | 29 | let mut params = Vec::new(); |
33 | let mut has_self_param = false; | 30 | let mut has_self_param = false; |
34 | if let Some(param_list) = node.param_list() { | 31 | if let Some(param_list) = node.param_list() { |
@@ -61,12 +58,7 @@ impl FnSignature { | |||
61 | TypeRef::unit() | 58 | TypeRef::unit() |
62 | }; | 59 | }; |
63 | 60 | ||
64 | let sig = FnSignature { | 61 | let sig = FnSignature { name, params, ret_type, has_self_param }; |
65 | name, | ||
66 | params, | ||
67 | ret_type, | ||
68 | has_self_param, | ||
69 | }; | ||
70 | Arc::new(sig) | 62 | Arc::new(sig) |
71 | } | 63 | } |
72 | } | 64 | } |
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 1517434b8..161ae6e18 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -11,9 +11,7 @@ impl Crate { | |||
11 | crate_graph | 11 | crate_graph |
12 | .dependencies(self.crate_id) | 12 | .dependencies(self.crate_id) |
13 | .map(|dep| { | 13 | .map(|dep| { |
14 | let krate = Crate { | 14 | let krate = Crate { crate_id: dep.crate_id() }; |
15 | crate_id: dep.crate_id(), | ||
16 | }; | ||
17 | let name = dep.as_name(); | 15 | let name = dep.as_name(); |
18 | CrateDependency { krate, name } | 16 | CrateDependency { krate, name } |
19 | }) | 17 | }) |
@@ -23,10 +21,7 @@ impl Crate { | |||
23 | let module_tree = db.module_tree(*self); | 21 | let module_tree = db.module_tree(*self); |
24 | let module_id = module_tree.modules().next()?; | 22 | let module_id = module_tree.modules().next()?; |
25 | 23 | ||
26 | let module = Module { | 24 | let module = Module { krate: *self, module_id }; |
27 | krate: *self, | ||
28 | module_id, | ||
29 | }; | ||
30 | Some(module) | 25 | Some(module) |
31 | } | 26 | } |
32 | } | 27 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index f487b8532..1425fa693 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -12,10 +12,7 @@ use crate::{ | |||
12 | 12 | ||
13 | impl Module { | 13 | impl Module { |
14 | fn with_module_id(&self, module_id: ModuleId) -> Module { | 14 | fn with_module_id(&self, module_id: ModuleId) -> Module { |
15 | Module { | 15 | Module { module_id, krate: self.krate } |
16 | module_id, | ||
17 | krate: self.krate, | ||
18 | } | ||
19 | } | 16 | } |
20 | 17 | ||
21 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { | 18 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { |
@@ -42,10 +39,7 @@ impl Module { | |||
42 | ) -> Option<(FileId, TreeArc<ast::Module>)> { | 39 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
43 | let module_tree = db.module_tree(self.krate); | 40 | let module_tree = db.module_tree(self.krate); |
44 | let link = self.module_id.parent_link(&module_tree)?; | 41 | let link = self.module_id.parent_link(&module_tree)?; |
45 | let file_id = link | 42 | let file_id = link.owner(&module_tree).file_id(&module_tree).as_original_file(); |
46 | .owner(&module_tree) | ||
47 | .file_id(&module_tree) | ||
48 | .as_original_file(); | ||
49 | let src = link.source(&module_tree, db); | 43 | let src = link.source(&module_tree, db); |
50 | Some((file_id, src)) | 44 | Some((file_id, src)) |
51 | } | 45 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6826e966b..4e61d87ff 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -121,9 +121,7 @@ impl BodySyntaxMapping { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 123 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
124 | self.expr_syntax_mapping | 124 | self.expr_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
125 | .get(&SyntaxNodePtr::new(node.syntax())) | ||
126 | .cloned() | ||
127 | } | 125 | } |
128 | 126 | ||
129 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { | 127 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { |
@@ -135,9 +133,7 @@ impl BodySyntaxMapping { | |||
135 | } | 133 | } |
136 | 134 | ||
137 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 135 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
138 | self.pat_syntax_mapping | 136 | self.pat_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
139 | .get(&SyntaxNodePtr::new(node.syntax())) | ||
140 | .cloned() | ||
141 | } | 137 | } |
142 | 138 | ||
143 | pub fn body(&self) -> &Arc<Body> { | 139 | pub fn body(&self) -> &Arc<Body> { |
@@ -262,11 +258,7 @@ pub struct StructLitField { | |||
262 | 258 | ||
263 | #[derive(Debug, Clone, Eq, PartialEq)] | 259 | #[derive(Debug, Clone, Eq, PartialEq)] |
264 | pub enum Statement { | 260 | pub enum Statement { |
265 | Let { | 261 | Let { pat: PatId, type_ref: Option<TypeRef>, initializer: Option<ExprId> }, |
266 | pat: PatId, | ||
267 | type_ref: Option<TypeRef>, | ||
268 | initializer: Option<ExprId>, | ||
269 | }, | ||
270 | Expr(ExprId), | 262 | Expr(ExprId), |
271 | } | 263 | } |
272 | 264 | ||
@@ -275,11 +267,7 @@ impl Expr { | |||
275 | match self { | 267 | match self { |
276 | Expr::Missing => {} | 268 | Expr::Missing => {} |
277 | Expr::Path(_) => {} | 269 | Expr::Path(_) => {} |
278 | Expr::If { | 270 | Expr::If { condition, then_branch, else_branch } => { |
279 | condition, | ||
280 | then_branch, | ||
281 | else_branch, | ||
282 | } => { | ||
283 | f(*condition); | 271 | f(*condition); |
284 | f(*then_branch); | 272 | f(*then_branch); |
285 | if let Some(else_branch) = else_branch { | 273 | if let Some(else_branch) = else_branch { |
@@ -457,11 +445,7 @@ impl Pat { | |||
457 | args.iter().map(|pat| *pat).for_each(f); | 445 | args.iter().map(|pat| *pat).for_each(f); |
458 | } | 446 | } |
459 | Pat::Ref { pat, .. } => f(*pat), | 447 | Pat::Ref { pat, .. } => f(*pat), |
460 | Pat::Slice { | 448 | Pat::Slice { prefix, rest, suffix } => { |
461 | prefix, | ||
462 | rest, | ||
463 | suffix, | ||
464 | } => { | ||
465 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); | 449 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); |
466 | total_iter.map(|pat| *pat).for_each(f); | 450 | total_iter.map(|pat| *pat).for_each(f); |
467 | } | 451 | } |
@@ -520,10 +504,7 @@ impl ExprCollector { | |||
520 | } | 504 | } |
521 | 505 | ||
522 | fn empty_block(&mut self) -> ExprId { | 506 | fn empty_block(&mut self) -> ExprId { |
523 | let block = Expr::Block { | 507 | let block = Expr::Block { statements: Vec::new(), tail: None }; |
524 | statements: Vec::new(), | ||
525 | tail: None, | ||
526 | }; | ||
527 | self.exprs.alloc(block) | 508 | self.exprs.alloc(block) |
528 | } | 509 | } |
529 | 510 | ||
@@ -549,24 +530,10 @@ impl ExprCollector { | |||
549 | .unwrap_or_else(|| self.empty_block()); | 530 | .unwrap_or_else(|| self.empty_block()); |
550 | let placeholder_pat = self.pats.alloc(Pat::Missing); | 531 | let placeholder_pat = self.pats.alloc(Pat::Missing); |
551 | let arms = vec![ | 532 | let arms = vec![ |
552 | MatchArm { | 533 | MatchArm { pats: vec![pat], expr: then_branch, guard: None }, |
553 | pats: vec![pat], | 534 | MatchArm { pats: vec![placeholder_pat], expr: else_branch, guard: None }, |
554 | expr: then_branch, | ||
555 | guard: None, | ||
556 | }, | ||
557 | MatchArm { | ||
558 | pats: vec![placeholder_pat], | ||
559 | expr: else_branch, | ||
560 | guard: None, | ||
561 | }, | ||
562 | ]; | 535 | ]; |
563 | self.alloc_expr( | 536 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr) |
564 | Expr::Match { | ||
565 | expr: match_expr, | ||
566 | arms, | ||
567 | }, | ||
568 | syntax_ptr, | ||
569 | ) | ||
570 | } else { | 537 | } else { |
571 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); | 538 | let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr())); |
572 | let then_branch = self.collect_block_opt(e.then_branch()); | 539 | let then_branch = self.collect_block_opt(e.then_branch()); |
@@ -577,14 +544,7 @@ impl ExprCollector { | |||
577 | self.collect_expr(expr) | 544 | self.collect_expr(expr) |
578 | } | 545 | } |
579 | }); | 546 | }); |
580 | self.alloc_expr( | 547 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) |
581 | Expr::If { | ||
582 | condition, | ||
583 | then_branch, | ||
584 | else_branch, | ||
585 | }, | ||
586 | syntax_ptr, | ||
587 | ) | ||
588 | } | 548 | } |
589 | } | 549 | } |
590 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), | 550 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), |
@@ -610,14 +570,7 @@ impl ExprCollector { | |||
610 | let iterable = self.collect_expr_opt(e.iterable()); | 570 | let iterable = self.collect_expr_opt(e.iterable()); |
611 | let pat = self.collect_pat_opt(e.pat()); | 571 | let pat = self.collect_pat_opt(e.pat()); |
612 | let body = self.collect_block_opt(e.loop_body()); | 572 | let body = self.collect_block_opt(e.loop_body()); |
613 | self.alloc_expr( | 573 | self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) |
614 | Expr::For { | ||
615 | iterable, | ||
616 | pat, | ||
617 | body, | ||
618 | }, | ||
619 | syntax_ptr, | ||
620 | ) | ||
621 | } | 574 | } |
622 | ast::ExprKind::CallExpr(e) => { | 575 | ast::ExprKind::CallExpr(e) => { |
623 | let callee = self.collect_expr_opt(e.expr()); | 576 | let callee = self.collect_expr_opt(e.expr()); |
@@ -635,18 +588,8 @@ impl ExprCollector { | |||
635 | } else { | 588 | } else { |
636 | Vec::new() | 589 | Vec::new() |
637 | }; | 590 | }; |
638 | let method_name = e | 591 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
639 | .name_ref() | 592 | self.alloc_expr(Expr::MethodCall { receiver, method_name, args }, syntax_ptr) |
640 | .map(|nr| nr.as_name()) | ||
641 | .unwrap_or_else(Name::missing); | ||
642 | self.alloc_expr( | ||
643 | Expr::MethodCall { | ||
644 | receiver, | ||
645 | method_name, | ||
646 | args, | ||
647 | }, | ||
648 | syntax_ptr, | ||
649 | ) | ||
650 | } | 593 | } |
651 | ast::ExprKind::MatchExpr(e) => { | 594 | ast::ExprKind::MatchExpr(e) => { |
652 | let expr = self.collect_expr_opt(e.expr()); | 595 | let expr = self.collect_expr_opt(e.expr()); |
@@ -668,11 +611,8 @@ impl ExprCollector { | |||
668 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) | 611 | self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) |
669 | } | 612 | } |
670 | ast::ExprKind::PathExpr(e) => { | 613 | ast::ExprKind::PathExpr(e) => { |
671 | let path = e | 614 | let path = |
672 | .path() | 615 | e.path().and_then(Path::from_ast).map(Expr::Path).unwrap_or(Expr::Missing); |
673 | .and_then(Path::from_ast) | ||
674 | .map(Expr::Path) | ||
675 | .unwrap_or(Expr::Missing); | ||
676 | self.alloc_expr(path, syntax_ptr) | 616 | self.alloc_expr(path, syntax_ptr) |
677 | } | 617 | } |
678 | ast::ExprKind::ContinueExpr(_e) => { | 618 | ast::ExprKind::ContinueExpr(_e) => { |
@@ -721,21 +661,11 @@ impl ExprCollector { | |||
721 | Vec::new() | 661 | Vec::new() |
722 | }; | 662 | }; |
723 | let spread = e.spread().map(|s| self.collect_expr(s)); | 663 | let spread = e.spread().map(|s| self.collect_expr(s)); |
724 | self.alloc_expr( | 664 | self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr) |
725 | Expr::StructLit { | ||
726 | path, | ||
727 | fields, | ||
728 | spread, | ||
729 | }, | ||
730 | syntax_ptr, | ||
731 | ) | ||
732 | } | 665 | } |
733 | ast::ExprKind::FieldExpr(e) => { | 666 | ast::ExprKind::FieldExpr(e) => { |
734 | let expr = self.collect_expr_opt(e.expr()); | 667 | let expr = self.collect_expr_opt(e.expr()); |
735 | let name = e | 668 | let name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
736 | .name_ref() | ||
737 | .map(|nr| nr.as_name()) | ||
738 | .unwrap_or_else(Name::missing); | ||
739 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) | 669 | self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) |
740 | } | 670 | } |
741 | ast::ExprKind::TryExpr(e) => { | 671 | ast::ExprKind::TryExpr(e) => { |
@@ -772,14 +702,7 @@ impl ExprCollector { | |||
772 | } | 702 | } |
773 | } | 703 | } |
774 | let body = self.collect_expr_opt(e.body()); | 704 | let body = self.collect_expr_opt(e.body()); |
775 | self.alloc_expr( | 705 | self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) |
776 | Expr::Lambda { | ||
777 | args, | ||
778 | arg_types, | ||
779 | body, | ||
780 | }, | ||
781 | syntax_ptr, | ||
782 | ) | ||
783 | } | 706 | } |
784 | ast::ExprKind::BinExpr(e) => { | 707 | ast::ExprKind::BinExpr(e) => { |
785 | let lhs = self.collect_expr_opt(e.lhs()); | 708 | let lhs = self.collect_expr_opt(e.lhs()); |
@@ -804,9 +727,8 @@ impl ExprCollector { | |||
804 | 727 | ||
805 | let lit = match child.flavor() { | 728 | let lit = match child.flavor() { |
806 | LiteralFlavor::IntNumber { suffix } => { | 729 | LiteralFlavor::IntNumber { suffix } => { |
807 | let known_name = suffix | 730 | let known_name = |
808 | .map(Name::new) | 731 | suffix.map(Name::new).and_then(|name| UncertainIntTy::from_name(&name)); |
809 | .and_then(|name| UncertainIntTy::from_name(&name)); | ||
810 | 732 | ||
811 | Literal::Int( | 733 | Literal::Int( |
812 | Default::default(), | 734 | Default::default(), |
@@ -857,11 +779,7 @@ impl ExprCollector { | |||
857 | let pat = self.collect_pat_opt(stmt.pat()); | 779 | let pat = self.collect_pat_opt(stmt.pat()); |
858 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); | 780 | let type_ref = stmt.type_ref().map(TypeRef::from_ast); |
859 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 781 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
860 | Statement::Let { | 782 | Statement::Let { pat, type_ref, initializer } |
861 | pat, | ||
862 | type_ref, | ||
863 | initializer, | ||
864 | } | ||
865 | } | 783 | } |
866 | ast::StmtKind::ExprStmt(stmt) => { | 784 | ast::StmtKind::ExprStmt(stmt) => { |
867 | Statement::Expr(self.collect_expr_opt(stmt.expr())) | 785 | Statement::Expr(self.collect_expr_opt(stmt.expr())) |
@@ -869,10 +787,7 @@ impl ExprCollector { | |||
869 | }) | 787 | }) |
870 | .collect(); | 788 | .collect(); |
871 | let tail = block.expr().map(|e| self.collect_expr(e)); | 789 | let tail = block.expr().map(|e| self.collect_expr(e)); |
872 | self.alloc_expr( | 790 | self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) |
873 | Expr::Block { statements, tail }, | ||
874 | SyntaxNodePtr::new(block.syntax()), | ||
875 | ) | ||
876 | } | 791 | } |
877 | 792 | ||
878 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { | 793 | fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId { |
@@ -886,17 +801,10 @@ impl ExprCollector { | |||
886 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { | 801 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { |
887 | let pattern = match pat.kind() { | 802 | let pattern = match pat.kind() { |
888 | ast::PatKind::BindPat(bp) => { | 803 | ast::PatKind::BindPat(bp) => { |
889 | let name = bp | 804 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
890 | .name() | ||
891 | .map(|nr| nr.as_name()) | ||
892 | .unwrap_or_else(Name::missing); | ||
893 | let annotation = BindingAnnotation::new(bp.is_mutable(), bp.is_ref()); | 805 | let annotation = BindingAnnotation::new(bp.is_mutable(), bp.is_ref()); |
894 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); | 806 | let subpat = bp.pat().map(|subpat| self.collect_pat(subpat)); |
895 | Pat::Bind { | 807 | Pat::Bind { name, mode: annotation, subpat } |
896 | name, | ||
897 | mode: annotation, | ||
898 | subpat, | ||
899 | } | ||
900 | } | 808 | } |
901 | ast::PatKind::TupleStructPat(p) => { | 809 | ast::PatKind::TupleStructPat(p) => { |
902 | let path = p.path().and_then(Path::from_ast); | 810 | let path = p.path().and_then(Path::from_ast); |
@@ -919,9 +827,8 @@ impl ExprCollector { | |||
919 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, | 827 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, |
920 | ast::PatKind::StructPat(p) => { | 828 | ast::PatKind::StructPat(p) => { |
921 | let path = p.path().and_then(Path::from_ast); | 829 | let path = p.path().and_then(Path::from_ast); |
922 | let field_pat_list = p | 830 | let field_pat_list = |
923 | .field_pat_list() | 831 | p.field_pat_list().expect("every struct should have a field list"); |
924 | .expect("every struct should have a field list"); | ||
925 | let mut fields: Vec<_> = field_pat_list | 832 | let mut fields: Vec<_> = field_pat_list |
926 | .bind_pats() | 833 | .bind_pats() |
927 | .map(|bind_pat| { | 834 | .map(|bind_pat| { |
@@ -961,10 +868,7 @@ impl ExprCollector { | |||
961 | if let Some(param_list) = node.param_list() { | 868 | if let Some(param_list) = node.param_list() { |
962 | if let Some(self_param) = param_list.self_param() { | 869 | if let Some(self_param) = param_list.self_param() { |
963 | let self_param = SyntaxNodePtr::new( | 870 | let self_param = SyntaxNodePtr::new( |
964 | self_param | 871 | self_param.self_kw().expect("self param without self keyword").syntax(), |
965 | .self_kw() | ||
966 | .expect("self param without self keyword") | ||
967 | .syntax(), | ||
968 | ); | 872 | ); |
969 | let param_pat = self.alloc_pat( | 873 | let param_pat = self.alloc_pat( |
970 | Pat::Bind { | 874 | Pat::Bind { |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 368994bf7..44d5c2429 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -74,17 +74,11 @@ impl ExprScopes { | |||
74 | } | 74 | } |
75 | 75 | ||
76 | fn root_scope(&mut self) -> ScopeId { | 76 | fn root_scope(&mut self) -> ScopeId { |
77 | self.scopes.alloc(ScopeData { | 77 | self.scopes.alloc(ScopeData { parent: None, entries: vec![] }) |
78 | parent: None, | ||
79 | entries: vec![], | ||
80 | }) | ||
81 | } | 78 | } |
82 | 79 | ||
83 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { | 80 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { |
84 | self.scopes.alloc(ScopeData { | 81 | self.scopes.alloc(ScopeData { parent: Some(parent), entries: vec![] }) |
85 | parent: Some(parent), | ||
86 | entries: vec![], | ||
87 | }) | ||
88 | } | 82 | } |
89 | 83 | ||
90 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { | 84 | fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { |
@@ -92,10 +86,7 @@ impl ExprScopes { | |||
92 | Pat::Bind { name, .. } => { | 86 | Pat::Bind { name, .. } => { |
93 | // bind can have a subpattern, but it's actually not allowed | 87 | // bind can have a subpattern, but it's actually not allowed |
94 | // to bind to things in there | 88 | // to bind to things in there |
95 | let entry = ScopeEntry { | 89 | let entry = ScopeEntry { name: name.clone(), pat }; |
96 | name: name.clone(), | ||
97 | pat, | ||
98 | }; | ||
99 | self.scopes[scope].entries.push(entry) | 90 | self.scopes[scope].entries.push(entry) |
100 | } | 91 | } |
101 | p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), | 92 | p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), |
@@ -104,9 +95,7 @@ impl ExprScopes { | |||
104 | 95 | ||
105 | fn add_params_bindings(&mut self, scope: ScopeId, params: &[PatId]) { | 96 | fn add_params_bindings(&mut self, scope: ScopeId, params: &[PatId]) { |
106 | let body = Arc::clone(&self.body); | 97 | let body = Arc::clone(&self.body); |
107 | params | 98 | params.iter().for_each(|pat| self.add_bindings(&body, scope, *pat)); |
108 | .iter() | ||
109 | .for_each(|pat| self.add_bindings(&body, scope, *pat)); | ||
110 | } | 99 | } |
111 | 100 | ||
112 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { | 101 | fn set_scope(&mut self, node: ExprId, scope: ScopeId) { |
@@ -142,9 +131,7 @@ impl ScopeEntryWithSyntax { | |||
142 | 131 | ||
143 | impl ScopesWithSyntaxMapping { | 132 | impl ScopesWithSyntaxMapping { |
144 | fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { | 133 | fn scope_chain<'a>(&'a self, node: &SyntaxNode) -> impl Iterator<Item = ScopeId> + 'a { |
145 | generate(self.scope_for(node), move |&scope| { | 134 | generate(self.scope_for(node), move |&scope| self.scopes.scopes[scope].parent) |
146 | self.scopes.scopes[scope].parent | ||
147 | }) | ||
148 | } | 135 | } |
149 | 136 | ||
150 | pub fn scope_for_offset(&self, offset: TextUnit) -> Option<ScopeId> { | 137 | pub fn scope_for_offset(&self, offset: TextUnit) -> Option<ScopeId> { |
@@ -154,10 +141,7 @@ impl ScopesWithSyntaxMapping { | |||
154 | .filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope))) | 141 | .filter_map(|(id, scope)| Some((self.syntax_mapping.expr_syntax(*id)?, scope))) |
155 | // find containing scope | 142 | // find containing scope |
156 | .min_by_key(|(ptr, _scope)| { | 143 | .min_by_key(|(ptr, _scope)| { |
157 | ( | 144 | (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) |
158 | !(ptr.range().start() <= offset && offset <= ptr.range().end()), | ||
159 | ptr.range().len(), | ||
160 | ) | ||
161 | }) | 145 | }) |
162 | .map(|(ptr, scope)| self.adjust(ptr, *scope, offset)) | 146 | .map(|(ptr, scope)| self.adjust(ptr, *scope, offset)) |
163 | } | 147 | } |
@@ -251,9 +235,7 @@ fn compute_block_scopes( | |||
251 | ) { | 235 | ) { |
252 | for stmt in statements { | 236 | for stmt in statements { |
253 | match stmt { | 237 | match stmt { |
254 | Statement::Let { | 238 | Statement::Let { pat, initializer, .. } => { |
255 | pat, initializer, .. | ||
256 | } => { | ||
257 | if let Some(expr) = initializer { | 239 | if let Some(expr) = initializer { |
258 | scopes.set_scope(*expr, scope); | 240 | scopes.set_scope(*expr, scope); |
259 | compute_expr_scopes(*expr, body, scopes, scope); | 241 | compute_expr_scopes(*expr, body, scopes, scope); |
@@ -278,21 +260,13 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope | |||
278 | Expr::Block { statements, tail } => { | 260 | Expr::Block { statements, tail } => { |
279 | compute_block_scopes(&statements, *tail, body, scopes, scope); | 261 | compute_block_scopes(&statements, *tail, body, scopes, scope); |
280 | } | 262 | } |
281 | Expr::For { | 263 | Expr::For { iterable, pat, body: body_expr } => { |
282 | iterable, | ||
283 | pat, | ||
284 | body: body_expr, | ||
285 | } => { | ||
286 | compute_expr_scopes(*iterable, body, scopes, scope); | 264 | compute_expr_scopes(*iterable, body, scopes, scope); |
287 | let scope = scopes.new_scope(scope); | 265 | let scope = scopes.new_scope(scope); |
288 | scopes.add_bindings(body, scope, *pat); | 266 | scopes.add_bindings(body, scope, *pat); |
289 | compute_expr_scopes(*body_expr, body, scopes, scope); | 267 | compute_expr_scopes(*body_expr, body, scopes, scope); |
290 | } | 268 | } |
291 | Expr::Lambda { | 269 | Expr::Lambda { args, body: body_expr, .. } => { |
292 | args, | ||
293 | body: body_expr, | ||
294 | .. | ||
295 | } => { | ||
296 | let scope = scopes.new_scope(scope); | 270 | let scope = scopes.new_scope(scope); |
297 | scopes.add_params_bindings(scope, &args); | 271 | scopes.add_params_bindings(scope, &args); |
298 | compute_expr_scopes(*body_expr, body, scopes, scope); | 272 | compute_expr_scopes(*body_expr, body, scopes, scope); |
@@ -341,9 +315,7 @@ mod tests { | |||
341 | let file = SourceFile::parse(&code); | 315 | let file = SourceFile::parse(&code); |
342 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); | 316 | let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); |
343 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 317 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
344 | let irrelevant_function = Function { | 318 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; |
345 | id: crate::ids::FunctionId::from_raw(0.into()), | ||
346 | }; | ||
347 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); | 319 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); |
348 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); | 320 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); |
349 | let scopes = ScopesWithSyntaxMapping { | 321 | let scopes = ScopesWithSyntaxMapping { |
@@ -444,9 +416,7 @@ mod tests { | |||
444 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); | 416 | let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); |
445 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); | 417 | let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); |
446 | 418 | ||
447 | let irrelevant_function = Function { | 419 | let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; |
448 | id: crate::ids::FunctionId::from_raw(0.into()), | ||
449 | }; | ||
450 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); | 420 | let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); |
451 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); | 421 | let scopes = ExprScopes::new(Arc::clone(body_hir.body())); |
452 | let scopes = ScopesWithSyntaxMapping { | 422 | let scopes = ScopesWithSyntaxMapping { |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index a82205f0b..c72360f44 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -58,14 +58,8 @@ impl GenericParams { | |||
58 | 58 | ||
59 | fn fill_params(&mut self, params: &ast::TypeParamList) { | 59 | fn fill_params(&mut self, params: &ast::TypeParamList) { |
60 | for (idx, type_param) in params.type_params().enumerate() { | 60 | for (idx, type_param) in params.type_params().enumerate() { |
61 | let name = type_param | 61 | let name = type_param.name().map(AsName::as_name).unwrap_or_else(Name::missing); |
62 | .name() | 62 | let param = GenericParam { idx: idx as u32, name }; |
63 | .map(AsName::as_name) | ||
64 | .unwrap_or_else(Name::missing); | ||
65 | let param = GenericParam { | ||
66 | idx: idx as u32, | ||
67 | name, | ||
68 | }; | ||
69 | self.params.push(param); | 63 | self.params.push(param); |
70 | } | 64 | } |
71 | } | 65 | } |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 95678bf70..ea13c1196 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -169,11 +169,7 @@ impl<N: AstNode> Hash for ItemLoc<N> { | |||
169 | 169 | ||
170 | impl<N: AstNode> Clone for ItemLoc<N> { | 170 | impl<N: AstNode> Clone for ItemLoc<N> { |
171 | fn clone(&self) -> ItemLoc<N> { | 171 | fn clone(&self) -> ItemLoc<N> { |
172 | ItemLoc { | 172 | ItemLoc { module: self.module, raw: self.raw, _ty: PhantomData } |
173 | module: self.module, | ||
174 | raw: self.raw, | ||
175 | _ty: PhantomData, | ||
176 | } | ||
177 | } | 173 | } |
178 | } | 174 | } |
179 | 175 | ||
@@ -186,11 +182,7 @@ pub(crate) struct LocationCtx<DB> { | |||
186 | 182 | ||
187 | impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { | 183 | impl<'a, DB: PersistentHirDatabase> LocationCtx<&'a DB> { |
188 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { | 184 | pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> { |
189 | LocationCtx { | 185 | LocationCtx { db, module, file_id } |
190 | db, | ||
191 | module, | ||
192 | file_id, | ||
193 | } | ||
194 | } | 186 | } |
195 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF | 187 | pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF |
196 | where | 188 | where |
@@ -205,15 +197,9 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
205 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; | 197 | fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; |
206 | fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { | 198 | fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { |
207 | let items = ctx.db.file_items(ctx.file_id); | 199 | let items = ctx.db.file_items(ctx.file_id); |
208 | let raw = SourceItemId { | 200 | let raw = |
209 | file_id: ctx.file_id, | 201 | SourceItemId { file_id: ctx.file_id, item_id: items.id_of(ctx.file_id, ast.syntax()) }; |
210 | item_id: items.id_of(ctx.file_id, ast.syntax()), | 202 | let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData }; |
211 | }; | ||
212 | let loc = ItemLoc { | ||
213 | module: ctx.module, | ||
214 | raw, | ||
215 | _ty: PhantomData, | ||
216 | }; | ||
217 | 203 | ||
218 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | 204 | Self::interner(ctx.db.as_ref()).loc2id(&loc) |
219 | } | 205 | } |
@@ -221,9 +207,8 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
221 | let int = Self::interner(db.as_ref()); | 207 | let int = Self::interner(db.as_ref()); |
222 | let loc = int.id2loc(self); | 208 | let loc = int.id2loc(self); |
223 | let syntax = db.file_item(loc.raw); | 209 | let syntax = db.file_item(loc.raw); |
224 | let ast = N::cast(&syntax) | 210 | let ast = |
225 | .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)) | 211 | N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); |
226 | .to_owned(); | ||
227 | (loc.raw.file_id, ast) | 212 | (loc.raw.file_id, ast) |
228 | } | 213 | } |
229 | fn module(self, db: &impl HirDatabase) -> Module { | 214 | fn module(self, db: &impl HirDatabase) -> Module { |
@@ -317,10 +302,7 @@ pub struct SourceFileItems { | |||
317 | 302 | ||
318 | impl SourceFileItems { | 303 | impl SourceFileItems { |
319 | pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems { | 304 | pub(crate) fn new(file_id: HirFileId, source_file: &SourceFile) -> SourceFileItems { |
320 | let mut res = SourceFileItems { | 305 | let mut res = SourceFileItems { file_id, arena: Arena::default() }; |
321 | file_id, | ||
322 | arena: Arena::default(), | ||
323 | }; | ||
324 | res.init(source_file); | 306 | res.init(source_file); |
325 | res | 307 | res |
326 | } | 308 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 094dbedb3..b2fbee8d7 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -50,17 +50,11 @@ impl ImplBlock { | |||
50 | item: ImplItem, | 50 | item: ImplItem, |
51 | ) -> Option<ImplBlock> { | 51 | ) -> Option<ImplBlock> { |
52 | let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; | 52 | let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; |
53 | Some(ImplBlock { | 53 | Some(ImplBlock { module_impl_blocks, impl_id }) |
54 | module_impl_blocks, | ||
55 | impl_id, | ||
56 | }) | ||
57 | } | 54 | } |
58 | 55 | ||
59 | pub(crate) fn from_id(module_impl_blocks: Arc<ModuleImplBlocks>, impl_id: ImplId) -> ImplBlock { | 56 | pub(crate) fn from_id(module_impl_blocks: Arc<ModuleImplBlocks>, impl_id: ImplId) -> ImplBlock { |
60 | ImplBlock { | 57 | ImplBlock { module_impl_blocks, impl_id } |
61 | module_impl_blocks, | ||
62 | impl_id, | ||
63 | } | ||
64 | } | 58 | } |
65 | 59 | ||
66 | pub fn id(&self) -> ImplId { | 60 | pub fn id(&self) -> ImplId { |
@@ -144,11 +138,7 @@ impl ImplData { | |||
144 | } else { | 138 | } else { |
145 | Vec::new() | 139 | Vec::new() |
146 | }; | 140 | }; |
147 | ImplData { | 141 | ImplData { target_trait, target_type, items } |
148 | target_trait, | ||
149 | target_type, | ||
150 | items, | ||
151 | } | ||
152 | } | 142 | } |
153 | 143 | ||
154 | pub fn target_trait(&self) -> Option<&TypeRef> { | 144 | pub fn target_trait(&self) -> Option<&TypeRef> { |
@@ -212,10 +202,9 @@ impl ModuleImplBlocks { | |||
212 | let file_id: HirFileId = file_id.into(); | 202 | let file_id: HirFileId = file_id.into(); |
213 | let node = match &module_source { | 203 | let node = match &module_source { |
214 | ModuleSource::SourceFile(node) => node.syntax(), | 204 | ModuleSource::SourceFile(node) => node.syntax(), |
215 | ModuleSource::Module(node) => node | 205 | ModuleSource::Module(node) => { |
216 | .item_list() | 206 | node.item_list().expect("inline module should have item list").syntax() |
217 | .expect("inline module should have item list") | 207 | } |
218 | .syntax(), | ||
219 | }; | 208 | }; |
220 | 209 | ||
221 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 210 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index cb8a9312e..95925159f 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs | |||
@@ -48,9 +48,7 @@ impl MacroDef { | |||
48 | 48 | ||
49 | let input = { | 49 | let input = { |
50 | let arg = macro_call.token_tree()?.syntax(); | 50 | let arg = macro_call.token_tree()?.syntax(); |
51 | MacroInput { | 51 | MacroInput { text: arg.text().to_string() } |
52 | text: arg.text().to_string(), | ||
53 | } | ||
54 | }; | 52 | }; |
55 | Some((def, input)) | 53 | Some((def, input)) |
56 | } | 54 | } |
@@ -68,20 +66,14 @@ impl MacroDef { | |||
68 | let ptr = SyntaxNodePtr::new(array_expr.syntax()); | 66 | let ptr = SyntaxNodePtr::new(array_expr.syntax()); |
69 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | 67 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); |
70 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; | 68 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; |
71 | let res = MacroExpansion { | 69 | let res = MacroExpansion { text, ranges_map, ptr }; |
72 | text, | ||
73 | ranges_map, | ||
74 | ptr, | ||
75 | }; | ||
76 | Some(res) | 70 | Some(res) |
77 | } | 71 | } |
78 | fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { | 72 | fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { |
79 | let anchor = "trait "; | 73 | let anchor = "trait "; |
80 | let pos = input.text.find(anchor)? + anchor.len(); | 74 | let pos = input.text.find(anchor)? + anchor.len(); |
81 | let trait_name = input.text[pos..] | 75 | let trait_name = |
82 | .chars() | 76 | input.text[pos..].chars().take_while(|c| c.is_alphabetic()).collect::<String>(); |
83 | .take_while(|c| c.is_alphabetic()) | ||
84 | .collect::<String>(); | ||
85 | if trait_name.is_empty() { | 77 | if trait_name.is_empty() { |
86 | return None; | 78 | return None; |
87 | } | 79 | } |
@@ -92,11 +84,7 @@ impl MacroDef { | |||
92 | let name = trait_def.name()?; | 84 | let name = trait_def.name()?; |
93 | let ptr = SyntaxNodePtr::new(trait_def.syntax()); | 85 | let ptr = SyntaxNodePtr::new(trait_def.syntax()); |
94 | let ranges_map = vec![(src_range, name.syntax().range())]; | 86 | let ranges_map = vec![(src_range, name.syntax().range())]; |
95 | let res = MacroExpansion { | 87 | let res = MacroExpansion { text, ranges_map, ptr }; |
96 | text, | ||
97 | ranges_map, | ||
98 | ptr, | ||
99 | }; | ||
100 | Some(res) | 88 | Some(res) |
101 | } | 89 | } |
102 | } | 90 | } |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 87095fb21..950f89948 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -64,10 +64,7 @@ impl MockDatabase { | |||
64 | let mut source_root = SourceRoot::default(); | 64 | let mut source_root = SourceRoot::default(); |
65 | for entry in parse_fixture(fixture) { | 65 | for entry in parse_fixture(fixture) { |
66 | if entry.text.contains(CURSOR_MARKER) { | 66 | if entry.text.contains(CURSOR_MARKER) { |
67 | assert!( | 67 | assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); |
68 | position.is_none(), | ||
69 | "only one marker (<|>) per fixture is allowed" | ||
70 | ); | ||
71 | position = Some(self.add_file_with_position( | 68 | position = Some(self.add_file_with_position( |
72 | source_root_id, | 69 | source_root_id, |
73 | &mut source_root, | 70 | &mut source_root, |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index a1aa3d8ce..1f19ee191 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -153,10 +153,8 @@ impl ModuleTree { | |||
153 | file_id: HirFileId, | 153 | file_id: HirFileId, |
154 | decl_id: Option<SourceFileItemId>, | 154 | decl_id: Option<SourceFileItemId>, |
155 | ) -> Option<ModuleId> { | 155 | ) -> Option<ModuleId> { |
156 | let (res, _) = self | 156 | let (res, _) = |
157 | .mods | 157 | self.mods.iter().find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?; |
158 | .iter() | ||
159 | .find(|(_, m)| (m.file_id, m.decl_id) == (file_id, decl_id))?; | ||
160 | Some(res) | 158 | Some(res) |
161 | } | 159 | } |
162 | 160 | ||
@@ -178,18 +176,10 @@ impl ModuleTree { | |||
178 | decl_id: Option<SourceFileItemId>, | 176 | decl_id: Option<SourceFileItemId>, |
179 | ) -> ModuleId { | 177 | ) -> ModuleId { |
180 | let is_root = parent.is_none(); | 178 | let is_root = parent.is_none(); |
181 | let id = self.alloc_mod(ModuleData { | 179 | let id = self.alloc_mod(ModuleData { file_id, decl_id, parent, children: Vec::new() }); |
182 | file_id, | ||
183 | decl_id, | ||
184 | parent, | ||
185 | children: Vec::new(), | ||
186 | }); | ||
187 | for sub in db.submodules(file_id, decl_id).iter() { | 180 | for sub in db.submodules(file_id, decl_id).iter() { |
188 | let link = self.alloc_link(LinkData { | 181 | let link = self.alloc_link(LinkData { |
189 | source: SourceItemId { | 182 | source: SourceItemId { file_id, item_id: sub.decl_id }, |
190 | file_id, | ||
191 | item_id: sub.decl_id, | ||
192 | }, | ||
193 | name: sub.name.clone(), | 183 | name: sub.name.clone(), |
194 | owner: id, | 184 | owner: id, |
195 | points_to: Vec::new(), | 185 | points_to: Vec::new(), |
@@ -244,9 +234,7 @@ impl ModuleId { | |||
244 | Some(tree.links[link].owner) | 234 | Some(tree.links[link].owner) |
245 | } | 235 | } |
246 | pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId { | 236 | pub(crate) fn crate_root(self, tree: &ModuleTree) -> ModuleId { |
247 | generate(Some(self), move |it| it.parent(tree)) | 237 | generate(Some(self), move |it| it.parent(tree)).last().unwrap() |
248 | .last() | ||
249 | .unwrap() | ||
250 | } | 238 | } |
251 | pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> { | 239 | pub(crate) fn child(self, tree: &ModuleTree, name: &Name) -> Option<ModuleId> { |
252 | let link = tree.mods[self] | 240 | let link = tree.mods[self] |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 681aa9a67..b7382d9c3 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -83,40 +83,25 @@ pub struct PerNs<T> { | |||
83 | 83 | ||
84 | impl<T> Default for PerNs<T> { | 84 | impl<T> Default for PerNs<T> { |
85 | fn default() -> Self { | 85 | fn default() -> Self { |
86 | PerNs { | 86 | PerNs { types: None, values: None } |
87 | types: None, | ||
88 | values: None, | ||
89 | } | ||
90 | } | 87 | } |
91 | } | 88 | } |
92 | 89 | ||
93 | impl<T> PerNs<T> { | 90 | impl<T> PerNs<T> { |
94 | pub fn none() -> PerNs<T> { | 91 | pub fn none() -> PerNs<T> { |
95 | PerNs { | 92 | PerNs { types: None, values: None } |
96 | types: None, | ||
97 | values: None, | ||
98 | } | ||
99 | } | 93 | } |
100 | 94 | ||
101 | pub fn values(t: T) -> PerNs<T> { | 95 | pub fn values(t: T) -> PerNs<T> { |
102 | PerNs { | 96 | PerNs { types: None, values: Some(t) } |
103 | types: None, | ||
104 | values: Some(t), | ||
105 | } | ||
106 | } | 97 | } |
107 | 98 | ||
108 | pub fn types(t: T) -> PerNs<T> { | 99 | pub fn types(t: T) -> PerNs<T> { |
109 | PerNs { | 100 | PerNs { types: Some(t), values: None } |
110 | types: Some(t), | ||
111 | values: None, | ||
112 | } | ||
113 | } | 101 | } |
114 | 102 | ||
115 | pub fn both(types: T, values: T) -> PerNs<T> { | 103 | pub fn both(types: T, values: T) -> PerNs<T> { |
116 | PerNs { | 104 | PerNs { types: Some(types), values: Some(values) } |
117 | types: Some(types), | ||
118 | values: Some(values), | ||
119 | } | ||
120 | } | 105 | } |
121 | 106 | ||
122 | pub fn is_none(&self) -> bool { | 107 | pub fn is_none(&self) -> bool { |
@@ -147,31 +132,19 @@ impl<T> PerNs<T> { | |||
147 | } | 132 | } |
148 | 133 | ||
149 | pub fn as_ref(&self) -> PerNs<&T> { | 134 | pub fn as_ref(&self) -> PerNs<&T> { |
150 | PerNs { | 135 | PerNs { types: self.types.as_ref(), values: self.values.as_ref() } |
151 | types: self.types.as_ref(), | ||
152 | values: self.values.as_ref(), | ||
153 | } | ||
154 | } | 136 | } |
155 | 137 | ||
156 | pub fn combine(self, other: PerNs<T>) -> PerNs<T> { | 138 | pub fn combine(self, other: PerNs<T>) -> PerNs<T> { |
157 | PerNs { | 139 | PerNs { types: self.types.or(other.types), values: self.values.or(other.values) } |
158 | types: self.types.or(other.types), | ||
159 | values: self.values.or(other.values), | ||
160 | } | ||
161 | } | 140 | } |
162 | 141 | ||
163 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { | 142 | pub fn and_then<U>(self, f: impl Fn(T) -> Option<U>) -> PerNs<U> { |
164 | PerNs { | 143 | PerNs { types: self.types.and_then(&f), values: self.values.and_then(&f) } |
165 | types: self.types.and_then(&f), | ||
166 | values: self.values.and_then(&f), | ||
167 | } | ||
168 | } | 144 | } |
169 | 145 | ||
170 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { | 146 | pub fn map<U>(self, f: impl Fn(T) -> U) -> PerNs<U> { |
171 | PerNs { | 147 | PerNs { types: self.types.map(&f), values: self.values.map(&f) } |
172 | types: self.types.map(&f), | ||
173 | values: self.values.map(&f), | ||
174 | } | ||
175 | } | 148 | } |
176 | } | 149 | } |
177 | 150 | ||
@@ -233,9 +206,7 @@ where | |||
233 | for dep in self.krate.dependencies(self.db) { | 206 | for dep in self.krate.dependencies(self.db) { |
234 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); | 207 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate); |
235 | if let Some(module) = dep.krate.root_module(self.db) { | 208 | if let Some(module) = dep.krate.root_module(self.db) { |
236 | self.result | 209 | self.result.extern_prelude.insert(dep.name.clone(), module.into()); |
237 | .extern_prelude | ||
238 | .insert(dep.name.clone(), module.into()); | ||
239 | } | 210 | } |
240 | } | 211 | } |
241 | } | 212 | } |
@@ -245,17 +216,11 @@ where | |||
245 | for (import_id, import_data) in input.imports.iter() { | 216 | for (import_id, import_data) in input.imports.iter() { |
246 | if let Some(last_segment) = import_data.path.segments.iter().last() { | 217 | if let Some(last_segment) = import_data.path.segments.iter().last() { |
247 | if !import_data.is_glob { | 218 | if !import_data.is_glob { |
248 | let name = import_data | 219 | let name = |
249 | .alias | 220 | import_data.alias.clone().unwrap_or_else(|| last_segment.name.clone()); |
250 | .clone() | 221 | module_items |
251 | .unwrap_or_else(|| last_segment.name.clone()); | 222 | .items |
252 | module_items.items.insert( | 223 | .insert(name, Resolution { def: PerNs::none(), import: Some(import_id) }); |
253 | name, | ||
254 | Resolution { | ||
255 | def: PerNs::none(), | ||
256 | import: Some(import_id), | ||
257 | }, | ||
258 | ); | ||
259 | } | 224 | } |
260 | } | 225 | } |
261 | } | 226 | } |
@@ -267,10 +232,7 @@ where | |||
267 | 232 | ||
268 | // Populate modules | 233 | // Populate modules |
269 | for (name, module_id) in module_id.children(&self.module_tree) { | 234 | for (name, module_id) in module_id.children(&self.module_tree) { |
270 | let module = Module { | 235 | let module = Module { module_id, krate: self.krate }; |
271 | module_id, | ||
272 | krate: self.krate, | ||
273 | }; | ||
274 | self.add_module_item(&mut module_items, name, PerNs::types(module.into())); | 236 | self.add_module_item(&mut module_items, name, PerNs::types(module.into())); |
275 | } | 237 | } |
276 | 238 | ||
@@ -305,20 +267,13 @@ where | |||
305 | if import.is_glob { | 267 | if import.is_glob { |
306 | return ReachedFixedPoint::Yes; | 268 | return ReachedFixedPoint::Yes; |
307 | }; | 269 | }; |
308 | let original_module = Module { | 270 | let original_module = Module { krate: self.krate, module_id }; |
309 | krate: self.krate, | ||
310 | module_id, | ||
311 | }; | ||
312 | let (def, reached_fixedpoint) = | 271 | let (def, reached_fixedpoint) = |
313 | self.result | 272 | self.result.resolve_path_fp(self.db, original_module, &import.path); |
314 | .resolve_path_fp(self.db, original_module, &import.path); | ||
315 | 273 | ||
316 | if reached_fixedpoint == ReachedFixedPoint::Yes { | 274 | if reached_fixedpoint == ReachedFixedPoint::Yes { |
317 | let last_segment = import.path.segments.last().unwrap(); | 275 | let last_segment = import.path.segments.last().unwrap(); |
318 | let name = import | 276 | let name = import.alias.clone().unwrap_or_else(|| last_segment.name.clone()); |
319 | .alias | ||
320 | .clone() | ||
321 | .unwrap_or_else(|| last_segment.name.clone()); | ||
322 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); | 277 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); |
323 | 278 | ||
324 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 | 279 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 |
@@ -330,10 +285,7 @@ where | |||
330 | } | 285 | } |
331 | } | 286 | } |
332 | self.update(module_id, |items| { | 287 | self.update(module_id, |items| { |
333 | let res = Resolution { | 288 | let res = Resolution { def, import: Some(import_id) }; |
334 | def, | ||
335 | import: Some(import_id), | ||
336 | }; | ||
337 | items.items.insert(name, res); | 289 | items.items.insert(name, res); |
338 | }); | 290 | }); |
339 | } | 291 | } |
@@ -358,12 +310,7 @@ impl ItemMap { | |||
358 | let module_tree = db.module_tree(krate); | 310 | let module_tree = db.module_tree(krate); |
359 | let input = module_tree | 311 | let input = module_tree |
360 | .modules() | 312 | .modules() |
361 | .map(|module_id| { | 313 | .map(|module_id| (module_id, db.lower_module_module(Module { krate, module_id }))) |
362 | ( | ||
363 | module_id, | ||
364 | db.lower_module_module(Module { krate, module_id }), | ||
365 | ) | ||
366 | }) | ||
367 | .collect::<FxHashMap<_, _>>(); | 314 | .collect::<FxHashMap<_, _>>(); |
368 | 315 | ||
369 | let resolver = Resolver::new(db, &input, krate); | 316 | let resolver = Resolver::new(db, &input, krate); |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 7e6e48ae0..7e9a3de2b 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -82,13 +82,9 @@ impl LoweredModule { | |||
82 | let mut source_map = ImportSourceMap::default(); | 82 | let mut source_map = ImportSourceMap::default(); |
83 | let mut res = LoweredModule::default(); | 83 | let mut res = LoweredModule::default(); |
84 | match source { | 84 | match source { |
85 | ModuleSource::SourceFile(it) => res.fill( | 85 | ModuleSource::SourceFile(it) => { |
86 | &mut source_map, | 86 | res.fill(&mut source_map, db, module, file_id, &mut it.items_with_macros()) |
87 | db, | 87 | } |
88 | module, | ||
89 | file_id, | ||
90 | &mut it.items_with_macros(), | ||
91 | ), | ||
92 | ModuleSource::Module(it) => { | 88 | ModuleSource::Module(it) => { |
93 | if let Some(item_list) = it.item_list() { | 89 | if let Some(item_list) = it.item_list() { |
94 | res.fill( | 90 | res.fill( |
@@ -121,10 +117,8 @@ impl LoweredModule { | |||
121 | } | 117 | } |
122 | ast::ItemOrMacro::Macro(macro_call) => { | 118 | ast::ItemOrMacro::Macro(macro_call) => { |
123 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); | 119 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); |
124 | let loc = MacroCallLoc { | 120 | let loc = |
125 | module, | 121 | MacroCallLoc { module, source_item_id: SourceItemId { file_id, item_id } }; |
126 | source_item_id: SourceItemId { file_id, item_id }, | ||
127 | }; | ||
128 | let id = loc.id(db); | 122 | let id = loc.id(db); |
129 | let file_id = HirFileId::from(id); | 123 | let file_id = HirFileId::from(id); |
130 | //FIXME: expand recursively | 124 | //FIXME: expand recursively |
@@ -163,22 +157,19 @@ impl LoweredModule { | |||
163 | ast::ModuleItemKind::FnDef(it) => { | 157 | ast::ModuleItemKind::FnDef(it) => { |
164 | if let Some(name) = it.name() { | 158 | if let Some(name) = it.name() { |
165 | let func = Function { id: ctx.to_def(it) }; | 159 | let func = Function { id: ctx.to_def(it) }; |
166 | self.declarations | 160 | self.declarations.insert(name.as_name(), PerNs::values(func.into())); |
167 | .insert(name.as_name(), PerNs::values(func.into())); | ||
168 | } | 161 | } |
169 | } | 162 | } |
170 | ast::ModuleItemKind::TraitDef(it) => { | 163 | ast::ModuleItemKind::TraitDef(it) => { |
171 | if let Some(name) = it.name() { | 164 | if let Some(name) = it.name() { |
172 | let t = Trait { id: ctx.to_def(it) }; | 165 | let t = Trait { id: ctx.to_def(it) }; |
173 | self.declarations | 166 | self.declarations.insert(name.as_name(), PerNs::types(t.into())); |
174 | .insert(name.as_name(), PerNs::types(t.into())); | ||
175 | } | 167 | } |
176 | } | 168 | } |
177 | ast::ModuleItemKind::TypeDef(it) => { | 169 | ast::ModuleItemKind::TypeDef(it) => { |
178 | if let Some(name) = it.name() { | 170 | if let Some(name) = it.name() { |
179 | let t = Type { id: ctx.to_def(it) }; | 171 | let t = Type { id: ctx.to_def(it) }; |
180 | self.declarations | 172 | self.declarations.insert(name.as_name(), PerNs::types(t.into())); |
181 | .insert(name.as_name(), PerNs::types(t.into())); | ||
182 | } | 173 | } |
183 | } | 174 | } |
184 | ast::ModuleItemKind::ImplBlock(_) => { | 175 | ast::ModuleItemKind::ImplBlock(_) => { |
@@ -207,15 +198,13 @@ impl LoweredModule { | |||
207 | ast::ModuleItemKind::ConstDef(it) => { | 198 | ast::ModuleItemKind::ConstDef(it) => { |
208 | if let Some(name) = it.name() { | 199 | if let Some(name) = it.name() { |
209 | let c = Const { id: ctx.to_def(it) }; | 200 | let c = Const { id: ctx.to_def(it) }; |
210 | self.declarations | 201 | self.declarations.insert(name.as_name(), PerNs::values(c.into())); |
211 | .insert(name.as_name(), PerNs::values(c.into())); | ||
212 | } | 202 | } |
213 | } | 203 | } |
214 | ast::ModuleItemKind::StaticDef(it) => { | 204 | ast::ModuleItemKind::StaticDef(it) => { |
215 | if let Some(name) = it.name() { | 205 | if let Some(name) = it.name() { |
216 | let s = Static { id: ctx.to_def(it) }; | 206 | let s = Static { id: ctx.to_def(it) }; |
217 | self.declarations | 207 | self.declarations.insert(name.as_name(), PerNs::values(s.into())); |
218 | .insert(name.as_name(), PerNs::values(s.into())); | ||
219 | } | 208 | } |
220 | } | 209 | } |
221 | ast::ModuleItemKind::Module(_) => { | 210 | ast::ModuleItemKind::Module(_) => { |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 0654dbaa1..3dfad6bf2 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -42,19 +42,11 @@ fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | |||
42 | .collect::<Vec<_>>(); | 42 | .collect::<Vec<_>>(); |
43 | lines.sort(); | 43 | lines.sort(); |
44 | let actual = lines.join("\n"); | 44 | let actual = lines.join("\n"); |
45 | let expected = expected | 45 | let expected = expected.trim().lines().map(|it| it.trim()).collect::<Vec<_>>().join("\n"); |
46 | .trim() | ||
47 | .lines() | ||
48 | .map(|it| it.trim()) | ||
49 | .collect::<Vec<_>>() | ||
50 | .join("\n"); | ||
51 | assert_eq_text!(&expected, &actual); | 46 | assert_eq_text!(&expected, &actual); |
52 | 47 | ||
53 | fn dump_resolution(resolution: &Resolution) -> &'static str { | 48 | fn dump_resolution(resolution: &Resolution) -> &'static str { |
54 | match ( | 49 | match (resolution.def.types.is_some(), resolution.def.values.is_some()) { |
55 | resolution.def.types.is_some(), | ||
56 | resolution.def.values.is_some(), | ||
57 | ) { | ||
58 | (true, true) => "t v", | 50 | (true, true) => "t v", |
59 | (true, false) => "t", | 51 | (true, false) => "t", |
60 | (false, true) => "v", | 52 | (false, true) => "v", |
@@ -314,9 +306,7 @@ fn item_map_across_crates() { | |||
314 | let mut crate_graph = CrateGraph::default(); | 306 | let mut crate_graph = CrateGraph::default(); |
315 | let main_crate = crate_graph.add_crate_root(main_id); | 307 | let main_crate = crate_graph.add_crate_root(main_id); |
316 | let lib_crate = crate_graph.add_crate_root(lib_id); | 308 | let lib_crate = crate_graph.add_crate_root(lib_id); |
317 | crate_graph | 309 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
318 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
319 | .unwrap(); | ||
320 | 310 | ||
321 | db.set_crate_graph(Arc::new(crate_graph)); | 311 | db.set_crate_graph(Arc::new(crate_graph)); |
322 | 312 | ||
@@ -357,9 +347,7 @@ fn extern_crate_rename() { | |||
357 | let mut crate_graph = CrateGraph::default(); | 347 | let mut crate_graph = CrateGraph::default(); |
358 | let main_crate = crate_graph.add_crate_root(main_id); | 348 | let main_crate = crate_graph.add_crate_root(main_id); |
359 | let lib_crate = crate_graph.add_crate_root(lib_id); | 349 | let lib_crate = crate_graph.add_crate_root(lib_id); |
360 | crate_graph | 350 | crate_graph.add_dep(main_crate, "alloc".into(), lib_crate).unwrap(); |
361 | .add_dep(main_crate, "alloc".into(), lib_crate) | ||
362 | .unwrap(); | ||
363 | 351 | ||
364 | db.set_crate_graph(Arc::new(crate_graph)); | 352 | db.set_crate_graph(Arc::new(crate_graph)); |
365 | 353 | ||
@@ -406,9 +394,7 @@ fn import_across_source_roots() { | |||
406 | let mut crate_graph = CrateGraph::default(); | 394 | let mut crate_graph = CrateGraph::default(); |
407 | let main_crate = crate_graph.add_crate_root(main_id); | 395 | let main_crate = crate_graph.add_crate_root(main_id); |
408 | let lib_crate = crate_graph.add_crate_root(lib_id); | 396 | let lib_crate = crate_graph.add_crate_root(lib_id); |
409 | crate_graph | 397 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
410 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
411 | .unwrap(); | ||
412 | 398 | ||
413 | db.set_crate_graph(Arc::new(crate_graph)); | 399 | db.set_crate_graph(Arc::new(crate_graph)); |
414 | 400 | ||
@@ -447,9 +433,7 @@ fn reexport_across_crates() { | |||
447 | let mut crate_graph = CrateGraph::default(); | 433 | let mut crate_graph = CrateGraph::default(); |
448 | let main_crate = crate_graph.add_crate_root(main_id); | 434 | let main_crate = crate_graph.add_crate_root(main_id); |
449 | let lib_crate = crate_graph.add_crate_root(lib_id); | 435 | let lib_crate = crate_graph.add_crate_root(lib_id); |
450 | crate_graph | 436 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate).unwrap(); |
451 | .add_dep(main_crate, "test_crate".into(), lib_crate) | ||
452 | .unwrap(); | ||
453 | 437 | ||
454 | db.set_crate_graph(Arc::new(crate_graph)); | 438 | db.set_crate_graph(Arc::new(crate_graph)); |
455 | 439 | ||
@@ -482,11 +466,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | |||
482 | let events = db.log_executed(|| { | 466 | let events = db.log_executed(|| { |
483 | db.item_map(krate); | 467 | db.item_map(krate); |
484 | }); | 468 | }); |
485 | assert!( | 469 | assert!(!format!("{:?}", events).contains("item_map"), "{:#?}", events) |
486 | !format!("{:?}", events).contains("item_map"), | ||
487 | "{:#?}", | ||
488 | events | ||
489 | ) | ||
490 | } | 470 | } |
491 | } | 471 | } |
492 | 472 | ||
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index cb0a04500..6a24c8aa7 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -66,14 +66,9 @@ impl Path { | |||
66 | 66 | ||
67 | match segment.kind()? { | 67 | match segment.kind()? { |
68 | ast::PathSegmentKind::Name(name) => { | 68 | ast::PathSegmentKind::Name(name) => { |
69 | let args = segment | 69 | let args = |
70 | .type_arg_list() | 70 | segment.type_arg_list().and_then(GenericArgs::from_ast).map(Arc::new); |
71 | .and_then(GenericArgs::from_ast) | 71 | let segment = PathSegment { name: name.as_name(), args_and_bindings: args }; |
72 | .map(Arc::new); | ||
73 | let segment = PathSegment { | ||
74 | name: name.as_name(), | ||
75 | args_and_bindings: args, | ||
76 | }; | ||
77 | segments.push(segment); | 72 | segments.push(segment); |
78 | } | 73 | } |
79 | ast::PathSegmentKind::CrateKw => { | 74 | ast::PathSegmentKind::CrateKw => { |
@@ -153,10 +148,7 @@ impl From<Name> for Path { | |||
153 | fn from(name: Name) -> Path { | 148 | fn from(name: Name) -> Path { |
154 | Path { | 149 | Path { |
155 | kind: PathKind::Plain, | 150 | kind: PathKind::Plain, |
156 | segments: vec![PathSegment { | 151 | segments: vec![PathSegment { name, args_and_bindings: None }], |
157 | name, | ||
158 | args_and_bindings: None, | ||
159 | }], | ||
160 | } | 152 | } |
161 | } | 153 | } |
162 | } | 154 | } |
@@ -209,18 +201,13 @@ fn expand_use_tree<'a>( | |||
209 | } | 201 | } |
210 | 202 | ||
211 | fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { | 203 | fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { |
212 | let prefix = if let Some(qual) = path.qualifier() { | 204 | let prefix = |
213 | Some(convert_path(prefix, qual)?) | 205 | if let Some(qual) = path.qualifier() { Some(convert_path(prefix, qual)?) } else { prefix }; |
214 | } else { | ||
215 | prefix | ||
216 | }; | ||
217 | let segment = path.segment()?; | 206 | let segment = path.segment()?; |
218 | let res = match segment.kind()? { | 207 | let res = match segment.kind()? { |
219 | ast::PathSegmentKind::Name(name) => { | 208 | ast::PathSegmentKind::Name(name) => { |
220 | let mut res = prefix.unwrap_or_else(|| Path { | 209 | let mut res = prefix |
221 | kind: PathKind::Plain, | 210 | .unwrap_or_else(|| Path { kind: PathKind::Plain, segments: Vec::with_capacity(1) }); |
222 | segments: Vec::with_capacity(1), | ||
223 | }); | ||
224 | res.segments.push(PathSegment { | 211 | res.segments.push(PathSegment { |
225 | name: name.as_name(), | 212 | name: name.as_name(), |
226 | args_and_bindings: None, // no type args in use | 213 | args_and_bindings: None, // no type args in use |
@@ -231,28 +218,19 @@ fn convert_path(prefix: Option<Path>, path: &ast::Path) -> Option<Path> { | |||
231 | if prefix.is_some() { | 218 | if prefix.is_some() { |
232 | return None; | 219 | return None; |
233 | } | 220 | } |
234 | Path { | 221 | Path { kind: PathKind::Crate, segments: Vec::new() } |
235 | kind: PathKind::Crate, | ||
236 | segments: Vec::new(), | ||
237 | } | ||
238 | } | 222 | } |
239 | ast::PathSegmentKind::SelfKw => { | 223 | ast::PathSegmentKind::SelfKw => { |
240 | if prefix.is_some() { | 224 | if prefix.is_some() { |
241 | return None; | 225 | return None; |
242 | } | 226 | } |
243 | Path { | 227 | Path { kind: PathKind::Self_, segments: Vec::new() } |
244 | kind: PathKind::Self_, | ||
245 | segments: Vec::new(), | ||
246 | } | ||
247 | } | 228 | } |
248 | ast::PathSegmentKind::SuperKw => { | 229 | ast::PathSegmentKind::SuperKw => { |
249 | if prefix.is_some() { | 230 | if prefix.is_some() { |
250 | return None; | 231 | return None; |
251 | } | 232 | } |
252 | Path { | 233 | Path { kind: PathKind::Super, segments: Vec::new() } |
253 | kind: PathKind::Super, | ||
254 | segments: Vec::new(), | ||
255 | } | ||
256 | } | 234 | } |
257 | }; | 235 | }; |
258 | Some(res) | 236 | Some(res) |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index b4d8da1e6..03113e7cc 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -23,7 +23,5 @@ pub(super) fn file_item( | |||
23 | source_item_id: SourceItemId, | 23 | source_item_id: SourceItemId, |
24 | ) -> TreeArc<SyntaxNode> { | 24 | ) -> TreeArc<SyntaxNode> { |
25 | let source_file = db.hir_parse(source_item_id.file_id); | 25 | let source_file = db.hir_parse(source_item_id.file_id); |
26 | db.file_items(source_item_id.file_id)[source_item_id.item_id] | 26 | db.file_items(source_item_id.file_id)[source_item_id.item_id].to_node(&source_file).to_owned() |
27 | .to_node(&source_file) | ||
28 | .to_owned() | ||
29 | } | 27 | } |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 0f60d4742..3d7ec5683 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -138,10 +138,7 @@ impl Resolver { | |||
138 | expr_scopes: Arc<ExprScopes>, | 138 | expr_scopes: Arc<ExprScopes>, |
139 | scope_id: ScopeId, | 139 | scope_id: ScopeId, |
140 | ) -> Resolver { | 140 | ) -> Resolver { |
141 | self.push_scope(Scope::ExprScope(ExprScope { | 141 | self.push_scope(Scope::ExprScope(ExprScope { expr_scopes, scope_id })) |
142 | expr_scopes, | ||
143 | scope_id, | ||
144 | })) | ||
145 | } | 142 | } |
146 | } | 143 | } |
147 | 144 | ||
@@ -170,11 +167,8 @@ impl Scope { | |||
170 | } | 167 | } |
171 | } | 168 | } |
172 | Scope::ExprScope(e) => { | 169 | Scope::ExprScope(e) => { |
173 | let entry = e | 170 | let entry = |
174 | .expr_scopes | 171 | e.expr_scopes.entries(e.scope_id).iter().find(|entry| entry.name() == name); |
175 | .entries(e.scope_id) | ||
176 | .iter() | ||
177 | .find(|entry| entry.name() == name); | ||
178 | match entry { | 172 | match entry { |
179 | Some(e) => PerNs::values(Resolution::LocalBinding(e.pat())), | 173 | Some(e) => PerNs::values(Resolution::LocalBinding(e.pat())), |
180 | None => PerNs::none(), | 174 | None => PerNs::none(), |
@@ -193,35 +187,24 @@ impl Scope { | |||
193 | // def: m.module.into(), | 187 | // def: m.module.into(), |
194 | // }), | 188 | // }), |
195 | // ); | 189 | // ); |
196 | m.item_map[m.module.module_id] | 190 | m.item_map[m.module.module_id].entries().for_each(|(name, res)| { |
197 | .entries() | 191 | f(name.clone(), res.def.map(Resolution::Def)); |
198 | .for_each(|(name, res)| { | 192 | }); |
199 | f(name.clone(), res.def.map(Resolution::Def)); | ||
200 | }); | ||
201 | m.item_map.extern_prelude.iter().for_each(|(name, def)| { | 193 | m.item_map.extern_prelude.iter().for_each(|(name, def)| { |
202 | f(name.clone(), PerNs::types(Resolution::Def(*def))); | 194 | f(name.clone(), PerNs::types(Resolution::Def(*def))); |
203 | }); | 195 | }); |
204 | } | 196 | } |
205 | Scope::GenericParams(gp) => { | 197 | Scope::GenericParams(gp) => { |
206 | for param in &gp.params { | 198 | for param in &gp.params { |
207 | f( | 199 | f(param.name.clone(), PerNs::types(Resolution::GenericParam(param.idx))) |
208 | param.name.clone(), | ||
209 | PerNs::types(Resolution::GenericParam(param.idx)), | ||
210 | ) | ||
211 | } | 200 | } |
212 | } | 201 | } |
213 | Scope::ImplBlockScope(i) => { | 202 | Scope::ImplBlockScope(i) => { |
214 | f( | 203 | f(Name::self_type(), PerNs::types(Resolution::SelfType(i.clone()))); |
215 | Name::self_type(), | ||
216 | PerNs::types(Resolution::SelfType(i.clone())), | ||
217 | ); | ||
218 | } | 204 | } |
219 | Scope::ExprScope(e) => { | 205 | Scope::ExprScope(e) => { |
220 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { | 206 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { |
221 | f( | 207 | f(e.name().clone(), PerNs::values(Resolution::LocalBinding(e.pat()))); |
222 | e.name().clone(), | ||
223 | PerNs::values(Resolution::LocalBinding(e.pat())), | ||
224 | ); | ||
225 | }); | 208 | }); |
226 | } | 209 | } |
227 | } | 210 | } |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 59f782277..625a2ce45 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -65,11 +65,7 @@ pub fn module_from_child_node( | |||
65 | file_id: FileId, | 65 | file_id: FileId, |
66 | child: &SyntaxNode, | 66 | child: &SyntaxNode, |
67 | ) -> Option<Module> { | 67 | ) -> Option<Module> { |
68 | if let Some(m) = child | 68 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { |
69 | .ancestors() | ||
70 | .filter_map(ast::Module::cast) | ||
71 | .find(|it| !it.has_semi()) | ||
72 | { | ||
73 | module_from_inline(db, file_id.into(), m) | 69 | module_from_inline(db, file_id.into(), m) |
74 | } else { | 70 | } else { |
75 | module_from_file_id(db, file_id.into()) | 71 | module_from_file_id(db, file_id.into()) |
@@ -82,14 +78,13 @@ fn module_from_source( | |||
82 | decl_id: Option<SourceFileItemId>, | 78 | decl_id: Option<SourceFileItemId>, |
83 | ) -> Option<Module> { | 79 | ) -> Option<Module> { |
84 | let source_root_id = db.file_source_root(file_id.as_original_file()); | 80 | let source_root_id = db.file_source_root(file_id.as_original_file()); |
85 | db.source_root_crates(source_root_id) | 81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( |
86 | .iter() | 82 | |krate| { |
87 | .map(|&crate_id| Crate { crate_id }) | ||
88 | .find_map(|krate| { | ||
89 | let module_tree = db.module_tree(krate); | 83 | let module_tree = db.module_tree(krate); |
90 | let module_id = module_tree.find_module_by_source(file_id, decl_id)?; | 84 | let module_id = module_tree.find_module_by_source(file_id, decl_id)?; |
91 | Some(Module { krate, module_id }) | 85 | Some(Module { krate, module_id }) |
92 | }) | 86 | }, |
87 | ) | ||
93 | } | 88 | } |
94 | 89 | ||
95 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { | 90 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { |
@@ -116,9 +111,7 @@ pub fn function_from_module( | |||
116 | let (file_id, _) = module.definition_source(db); | 111 | let (file_id, _) = module.definition_source(db); |
117 | let file_id = file_id.into(); | 112 | let file_id = file_id.into(); |
118 | let ctx = LocationCtx::new(db, module, file_id); | 113 | let ctx = LocationCtx::new(db, module, file_id); |
119 | Function { | 114 | Function { id: ctx.to_def(fn_def) } |
120 | id: ctx.to_def(fn_def), | ||
121 | } | ||
122 | } | 115 | } |
123 | 116 | ||
124 | pub fn function_from_child_node( | 117 | pub fn function_from_child_node( |
@@ -138,18 +131,14 @@ pub fn struct_from_module( | |||
138 | let (file_id, _) = module.definition_source(db); | 131 | let (file_id, _) = module.definition_source(db); |
139 | let file_id = file_id.into(); | 132 | let file_id = file_id.into(); |
140 | let ctx = LocationCtx::new(db, module, file_id); | 133 | let ctx = LocationCtx::new(db, module, file_id); |
141 | Struct { | 134 | Struct { id: ctx.to_def(struct_def) } |
142 | id: ctx.to_def(struct_def), | ||
143 | } | ||
144 | } | 135 | } |
145 | 136 | ||
146 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { | 137 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { |
147 | let (file_id, _) = module.definition_source(db); | 138 | let (file_id, _) = module.definition_source(db); |
148 | let file_id = file_id.into(); | 139 | let file_id = file_id.into(); |
149 | let ctx = LocationCtx::new(db, module, file_id); | 140 | let ctx = LocationCtx::new(db, module, file_id); |
150 | Enum { | 141 | Enum { id: ctx.to_def(enum_def) } |
151 | id: ctx.to_def(enum_def), | ||
152 | } | ||
153 | } | 142 | } |
154 | 143 | ||
155 | pub fn trait_from_module( | 144 | pub fn trait_from_module( |
@@ -160,9 +149,7 @@ pub fn trait_from_module( | |||
160 | let (file_id, _) = module.definition_source(db); | 149 | let (file_id, _) = module.definition_source(db); |
161 | let file_id = file_id.into(); | 150 | let file_id = file_id.into(); |
162 | let ctx = LocationCtx::new(db, module, file_id); | 151 | let ctx = LocationCtx::new(db, module, file_id); |
163 | Trait { | 152 | Trait { id: ctx.to_def(trait_def) } |
164 | id: ctx.to_def(trait_def), | ||
165 | } | ||
166 | } | 153 | } |
167 | 154 | ||
168 | pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { | 155 | pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 86a7f8b83..453520bbe 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -305,10 +305,8 @@ impl Ty { | |||
305 | match type_ref { | 305 | match type_ref { |
306 | TypeRef::Never => Ty::Never, | 306 | TypeRef::Never => Ty::Never, |
307 | TypeRef::Tuple(inner) => { | 307 | TypeRef::Tuple(inner) => { |
308 | let inner_tys = inner | 308 | let inner_tys = |
309 | .iter() | 309 | inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); |
310 | .map(|tr| Ty::from_hir(db, resolver, tr)) | ||
311 | .collect::<Vec<_>>(); | ||
312 | Ty::Tuple(inner_tys.into()) | 310 | Ty::Tuple(inner_tys.into()) |
313 | } | 311 | } |
314 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), | 312 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), |
@@ -330,17 +328,11 @@ impl Ty { | |||
330 | } | 328 | } |
331 | TypeRef::Placeholder => Ty::Unknown, | 329 | TypeRef::Placeholder => Ty::Unknown, |
332 | TypeRef::Fn(params) => { | 330 | TypeRef::Fn(params) => { |
333 | let mut inner_tys = params | 331 | let mut inner_tys = |
334 | .iter() | 332 | params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect::<Vec<_>>(); |
335 | .map(|tr| Ty::from_hir(db, resolver, tr)) | 333 | let return_ty = |
336 | .collect::<Vec<_>>(); | 334 | inner_tys.pop().expect("TypeRef::Fn should always have at least return type"); |
337 | let return_ty = inner_tys | 335 | let sig = FnSig { input: inner_tys, output: return_ty }; |
338 | .pop() | ||
339 | .expect("TypeRef::Fn should always have at least return type"); | ||
340 | let sig = FnSig { | ||
341 | input: inner_tys, | ||
342 | output: return_ty, | ||
343 | }; | ||
344 | Ty::FnPtr(Arc::new(sig)) | 336 | Ty::FnPtr(Arc::new(sig)) |
345 | } | 337 | } |
346 | TypeRef::Error => Ty::Unknown, | 338 | TypeRef::Error => Ty::Unknown, |
@@ -407,10 +399,7 @@ impl Ty { | |||
407 | resolved: TypableDef, | 399 | resolved: TypableDef, |
408 | ) -> Substs { | 400 | ) -> Substs { |
409 | let mut substs = Vec::new(); | 401 | let mut substs = Vec::new(); |
410 | let last = path | 402 | let last = path.segments.last().expect("path should have at least one segment"); |
411 | .segments | ||
412 | .last() | ||
413 | .expect("path should have at least one segment"); | ||
414 | let (def_generics, segment) = match resolved { | 403 | let (def_generics, segment) = match resolved { |
415 | TypableDef::Function(func) => (func.generic_params(db), last), | 404 | TypableDef::Function(func) => (func.generic_params(db), last), |
416 | TypableDef::Struct(s) => (s.generic_params(db), last), | 405 | TypableDef::Struct(s) => (s.generic_params(db), last), |
@@ -447,11 +436,8 @@ impl Ty { | |||
447 | } | 436 | } |
448 | // add placeholders for args that were not provided | 437 | // add placeholders for args that were not provided |
449 | // TODO: handle defaults | 438 | // TODO: handle defaults |
450 | let supplied_params = segment | 439 | let supplied_params = |
451 | .args_and_bindings | 440 | segment.args_and_bindings.as_ref().map(|ga| ga.args.len()).unwrap_or(0); |
452 | .as_ref() | ||
453 | .map(|ga| ga.args.len()) | ||
454 | .unwrap_or(0); | ||
455 | for _ in supplied_params..def_generics.params.len() { | 441 | for _ in supplied_params..def_generics.params.len() { |
456 | substs.push(Ty::Unknown); | 442 | substs.push(Ty::Unknown); |
457 | } | 443 | } |
@@ -531,17 +517,8 @@ impl Ty { | |||
531 | /// `Option<u32>` afterwards.) | 517 | /// `Option<u32>` afterwards.) |
532 | pub fn apply_substs(self, substs: Substs) -> Ty { | 518 | pub fn apply_substs(self, substs: Substs) -> Ty { |
533 | match self { | 519 | match self { |
534 | Ty::Adt { def_id, name, .. } => Ty::Adt { | 520 | Ty::Adt { def_id, name, .. } => Ty::Adt { def_id, name, substs }, |
535 | def_id, | 521 | Ty::FnDef { def, name, sig, .. } => Ty::FnDef { def, name, sig, substs }, |
536 | name, | ||
537 | substs, | ||
538 | }, | ||
539 | Ty::FnDef { def, name, sig, .. } => Ty::FnDef { | ||
540 | def, | ||
541 | name, | ||
542 | sig, | ||
543 | substs, | ||
544 | }, | ||
545 | _ => self, | 522 | _ => self, |
546 | } | 523 | } |
547 | } | 524 | } |
@@ -591,42 +568,25 @@ impl fmt::Display for Ty { | |||
591 | if ts.len() == 1 { | 568 | if ts.len() == 1 { |
592 | write!(f, "({},)", ts[0]) | 569 | write!(f, "({},)", ts[0]) |
593 | } else { | 570 | } else { |
594 | join(ts.iter()) | 571 | join(ts.iter()).surround_with("(", ")").separator(", ").to_fmt(f) |
595 | .surround_with("(", ")") | ||
596 | .separator(", ") | ||
597 | .to_fmt(f) | ||
598 | } | 572 | } |
599 | } | 573 | } |
600 | Ty::FnPtr(sig) => { | 574 | Ty::FnPtr(sig) => { |
601 | join(sig.input.iter()) | 575 | join(sig.input.iter()).surround_with("fn(", ")").separator(", ").to_fmt(f)?; |
602 | .surround_with("fn(", ")") | ||
603 | .separator(", ") | ||
604 | .to_fmt(f)?; | ||
605 | write!(f, " -> {}", sig.output) | 576 | write!(f, " -> {}", sig.output) |
606 | } | 577 | } |
607 | Ty::FnDef { | 578 | Ty::FnDef { name, substs, sig, .. } => { |
608 | name, substs, sig, .. | ||
609 | } => { | ||
610 | write!(f, "fn {}", name)?; | 579 | write!(f, "fn {}", name)?; |
611 | if substs.0.len() > 0 { | 580 | if substs.0.len() > 0 { |
612 | join(substs.0.iter()) | 581 | join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?; |
613 | .surround_with("<", ">") | ||
614 | .separator(", ") | ||
615 | .to_fmt(f)?; | ||
616 | } | 582 | } |
617 | join(sig.input.iter()) | 583 | join(sig.input.iter()).surround_with("(", ")").separator(", ").to_fmt(f)?; |
618 | .surround_with("(", ")") | ||
619 | .separator(", ") | ||
620 | .to_fmt(f)?; | ||
621 | write!(f, " -> {}", sig.output) | 584 | write!(f, " -> {}", sig.output) |
622 | } | 585 | } |
623 | Ty::Adt { name, substs, .. } => { | 586 | Ty::Adt { name, substs, .. } => { |
624 | write!(f, "{}", name)?; | 587 | write!(f, "{}", name)?; |
625 | if substs.0.len() > 0 { | 588 | if substs.0.len() > 0 { |
626 | join(substs.0.iter()) | 589 | join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?; |
627 | .surround_with("<", ">") | ||
628 | .separator(", ") | ||
629 | .to_fmt(f)?; | ||
630 | } | 590 | } |
631 | Ok(()) | 591 | Ok(()) |
632 | } | 592 | } |
@@ -646,31 +606,16 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | |||
646 | let resolver = def.resolver(db); | 606 | let resolver = def.resolver(db); |
647 | let generics = def.generic_params(db); | 607 | let generics = def.generic_params(db); |
648 | let name = def.name(db); | 608 | let name = def.name(db); |
649 | let input = signature | 609 | let input = |
650 | .params() | 610 | signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); |
651 | .iter() | ||
652 | .map(|tr| Ty::from_hir(db, &resolver, tr)) | ||
653 | .collect::<Vec<_>>(); | ||
654 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); | 611 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); |
655 | let sig = Arc::new(FnSig { input, output }); | 612 | let sig = Arc::new(FnSig { input, output }); |
656 | let substs = make_substs(&generics); | 613 | let substs = make_substs(&generics); |
657 | Ty::FnDef { | 614 | Ty::FnDef { def, sig, name, substs } |
658 | def, | ||
659 | sig, | ||
660 | name, | ||
661 | substs, | ||
662 | } | ||
663 | } | 615 | } |
664 | 616 | ||
665 | fn make_substs(generics: &GenericParams) -> Substs { | 617 | fn make_substs(generics: &GenericParams) -> Substs { |
666 | Substs( | 618 | Substs(generics.params.iter().map(|_p| Ty::Unknown).collect::<Vec<_>>().into()) |
667 | generics | ||
668 | .params | ||
669 | .iter() | ||
670 | .map(|_p| Ty::Unknown) | ||
671 | .collect::<Vec<_>>() | ||
672 | .into(), | ||
673 | ) | ||
674 | } | 619 | } |
675 | 620 | ||
676 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | 621 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
@@ -935,11 +880,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
935 | } | 880 | } |
936 | 881 | ||
937 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { | 882 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { |
938 | substs1 | 883 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify(t1, t2)) |
939 | .0 | ||
940 | .iter() | ||
941 | .zip(substs2.0.iter()) | ||
942 | .all(|(t1, t2)| self.unify(t1, t2)) | ||
943 | } | 884 | } |
944 | 885 | ||
945 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 886 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
@@ -961,25 +902,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
961 | }, | 902 | }, |
962 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, | 903 | (Ty::Bool, _) | (Ty::Str, _) | (Ty::Never, _) | (Ty::Char, _) => ty1 == ty2, |
963 | ( | 904 | ( |
964 | Ty::Adt { | 905 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, |
965 | def_id: def_id1, | 906 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, |
966 | substs: substs1, | ||
967 | .. | ||
968 | }, | ||
969 | Ty::Adt { | ||
970 | def_id: def_id2, | ||
971 | substs: substs2, | ||
972 | .. | ||
973 | }, | ||
974 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), | 907 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), |
975 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), | 908 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), |
976 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 909 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), |
977 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 910 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), |
978 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | 911 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, |
979 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => ts1 | 912 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { |
980 | .iter() | 913 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify(t1, t2)) |
981 | .zip(ts2.iter()) | 914 | } |
982 | .all(|(t1, t2)| self.unify(t1, t2)), | ||
983 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 915 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
984 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 916 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |
985 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | 917 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { |
@@ -994,8 +926,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
994 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | 926 | | (Ty::Infer(InferTy::FloatVar(tv)), other) |
995 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | 927 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { |
996 | // the type var is unknown since we tried to resolve it | 928 | // the type var is unknown since we tried to resolve it |
997 | self.var_unification_table | 929 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); |
998 | .union_value(*tv, TypeVarValue::Known(other.clone())); | ||
999 | true | 930 | true |
1000 | } | 931 | } |
1001 | _ => false, | 932 | _ => false, |
@@ -1003,21 +934,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1003 | } | 934 | } |
1004 | 935 | ||
1005 | fn new_type_var(&mut self) -> Ty { | 936 | fn new_type_var(&mut self) -> Ty { |
1006 | Ty::Infer(InferTy::TypeVar( | 937 | Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1007 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1008 | )) | ||
1009 | } | 938 | } |
1010 | 939 | ||
1011 | fn new_integer_var(&mut self) -> Ty { | 940 | fn new_integer_var(&mut self) -> Ty { |
1012 | Ty::Infer(InferTy::IntVar( | 941 | Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1013 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1014 | )) | ||
1015 | } | 942 | } |
1016 | 943 | ||
1017 | fn new_float_var(&mut self) -> Ty { | 944 | fn new_float_var(&mut self) -> Ty { |
1018 | Ty::Infer(InferTy::FloatVar( | 945 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
1019 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
1020 | )) | ||
1021 | } | 946 | } |
1022 | 947 | ||
1023 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 948 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
@@ -1207,9 +1132,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1207 | 1132 | ||
1208 | for subpat in subpats { | 1133 | for subpat in subpats { |
1209 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); | 1134 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); |
1210 | let expected_ty = matching_field | 1135 | let expected_ty = |
1211 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 1136 | matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); |
1212 | .subst(&substs); | ||
1213 | self.infer_pat(subpat.pat, &expected_ty); | 1137 | self.infer_pat(subpat.pat, &expected_ty); |
1214 | } | 1138 | } |
1215 | 1139 | ||
@@ -1249,25 +1173,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1249 | let subty = self.infer_pat(*pat, expectation); | 1173 | let subty = self.infer_pat(*pat, expectation); |
1250 | Ty::Ref(subty.into(), *mutability) | 1174 | Ty::Ref(subty.into(), *mutability) |
1251 | } | 1175 | } |
1252 | Pat::TupleStruct { | 1176 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
1253 | path: ref p, | 1177 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected) |
1254 | args: ref subpats, | 1178 | } |
1255 | } => self.infer_tuple_struct_pat(p.as_ref(), subpats, expected), | 1179 | Pat::Struct { path: ref p, args: ref fields } => { |
1256 | Pat::Struct { | 1180 | self.infer_struct_pat(p.as_ref(), fields, expected) |
1257 | path: ref p, | 1181 | } |
1258 | args: ref fields, | ||
1259 | } => self.infer_struct_pat(p.as_ref(), fields, expected), | ||
1260 | Pat::Path(path) => { | 1182 | Pat::Path(path) => { |
1261 | // TODO use correct resolver for the surrounding expression | 1183 | // TODO use correct resolver for the surrounding expression |
1262 | let resolver = self.resolver.clone(); | 1184 | let resolver = self.resolver.clone(); |
1263 | self.infer_path_expr(&resolver, &path) | 1185 | self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) |
1264 | .unwrap_or(Ty::Unknown) | 1186 | } |
1265 | } | 1187 | Pat::Bind { mode, name: _name, subpat } => { |
1266 | Pat::Bind { | ||
1267 | mode, | ||
1268 | name: _name, | ||
1269 | subpat, | ||
1270 | } => { | ||
1271 | let subty = if let Some(subpat) = subpat { | 1188 | let subty = if let Some(subpat) = subpat { |
1272 | self.infer_pat(*subpat, expected) | 1189 | self.infer_pat(*subpat, expected) |
1273 | } else { | 1190 | } else { |
@@ -1294,11 +1211,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1294 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1211 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1295 | let ty = match &body[tgt_expr] { | 1212 | let ty = match &body[tgt_expr] { |
1296 | Expr::Missing => Ty::Unknown, | 1213 | Expr::Missing => Ty::Unknown, |
1297 | Expr::If { | 1214 | Expr::If { condition, then_branch, else_branch } => { |
1298 | condition, | ||
1299 | then_branch, | ||
1300 | else_branch, | ||
1301 | } => { | ||
1302 | // if let is desugared to match, so this is always simple if | 1215 | // if let is desugared to match, so this is always simple if |
1303 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); | 1216 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); |
1304 | let then_ty = self.infer_expr(*then_branch, expected); | 1217 | let then_ty = self.infer_expr(*then_branch, expected); |
@@ -1325,21 +1238,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1325 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1238 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1326 | Ty::unit() | 1239 | Ty::unit() |
1327 | } | 1240 | } |
1328 | Expr::For { | 1241 | Expr::For { iterable, body, pat } => { |
1329 | iterable, | ||
1330 | body, | ||
1331 | pat, | ||
1332 | } => { | ||
1333 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 1242 | let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
1334 | self.infer_pat(*pat, &Ty::Unknown); | 1243 | self.infer_pat(*pat, &Ty::Unknown); |
1335 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 1244 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
1336 | Ty::unit() | 1245 | Ty::unit() |
1337 | } | 1246 | } |
1338 | Expr::Lambda { | 1247 | Expr::Lambda { body, args, arg_types } => { |
1339 | body, | ||
1340 | args, | ||
1341 | arg_types, | ||
1342 | } => { | ||
1343 | assert_eq!(args.len(), arg_types.len()); | 1248 | assert_eq!(args.len(), arg_types.len()); |
1344 | 1249 | ||
1345 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { | 1250 | for (arg_pat, arg_type) in args.iter().zip(arg_types.iter()) { |
@@ -1362,11 +1267,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1362 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), | 1267 | Ty::FnPtr(sig) => (sig.input.clone(), sig.output.clone()), |
1363 | Ty::FnDef { substs, sig, .. } => { | 1268 | Ty::FnDef { substs, sig, .. } => { |
1364 | let ret_ty = sig.output.clone().subst(&substs); | 1269 | let ret_ty = sig.output.clone().subst(&substs); |
1365 | let param_tys = sig | 1270 | let param_tys = |
1366 | .input | 1271 | sig.input.iter().map(|ty| ty.clone().subst(&substs)).collect(); |
1367 | .iter() | ||
1368 | .map(|ty| ty.clone().subst(&substs)) | ||
1369 | .collect(); | ||
1370 | (param_tys, ret_ty) | 1272 | (param_tys, ret_ty) |
1371 | } | 1273 | } |
1372 | _ => { | 1274 | _ => { |
@@ -1381,11 +1283,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1381 | } | 1283 | } |
1382 | ret_ty | 1284 | ret_ty |
1383 | } | 1285 | } |
1384 | Expr::MethodCall { | 1286 | Expr::MethodCall { receiver, args, method_name } => { |
1385 | receiver, | ||
1386 | args, | ||
1387 | method_name, | ||
1388 | } => { | ||
1389 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); | 1287 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); |
1390 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); | 1288 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
1391 | let method_ty = match resolved { | 1289 | let method_ty = match resolved { |
@@ -1399,11 +1297,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1399 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { | 1297 | let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { |
1400 | Ty::FnPtr(sig) => { | 1298 | Ty::FnPtr(sig) => { |
1401 | if !sig.input.is_empty() { | 1299 | if !sig.input.is_empty() { |
1402 | ( | 1300 | (sig.input[0].clone(), sig.input[1..].to_vec(), sig.output.clone()) |
1403 | sig.input[0].clone(), | ||
1404 | sig.input[1..].to_vec(), | ||
1405 | sig.output.clone(), | ||
1406 | ) | ||
1407 | } else { | 1301 | } else { |
1408 | (Ty::Unknown, Vec::new(), sig.output.clone()) | 1302 | (Ty::Unknown, Vec::new(), sig.output.clone()) |
1409 | } | 1303 | } |
@@ -1469,11 +1363,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1469 | } | 1363 | } |
1470 | Ty::Never | 1364 | Ty::Never |
1471 | } | 1365 | } |
1472 | Expr::StructLit { | 1366 | Expr::StructLit { path, fields, spread } => { |
1473 | path, | ||
1474 | fields, | ||
1475 | spread, | ||
1476 | } => { | ||
1477 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1367 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1478 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1368 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1479 | for field in fields { | 1369 | for field in fields { |
@@ -1497,14 +1387,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1497 | let i = name.to_string().parse::<usize>().ok(); | 1387 | let i = name.to_string().parse::<usize>().ok(); |
1498 | i.and_then(|i| fields.get(i).cloned()) | 1388 | i.and_then(|i| fields.get(i).cloned()) |
1499 | } | 1389 | } |
1500 | Ty::Adt { | 1390 | Ty::Adt { def_id: AdtDef::Struct(s), ref substs, .. } => { |
1501 | def_id: AdtDef::Struct(s), | 1391 | s.field(self.db, name).map(|field| { |
1502 | ref substs, | 1392 | self.write_field_resolution(tgt_expr, field); |
1503 | .. | 1393 | field.ty(self.db).subst(substs) |
1504 | } => s.field(self.db, name).map(|field| { | 1394 | }) |
1505 | self.write_field_resolution(tgt_expr, field); | 1395 | } |
1506 | field.ty(self.db).subst(substs) | ||
1507 | }), | ||
1508 | _ => None, | 1396 | _ => None, |
1509 | }) | 1397 | }) |
1510 | .unwrap_or(Ty::Unknown); | 1398 | .unwrap_or(Ty::Unknown); |
@@ -1635,15 +1523,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1635 | ) -> Ty { | 1523 | ) -> Ty { |
1636 | for stmt in statements { | 1524 | for stmt in statements { |
1637 | match stmt { | 1525 | match stmt { |
1638 | Statement::Let { | 1526 | Statement::Let { pat, type_ref, initializer } => { |
1639 | pat, | 1527 | let decl_ty = |
1640 | type_ref, | 1528 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); |
1641 | initializer, | ||
1642 | } => { | ||
1643 | let decl_ty = type_ref | ||
1644 | .as_ref() | ||
1645 | .map(|tr| self.make_ty(tr)) | ||
1646 | .unwrap_or(Ty::Unknown); | ||
1647 | let decl_ty = self.insert_type_vars(decl_ty); | 1529 | let decl_ty = self.insert_type_vars(decl_ty); |
1648 | let ty = if let Some(expr) = initializer { | 1530 | let ty = if let Some(expr) = initializer { |
1649 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); | 1531 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); |
@@ -1659,11 +1541,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1659 | } | 1541 | } |
1660 | } | 1542 | } |
1661 | } | 1543 | } |
1662 | let ty = if let Some(expr) = tail { | 1544 | let ty = if let Some(expr) = tail { self.infer_expr(expr, expected) } else { Ty::unit() }; |
1663 | self.infer_expr(expr, expected) | ||
1664 | } else { | ||
1665 | Ty::unit() | ||
1666 | }; | ||
1667 | ty | 1545 | ty |
1668 | } | 1546 | } |
1669 | 1547 | ||
@@ -1678,10 +1556,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1678 | } | 1556 | } |
1679 | 1557 | ||
1680 | fn infer_body(&mut self) { | 1558 | fn infer_body(&mut self) { |
1681 | self.infer_expr( | 1559 | self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone())); |
1682 | self.body.body_expr(), | ||
1683 | &Expectation::has_type(self.return_ty.clone()), | ||
1684 | ); | ||
1685 | } | 1560 | } |
1686 | } | 1561 | } |
1687 | 1562 | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index a7d4517ee..da7587f01 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -46,18 +46,13 @@ impl CrateImplBlocks { | |||
46 | ty: &Ty, | 46 | ty: &Ty, |
47 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { | 47 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { |
48 | let fingerprint = TyFingerprint::for_impl(ty); | 48 | let fingerprint = TyFingerprint::for_impl(ty); |
49 | fingerprint | 49 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( |
50 | .and_then(|f| self.impls.get(&f)) | 50 | move |(module_id, impl_id)| { |
51 | .into_iter() | 51 | let module = Module { krate: self.krate, module_id: *module_id }; |
52 | .flat_map(|i| i.iter()) | ||
53 | .map(move |(module_id, impl_id)| { | ||
54 | let module = Module { | ||
55 | krate: self.krate, | ||
56 | module_id: *module_id, | ||
57 | }; | ||
58 | let module_impl_blocks = db.impls_in_module(module); | 52 | let module_impl_blocks = db.impls_in_module(module); |
59 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) | 53 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) |
60 | }) | 54 | }, |
55 | ) | ||
61 | } | 56 | } |
62 | 57 | ||
63 | pub fn lookup_impl_blocks_for_trait<'a>( | 58 | pub fn lookup_impl_blocks_for_trait<'a>( |
@@ -66,18 +61,13 @@ impl CrateImplBlocks { | |||
66 | tr: &Trait, | 61 | tr: &Trait, |
67 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { | 62 | ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a { |
68 | let id = tr.id; | 63 | let id = tr.id; |
69 | self.impls_by_trait | 64 | self.impls_by_trait.get(&id).into_iter().flat_map(|i| i.iter()).map( |
70 | .get(&id) | 65 | move |(module_id, impl_id)| { |
71 | .into_iter() | 66 | let module = Module { krate: self.krate, module_id: *module_id }; |
72 | .flat_map(|i| i.iter()) | ||
73 | .map(move |(module_id, impl_id)| { | ||
74 | let module = Module { | ||
75 | krate: self.krate, | ||
76 | module_id: *module_id, | ||
77 | }; | ||
78 | let module_impl_blocks = db.impls_in_module(module); | 67 | let module_impl_blocks = db.impls_in_module(module); |
79 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) | 68 | (module, ImplBlock::from_id(module_impl_blocks, *impl_id)) |
80 | }) | 69 | }, |
70 | ) | ||
81 | } | 71 | } |
82 | 72 | ||
83 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { | 73 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 30da8fc23..2621d1b55 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -634,11 +634,7 @@ fn infer(content: &str) -> String { | |||
634 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 634 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
635 | let source_file = db.parse(file_id); | 635 | let source_file = db.parse(file_id); |
636 | let mut acc = String::new(); | 636 | let mut acc = String::new(); |
637 | for fn_def in source_file | 637 | for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) { |
638 | .syntax() | ||
639 | .descendants() | ||
640 | .filter_map(ast::FnDef::cast) | ||
641 | { | ||
642 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); | 638 | let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); |
643 | let inference_result = func.infer(&db); | 639 | let inference_result = func.infer(&db); |
644 | let body_syntax_mapping = func.body_syntax_mapping(&db); | 640 | let body_syntax_mapping = func.body_syntax_mapping(&db); |
@@ -725,8 +721,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
725 | " | 721 | " |
726 | .to_string(); | 722 | .to_string(); |
727 | 723 | ||
728 | db.query_mut(ra_db::FileTextQuery) | 724 | db.query_mut(ra_db::FileTextQuery).set(pos.file_id, Arc::new(new_text)); |
729 | .set(pos.file_id, Arc::new(new_text)); | ||
730 | 725 | ||
731 | { | 726 | { |
732 | let events = db.log_executed(|| { | 727 | let events = db.log_executed(|| { |
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs index c9db4e0a5..ee8b7376a 100644 --- a/crates/ra_hir/src/type_ref.rs +++ b/crates/ra_hir/src/type_ref.rs | |||
@@ -62,11 +62,9 @@ impl TypeRef { | |||
62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), | 62 | ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()), |
63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), | 63 | TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()), |
64 | NeverType(..) => TypeRef::Never, | 64 | NeverType(..) => TypeRef::Never, |
65 | PathType(inner) => inner | 65 | PathType(inner) => { |
66 | .path() | 66 | inner.path().and_then(Path::from_ast).map(TypeRef::Path).unwrap_or(TypeRef::Error) |
67 | .and_then(Path::from_ast) | 67 | } |
68 | .map(TypeRef::Path) | ||
69 | .unwrap_or(TypeRef::Error), | ||
70 | PointerType(inner) => { | 68 | PointerType(inner) => { |
71 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); | 69 | let inner_ty = TypeRef::from_ast_opt(inner.type_ref()); |
72 | let mutability = Mutability::from_mutable(inner.is_mut()); | 70 | let mutability = Mutability::from_mutable(inner.is_mut()); |
@@ -83,10 +81,7 @@ impl TypeRef { | |||
83 | FnPointerType(inner) => { | 81 | FnPointerType(inner) => { |
84 | let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); | 82 | let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); |
85 | let mut params = if let Some(pl) = inner.param_list() { | 83 | let mut params = if let Some(pl) = inner.param_list() { |
86 | pl.params() | 84 | pl.params().map(|p| p.type_ref()).map(TypeRef::from_ast_opt).collect() |
87 | .map(|p| p.type_ref()) | ||
88 | .map(TypeRef::from_ast_opt) | ||
89 | .collect() | ||
90 | } else { | 85 | } else { |
91 | Vec::new() | 86 | Vec::new() |
92 | }; | 87 | }; |
diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide_api/src/assists.rs index 2a96fdf47..7a9c66681 100644 --- a/crates/ra_ide_api/src/assists.rs +++ b/crates/ra_ide_api/src/assists.rs | |||
@@ -7,10 +7,7 @@ pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<SourceChange> | |||
7 | .into_iter() | 7 | .into_iter() |
8 | .map(|(label, action)| { | 8 | .map(|(label, action)| { |
9 | let file_id = frange.file_id; | 9 | let file_id = frange.file_id; |
10 | let file_edit = SourceFileEdit { | 10 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; |
11 | file_id, | ||
12 | edit: action.edit, | ||
13 | }; | ||
14 | SourceChange { | 11 | SourceChange { |
15 | label: label.label, | 12 | label: label.label, |
16 | source_file_edits: vec![file_edit], | 13 | source_file_edits: vec![file_edit], |
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index a59ab7853..1b279615c 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -21,9 +21,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
21 | 21 | ||
22 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | 22 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). |
23 | let file_symbols = crate::symbol_index::index_resolve(db, name_ref); | 23 | let file_symbols = crate::symbol_index::index_resolve(db, name_ref); |
24 | let symbol = file_symbols | 24 | let symbol = file_symbols.into_iter().find(|it| it.ptr.kind() == FN_DEF)?; |
25 | .into_iter() | ||
26 | .find(|it| it.ptr.kind() == FN_DEF)?; | ||
27 | let fn_file = db.parse(symbol.file_id); | 25 | let fn_file = db.parse(symbol.file_id); |
28 | let fn_def = symbol.ptr.to_node(&fn_file); | 26 | let fn_def = symbol.ptr.to_node(&fn_file); |
29 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); | 27 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); |
@@ -53,13 +51,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
53 | let start = arg_list_range.start(); | 51 | let start = arg_list_range.start(); |
54 | 52 | ||
55 | let range_search = TextRange::from_to(start, position.offset); | 53 | let range_search = TextRange::from_to(start, position.offset); |
56 | let mut commas: usize = arg_list | 54 | let mut commas: usize = |
57 | .syntax() | 55 | arg_list.syntax().text().slice(range_search).to_string().matches(',').count(); |
58 | .text() | ||
59 | .slice(range_search) | ||
60 | .to_string() | ||
61 | .matches(',') | ||
62 | .count(); | ||
63 | 56 | ||
64 | // If we have a method call eat the first param since it's just self. | 57 | // If we have a method call eat the first param since it's just self. |
65 | if has_self { | 58 | if has_self { |
@@ -96,11 +89,9 @@ impl<'a> FnCallNode<'a> { | |||
96 | _ => return None, | 89 | _ => return None, |
97 | }), | 90 | }), |
98 | 91 | ||
99 | FnCallNode::MethodCallExpr(call_expr) => call_expr | 92 | FnCallNode::MethodCallExpr(call_expr) => { |
100 | .syntax() | 93 | call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) |
101 | .children() | 94 | } |
102 | .filter_map(ast::NameRef::cast) | ||
103 | .nth(0), | ||
104 | } | 95 | } |
105 | } | 96 | } |
106 | 97 | ||
@@ -117,12 +108,7 @@ impl CallInfo { | |||
117 | let label = crate::completion::function_label(node)?; | 108 | let label = crate::completion::function_label(node)?; |
118 | let doc = function.docs(db); | 109 | let doc = function.docs(db); |
119 | 110 | ||
120 | Some(CallInfo { | 111 | Some(CallInfo { parameters: param_list(node), label, doc, active_parameter: None }) |
121 | parameters: param_list(node), | ||
122 | label, | ||
123 | doc, | ||
124 | active_parameter: None, | ||
125 | }) | ||
126 | } | 112 | } |
127 | } | 113 | } |
128 | 114 | ||
@@ -136,10 +122,7 @@ fn param_list(node: &ast::FnDef) -> Vec<String> { | |||
136 | // Maybe use param.pat here? See if we can just extract the name? | 122 | // Maybe use param.pat here? See if we can just extract the name? |
137 | //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); | 123 | //res.extend(param_list.params().map(|p| p.syntax().text().to_string())); |
138 | res.extend( | 124 | res.extend( |
139 | param_list | 125 | param_list.params().filter_map(|p| p.pat()).map(|pat| pat.syntax().text().to_string()), |
140 | .params() | ||
141 | .filter_map(|p| p.pat()) | ||
142 | .map(|pat| pat.syntax().text().to_string()), | ||
143 | ); | 126 | ); |
144 | } | 127 | } |
145 | res | 128 | res |
@@ -378,10 +361,7 @@ pub fn foo() { | |||
378 | "#, | 361 | "#, |
379 | ); | 362 | ); |
380 | 363 | ||
381 | assert_eq!( | 364 | assert_eq!(info.parameters, vec!["&mut self".to_string(), "ctx".to_string()]); |
382 | info.parameters, | ||
383 | vec!["&mut self".to_string(), "ctx".to_string()] | ||
384 | ); | ||
385 | assert_eq!(info.active_parameter, Some(1)); | 365 | assert_eq!(info.active_parameter, Some(1)); |
386 | assert_eq!( | 366 | assert_eq!( |
387 | info.doc.map(|it| it.into()), | 367 | info.doc.map(|it| it.into()), |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 992955740..3f041f9c3 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -65,16 +65,8 @@ impl AnalysisChange { | |||
65 | path: RelativePathBuf, | 65 | path: RelativePathBuf, |
66 | text: Arc<String>, | 66 | text: Arc<String>, |
67 | ) { | 67 | ) { |
68 | let file = AddFile { | 68 | let file = AddFile { file_id, path, text }; |
69 | file_id, | 69 | self.roots_changed.entry(root_id).or_default().added.push(file); |
70 | path, | ||
71 | text, | ||
72 | }; | ||
73 | self.roots_changed | ||
74 | .entry(root_id) | ||
75 | .or_default() | ||
76 | .added | ||
77 | .push(file); | ||
78 | } | 70 | } |
79 | 71 | ||
80 | pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { | 72 | pub fn change_file(&mut self, file_id: FileId, new_text: Arc<String>) { |
@@ -83,11 +75,7 @@ impl AnalysisChange { | |||
83 | 75 | ||
84 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { | 76 | pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { |
85 | let file = RemoveFile { file_id, path }; | 77 | let file = RemoveFile { file_id, path }; |
86 | self.roots_changed | 78 | self.roots_changed.entry(root_id).or_default().removed.push(file); |
87 | .entry(root_id) | ||
88 | .or_default() | ||
89 | .removed | ||
90 | .push(file); | ||
91 | } | 79 | } |
92 | 80 | ||
93 | pub fn add_library(&mut self, data: LibraryData) { | 81 | pub fn add_library(&mut self, data: LibraryData) { |
@@ -155,17 +143,9 @@ impl LibraryData { | |||
155 | let mut root_change = RootChange::default(); | 143 | let mut root_change = RootChange::default(); |
156 | root_change.added = files | 144 | root_change.added = files |
157 | .into_iter() | 145 | .into_iter() |
158 | .map(|(file_id, path, text)| AddFile { | 146 | .map(|(file_id, path, text)| AddFile { file_id, path, text }) |
159 | file_id, | ||
160 | path, | ||
161 | text, | ||
162 | }) | ||
163 | .collect(); | 147 | .collect(); |
164 | LibraryData { | 148 | LibraryData { root_id, root_change, symbol_index } |
165 | root_id, | ||
166 | root_change, | ||
167 | symbol_index, | ||
168 | } | ||
169 | } | 149 | } |
170 | } | 150 | } |
171 | 151 | ||
@@ -226,10 +206,7 @@ impl RootDatabase { | |||
226 | self.last_gc_check = time::Instant::now(); | 206 | self.last_gc_check = time::Instant::now(); |
227 | let retained_trees = syntax_tree_stats(self).retained; | 207 | let retained_trees = syntax_tree_stats(self).retained; |
228 | if retained_trees > 100 { | 208 | if retained_trees > 100 { |
229 | log::info!( | 209 | log::info!("automatic garbadge collection, {} retained trees", retained_trees); |
230 | "automatic garbadge collection, {} retained trees", | ||
231 | retained_trees | ||
232 | ); | ||
233 | self.collect_garbage(); | 210 | self.collect_garbage(); |
234 | } | 211 | } |
235 | } | 212 | } |
@@ -238,9 +215,7 @@ impl RootDatabase { | |||
238 | pub(crate) fn collect_garbage(&mut self) { | 215 | pub(crate) fn collect_garbage(&mut self) { |
239 | self.last_gc = time::Instant::now(); | 216 | self.last_gc = time::Instant::now(); |
240 | 217 | ||
241 | let sweep = SweepStrategy::default() | 218 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); |
242 | .discard_values() | ||
243 | .sweep_all_revisions(); | ||
244 | 219 | ||
245 | self.query(ra_db::ParseQuery).sweep(sweep); | 220 | self.query(ra_db::ParseQuery).sweep(sweep); |
246 | 221 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index bad51cc51..a673dbdcf 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -25,9 +25,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | |||
25 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 25 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { |
26 | for receiver in receiver.autoderef(ctx.db) { | 26 | for receiver in receiver.autoderef(ctx.db) { |
27 | match receiver { | 27 | match receiver { |
28 | Ty::Adt { | 28 | Ty::Adt { def_id, ref substs, .. } => { |
29 | def_id, ref substs, .. | ||
30 | } => { | ||
31 | match def_id { | 29 | match def_id { |
32 | AdtDef::Struct(s) => { | 30 | AdtDef::Struct(s) => { |
33 | for field in s.fields(ctx.db) { | 31 | for field in s.fields(ctx.db) { |
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide_api/src/completion/complete_fn_param.rs index 8d4df4ea1..43532226f 100644 --- a/crates/ra_ide_api/src/completion/complete_fn_param.rs +++ b/crates/ra_ide_api/src/completion/complete_fn_param.rs | |||
@@ -43,13 +43,12 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) | |||
43 | node: &'a N, | 43 | node: &'a N, |
44 | params: &mut FxHashMap<String, (u32, &'a ast::Param)>, | 44 | params: &mut FxHashMap<String, (u32, &'a ast::Param)>, |
45 | ) { | 45 | ) { |
46 | node.functions() | 46 | node.functions().filter_map(|it| it.param_list()).flat_map(|it| it.params()).for_each( |
47 | .filter_map(|it| it.param_list()) | 47 | |param| { |
48 | .flat_map(|it| it.params()) | ||
49 | .for_each(|param| { | ||
50 | let text = param.syntax().text().to_string(); | 48 | let text = param.syntax().text().to_string(); |
51 | params.entry(text).or_insert((0, param)).0 += 1; | 49 | params.entry(text).or_insert((0, param)).0 += 1; |
52 | }) | 50 | }, |
51 | ) | ||
53 | } | 52 | } |
54 | } | 53 | } |
55 | 54 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 0b9948d4b..c47a14e9f 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -31,14 +31,10 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
31 | hir::ModuleDef::Enum(e) => { | 31 | hir::ModuleDef::Enum(e) => { |
32 | e.variants(ctx.db).into_iter().for_each(|variant| { | 32 | e.variants(ctx.db).into_iter().for_each(|variant| { |
33 | if let Some(name) = variant.name(ctx.db) { | 33 | if let Some(name) = variant.name(ctx.db) { |
34 | let detail_types = variant | 34 | let detail_types = |
35 | .fields(ctx.db) | 35 | variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); |
36 | .into_iter() | 36 | let detail = |
37 | .map(|field| field.ty(ctx.db)); | 37 | join(detail_types).separator(", ").surround_with("(", ")").to_string(); |
38 | let detail = join(detail_types) | ||
39 | .separator(", ") | ||
40 | .surround_with("(", ")") | ||
41 | .to_string(); | ||
42 | 38 | ||
43 | CompletionItem::new( | 39 | CompletionItem::new( |
44 | CompletionKind::Reference, | 40 | CompletionKind::Reference, |
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index e3a739d6d..10a3c8db7 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs | |||
@@ -17,11 +17,7 @@ use ra_text_edit::TextEditBuilder; | |||
17 | 17 | ||
18 | fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder { | 18 | fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder { |
19 | let replace_range = ctx.source_range(); | 19 | let replace_range = ctx.source_range(); |
20 | let receiver_range = ctx | 20 | let receiver_range = ctx.dot_receiver.expect("no receiver available").syntax().range(); |
21 | .dot_receiver | ||
22 | .expect("no receiver available") | ||
23 | .syntax() | ||
24 | .range(); | ||
25 | let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start()); | 21 | let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start()); |
26 | let mut builder = TextEditBuilder::default(); | 22 | let mut builder = TextEditBuilder::default(); |
27 | builder.delete(delete_range); | 23 | builder.delete(delete_range); |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 8674b1e66..445788407 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -7,13 +7,9 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
7 | let names = ctx.resolver.all_names(); | 7 | let names = ctx.resolver.all_names(); |
8 | 8 | ||
9 | names.into_iter().for_each(|(name, res)| { | 9 | names.into_iter().for_each(|(name, res)| { |
10 | CompletionItem::new( | 10 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) |
11 | CompletionKind::Reference, | 11 | .from_resolution(ctx, &res) |
12 | ctx.source_range(), | 12 | .add_to(acc) |
13 | name.to_string(), | ||
14 | ) | ||
15 | .from_resolution(ctx, &res) | ||
16 | .add_to(acc) | ||
17 | }); | 13 | }); |
18 | } | 14 | } |
19 | 15 | ||
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index 8abab0221..82bd4d606 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -108,12 +108,8 @@ impl<'a> CompletionContext<'a> { | |||
108 | } | 108 | } |
109 | fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { | 109 | fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { |
110 | let name_range = name_ref.syntax().range(); | 110 | let name_range = name_ref.syntax().range(); |
111 | let top_node = name_ref | 111 | let top_node = |
112 | .syntax() | 112 | name_ref.syntax().ancestors().take_while(|it| it.range() == name_range).last().unwrap(); |
113 | .ancestors() | ||
114 | .take_while(|it| it.range() == name_range) | ||
115 | .last() | ||
116 | .unwrap(); | ||
117 | 113 | ||
118 | match top_node.parent().map(|it| it.kind()) { | 114 | match top_node.parent().map(|it| it.kind()) { |
119 | Some(SOURCE_FILE) | Some(ITEM_LIST) => { | 115 | Some(SOURCE_FILE) | Some(ITEM_LIST) => { |
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 92e6e78bf..7b8972af0 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs | |||
@@ -105,10 +105,7 @@ impl CompletionItem { | |||
105 | } | 105 | } |
106 | /// What string is used for filtering. | 106 | /// What string is used for filtering. |
107 | pub fn lookup(&self) -> &str { | 107 | pub fn lookup(&self) -> &str { |
108 | self.lookup | 108 | self.lookup.as_ref().map(|it| it.as_str()).unwrap_or_else(|| self.label()) |
109 | .as_ref() | ||
110 | .map(|it| it.as_str()) | ||
111 | .unwrap_or_else(|| self.label()) | ||
112 | } | 109 | } |
113 | 110 | ||
114 | pub fn insert_text_format(&self) -> InsertTextFormat { | 111 | pub fn insert_text_format(&self) -> InsertTextFormat { |
@@ -214,10 +211,7 @@ impl Builder { | |||
214 | ) -> Builder { | 211 | ) -> Builder { |
215 | use hir::ModuleDef::*; | 212 | use hir::ModuleDef::*; |
216 | 213 | ||
217 | let def = resolution | 214 | let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); |
218 | .as_ref() | ||
219 | .take_types() | ||
220 | .or_else(|| resolution.as_ref().take_values()); | ||
221 | let def = match def { | 215 | let def = match def { |
222 | None => return self, | 216 | None => return self, |
223 | Some(it) => it, | 217 | Some(it) => it, |
@@ -323,10 +317,8 @@ pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind | |||
323 | }; | 317 | }; |
324 | let completions = completions(&analysis.db, position).unwrap(); | 318 | let completions = completions(&analysis.db, position).unwrap(); |
325 | let completion_items: Vec<CompletionItem> = completions.into(); | 319 | let completion_items: Vec<CompletionItem> = completions.into(); |
326 | let mut kind_completions: Vec<CompletionItem> = completion_items | 320 | let mut kind_completions: Vec<CompletionItem> = |
327 | .into_iter() | 321 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); |
328 | .filter(|c| c.completion_kind == kind) | ||
329 | .collect(); | ||
330 | kind_completions.sort_by_key(|c| c.label.clone()); | 322 | kind_completions.sort_by_key(|c| c.label.clone()); |
331 | assert_debug_snapshot_matches!(test_name, kind_completions); | 323 | assert_debug_snapshot_matches!(test_name, kind_completions); |
332 | } | 324 | } |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index a499ac7c6..53d95fb4c 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -21,10 +21,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
21 | let source_root = db.file_source_root(file_id); | 21 | let source_root = db.file_source_root(file_id); |
22 | let diag = match problem { | 22 | let diag = match problem { |
23 | Problem::UnresolvedModule { candidate } => { | 23 | Problem::UnresolvedModule { candidate } => { |
24 | let create_file = FileSystemEdit::CreateFile { | 24 | let create_file = |
25 | source_root, | 25 | FileSystemEdit::CreateFile { source_root, path: candidate.clone() }; |
26 | path: candidate.clone(), | ||
27 | }; | ||
28 | let fix = SourceChange { | 26 | let fix = SourceChange { |
29 | label: "create module".to_string(), | 27 | label: "create module".to_string(), |
30 | source_file_edits: Vec::new(), | 28 | source_file_edits: Vec::new(), |
@@ -44,10 +42,8 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
44 | dst_source_root: source_root, | 42 | dst_source_root: source_root, |
45 | dst_path: move_to.clone(), | 43 | dst_path: move_to.clone(), |
46 | }; | 44 | }; |
47 | let create_file = FileSystemEdit::CreateFile { | 45 | let create_file = |
48 | source_root, | 46 | FileSystemEdit::CreateFile { source_root, path: move_to.join(candidate) }; |
49 | path: move_to.join(candidate), | ||
50 | }; | ||
51 | let fix = SourceChange { | 47 | let fix = SourceChange { |
52 | label: "move file and create module".to_string(), | 48 | label: "move file and create module".to_string(), |
53 | source_file_edits: Vec::new(), | 49 | source_file_edits: Vec::new(), |
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs index f61feaf1b..4051728e1 100644 --- a/crates/ra_ide_api/src/extend_selection.rs +++ b/crates/ra_ide_api/src/extend_selection.rs | |||
@@ -31,9 +31,7 @@ fn extend_selection_in_macro( | |||
31 | } | 31 | } |
32 | 32 | ||
33 | fn find_macro_call(node: &SyntaxNode, range: TextRange) -> Option<&ast::MacroCall> { | 33 | fn find_macro_call(node: &SyntaxNode, range: TextRange) -> Option<&ast::MacroCall> { |
34 | find_covering_node(node, range) | 34 | find_covering_node(node, range).ancestors().find_map(ast::MacroCall::cast) |
35 | .ancestors() | ||
36 | .find_map(ast::MacroCall::cast) | ||
37 | } | 35 | } |
38 | 36 | ||
39 | #[cfg(test)] | 37 | #[cfg(test)] |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 69f2d2bf6..413720960 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -50,18 +50,13 @@ pub(crate) fn reference_definition( | |||
50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) | 50 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax()) |
51 | { | 51 | { |
52 | // Check if it is a method | 52 | // Check if it is a method |
53 | if let Some(method_call) = name_ref | 53 | if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { |
54 | .syntax() | ||
55 | .parent() | ||
56 | .and_then(ast::MethodCallExpr::cast) | ||
57 | { | ||
58 | tested_by!(goto_definition_works_for_methods); | 54 | tested_by!(goto_definition_works_for_methods); |
59 | let infer_result = function.infer(db); | 55 | let infer_result = function.infer(db); |
60 | let syntax_mapping = function.body_syntax_mapping(db); | 56 | let syntax_mapping = function.body_syntax_mapping(db); |
61 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); | 57 | let expr = ast::Expr::cast(method_call.syntax()).unwrap(); |
62 | if let Some(func) = syntax_mapping | 58 | if let Some(func) = |
63 | .node_expr(expr) | 59 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.method_resolution(it)) |
64 | .and_then(|it| infer_result.method_resolution(it)) | ||
65 | { | 60 | { |
66 | return Exact(NavigationTarget::from_function(db, func)); | 61 | return Exact(NavigationTarget::from_function(db, func)); |
67 | }; | 62 | }; |
@@ -72,9 +67,8 @@ pub(crate) fn reference_definition( | |||
72 | let infer_result = function.infer(db); | 67 | let infer_result = function.infer(db); |
73 | let syntax_mapping = function.body_syntax_mapping(db); | 68 | let syntax_mapping = function.body_syntax_mapping(db); |
74 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); | 69 | let expr = ast::Expr::cast(field_expr.syntax()).unwrap(); |
75 | if let Some(field) = syntax_mapping | 70 | if let Some(field) = |
76 | .node_expr(expr) | 71 | syntax_mapping.node_expr(expr).and_then(|it| infer_result.field_resolution(it)) |
77 | .and_then(|it| infer_result.field_resolution(it)) | ||
78 | { | 72 | { |
79 | return Exact(NavigationTarget::from_field(db, field)); | 73 | return Exact(NavigationTarget::from_field(db, field)); |
80 | }; | 74 | }; |
@@ -82,29 +76,19 @@ pub(crate) fn reference_definition( | |||
82 | } | 76 | } |
83 | // Try name resolution | 77 | // Try name resolution |
84 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); | 78 | let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); |
85 | if let Some(path) = name_ref | 79 | if let Some(path) = |
86 | .syntax() | 80 | name_ref.syntax().ancestors().find_map(ast::Path::cast).and_then(hir::Path::from_ast) |
87 | .ancestors() | ||
88 | .find_map(ast::Path::cast) | ||
89 | .and_then(hir::Path::from_ast) | ||
90 | { | 81 | { |
91 | let resolved = resolver.resolve_path(db, &path); | 82 | let resolved = resolver.resolve_path(db, &path); |
92 | match resolved | 83 | match resolved.clone().take_types().or_else(|| resolved.take_values()) { |
93 | .clone() | ||
94 | .take_types() | ||
95 | .or_else(|| resolved.take_values()) | ||
96 | { | ||
97 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), | 84 | Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)), |
98 | Some(Resolution::LocalBinding(pat)) => { | 85 | Some(Resolution::LocalBinding(pat)) => { |
99 | let body = resolver.body().expect("no body for local binding"); | 86 | let body = resolver.body().expect("no body for local binding"); |
100 | let syntax_mapping = body.syntax_mapping(db); | 87 | let syntax_mapping = body.syntax_mapping(db); |
101 | let ptr = syntax_mapping | 88 | let ptr = |
102 | .pat_syntax(pat) | 89 | syntax_mapping.pat_syntax(pat).expect("pattern not found in syntax mapping"); |
103 | .expect("pattern not found in syntax mapping"); | 90 | let name = |
104 | let name = path | 91 | path.as_ident().cloned().expect("local binding from a multi-segment path"); |
105 | .as_ident() | ||
106 | .cloned() | ||
107 | .expect("local binding from a multi-segment path"); | ||
108 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); | 92 | let nav = NavigationTarget::from_scope_entry(file_id, name, ptr); |
109 | return Exact(nav); | 93 | return Exact(nav); |
110 | } | 94 | } |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index f993a461c..60b81567c 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -33,13 +33,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
33 | } | 33 | } |
34 | if range.is_none() { | 34 | if range.is_none() { |
35 | let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| { | 35 | let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| { |
36 | leaf.ancestors() | 36 | leaf.ancestors().find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) |
37 | .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) | ||
38 | })?; | 37 | })?; |
39 | let frange = FileRange { | 38 | let frange = FileRange { file_id: position.file_id, range: node.range() }; |
40 | file_id: position.file_id, | ||
41 | range: node.range(), | ||
42 | }; | ||
43 | res.extend(type_of(db, frange).map(Into::into)); | 39 | res.extend(type_of(db, frange).map(Into::into)); |
44 | range = Some(node.range()); | 40 | range = Some(node.range()); |
45 | }; | 41 | }; |
@@ -126,10 +122,8 @@ impl NavigationTarget { | |||
126 | where | 122 | where |
127 | T: ast::NameOwner + ast::VisibilityOwner, | 123 | T: ast::NameOwner + ast::VisibilityOwner, |
128 | { | 124 | { |
129 | let mut string = node | 125 | let mut string = |
130 | .visibility() | 126 | node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default(); |
131 | .map(|v| format!("{} ", v.syntax().text())) | ||
132 | .unwrap_or_default(); | ||
133 | string.push_str(label); | 127 | string.push_str(label); |
134 | node.name()?.syntax().text().push_to(&mut string); | 128 | node.name()?.syntax().text().push_to(&mut string); |
135 | Some(string) | 129 | Some(string) |
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 4fb054139..444c4aeb2 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs | |||
@@ -83,9 +83,7 @@ mod tests { | |||
83 | 83 | ||
84 | let navs = analysis.goto_implementation(pos).unwrap().unwrap().info; | 84 | let navs = analysis.goto_implementation(pos).unwrap().unwrap().info; |
85 | assert_eq!(navs.len(), expected.len()); | 85 | assert_eq!(navs.len(), expected.len()); |
86 | navs.into_iter() | 86 | navs.into_iter().enumerate().for_each(|(i, nav)| nav.assert_match(expected[i])); |
87 | .enumerate() | ||
88 | .for_each(|(i, nav)| nav.assert_match(expected[i])); | ||
89 | } | 87 | } |
90 | 88 | ||
91 | #[test] | 89 | #[test] |
@@ -109,10 +107,7 @@ mod tests { | |||
109 | impl Foo {} | 107 | impl Foo {} |
110 | impl Foo {} | 108 | impl Foo {} |
111 | ", | 109 | ", |
112 | &[ | 110 | &["impl IMPL_BLOCK FileId(1) [12; 23)", "impl IMPL_BLOCK FileId(1) [24; 35)"], |
113 | "impl IMPL_BLOCK FileId(1) [12; 23)", | ||
114 | "impl IMPL_BLOCK FileId(1) [24; 35)", | ||
115 | ], | ||
116 | ); | 111 | ); |
117 | } | 112 | } |
118 | 113 | ||
@@ -129,10 +124,7 @@ mod tests { | |||
129 | impl super::Foo {} | 124 | impl super::Foo {} |
130 | } | 125 | } |
131 | ", | 126 | ", |
132 | &[ | 127 | &["impl IMPL_BLOCK FileId(1) [24; 42)", "impl IMPL_BLOCK FileId(1) [57; 75)"], |
133 | "impl IMPL_BLOCK FileId(1) [24; 42)", | ||
134 | "impl IMPL_BLOCK FileId(1) [57; 75)", | ||
135 | ], | ||
136 | ); | 128 | ); |
137 | } | 129 | } |
138 | 130 | ||
@@ -149,10 +141,7 @@ mod tests { | |||
149 | //- /b.rs | 141 | //- /b.rs |
150 | impl crate::Foo {} | 142 | impl crate::Foo {} |
151 | ", | 143 | ", |
152 | &[ | 144 | &["impl IMPL_BLOCK FileId(2) [0; 18)", "impl IMPL_BLOCK FileId(3) [0; 18)"], |
153 | "impl IMPL_BLOCK FileId(2) [0; 18)", | ||
154 | "impl IMPL_BLOCK FileId(3) [0; 18)", | ||
155 | ], | ||
156 | ); | 145 | ); |
157 | } | 146 | } |
158 | 147 | ||
@@ -183,10 +172,7 @@ mod tests { | |||
183 | //- /b.rs | 172 | //- /b.rs |
184 | impl crate::T for crate::Foo {} | 173 | impl crate::T for crate::Foo {} |
185 | ", | 174 | ", |
186 | &[ | 175 | &["impl IMPL_BLOCK FileId(2) [0; 31)", "impl IMPL_BLOCK FileId(3) [0; 31)"], |
187 | "impl IMPL_BLOCK FileId(2) [0; 31)", | ||
188 | "impl IMPL_BLOCK FileId(3) [0; 31)", | ||
189 | ], | ||
190 | ); | 176 | ); |
191 | } | 177 | } |
192 | } | 178 | } |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 1f43b7623..2d090d9b4 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -90,15 +90,8 @@ pub struct SourceFileEdit { | |||
90 | 90 | ||
91 | #[derive(Debug)] | 91 | #[derive(Debug)] |
92 | pub enum FileSystemEdit { | 92 | pub enum FileSystemEdit { |
93 | CreateFile { | 93 | CreateFile { source_root: SourceRootId, path: RelativePathBuf }, |
94 | source_root: SourceRootId, | 94 | MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf }, |
95 | path: RelativePathBuf, | ||
96 | }, | ||
97 | MoveFile { | ||
98 | src: FileId, | ||
99 | dst_source_root: SourceRootId, | ||
100 | dst_path: RelativePathBuf, | ||
101 | }, | ||
102 | } | 95 | } |
103 | 96 | ||
104 | #[derive(Debug)] | 97 | #[derive(Debug)] |
@@ -179,9 +172,7 @@ impl AnalysisHost { | |||
179 | /// Returns a snapshot of the current state, which you can query for | 172 | /// Returns a snapshot of the current state, which you can query for |
180 | /// semantic information. | 173 | /// semantic information. |
181 | pub fn analysis(&self) -> Analysis { | 174 | pub fn analysis(&self) -> Analysis { |
182 | Analysis { | 175 | Analysis { db: self.db.snapshot() } |
183 | db: self.db.snapshot(), | ||
184 | } | ||
185 | } | 176 | } |
186 | 177 | ||
187 | /// Applies changes to the current state of the world. If there are | 178 | /// Applies changes to the current state of the world. If there are |
@@ -401,17 +392,12 @@ impl Analysis { | |||
401 | 392 | ||
402 | impl SourceChange { | 393 | impl SourceChange { |
403 | pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange { | 394 | pub(crate) fn from_local_edit(file_id: FileId, edit: LocalEdit) -> SourceChange { |
404 | let file_edit = SourceFileEdit { | 395 | let file_edit = SourceFileEdit { file_id, edit: edit.edit }; |
405 | file_id, | ||
406 | edit: edit.edit, | ||
407 | }; | ||
408 | SourceChange { | 396 | SourceChange { |
409 | label: edit.label, | 397 | label: edit.label, |
410 | source_file_edits: vec![file_edit], | 398 | source_file_edits: vec![file_edit], |
411 | file_system_edits: vec![], | 399 | file_system_edits: vec![], |
412 | cursor_position: edit | 400 | cursor_position: edit.cursor_position.map(|offset| FilePosition { offset, file_id }), |
413 | .cursor_position | ||
414 | .map(|offset| FilePosition { offset, file_id }), | ||
415 | } | 401 | } |
416 | } | 402 | } |
417 | } | 403 | } |
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs index 834b30541..8d8603062 100644 --- a/crates/ra_ide_api/src/mock_analysis.rs +++ b/crates/ra_ide_api/src/mock_analysis.rs | |||
@@ -41,10 +41,7 @@ impl MockAnalysis { | |||
41 | let mut res = MockAnalysis::new(); | 41 | let mut res = MockAnalysis::new(); |
42 | for entry in parse_fixture(fixture) { | 42 | for entry in parse_fixture(fixture) { |
43 | if entry.text.contains(CURSOR_MARKER) { | 43 | if entry.text.contains(CURSOR_MARKER) { |
44 | assert!( | 44 | assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); |
45 | position.is_none(), | ||
46 | "only one marker (<|>) per fixture is allowed" | ||
47 | ); | ||
48 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); | 45 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); |
49 | } else { | 46 | } else { |
50 | res.add_file(&entry.meta, &entry.text); | 47 | res.add_file(&entry.meta, &entry.text); |
@@ -97,9 +94,7 @@ impl MockAnalysis { | |||
97 | let other_crate = crate_graph.add_crate_root(file_id); | 94 | let other_crate = crate_graph.add_crate_root(file_id); |
98 | let crate_name = path.parent().unwrap().file_name().unwrap(); | 95 | let crate_name = path.parent().unwrap().file_name().unwrap(); |
99 | if let Some(root_crate) = root_crate { | 96 | if let Some(root_crate) = root_crate { |
100 | crate_graph | 97 | crate_graph.add_dep(root_crate, crate_name.into(), other_crate).unwrap(); |
101 | .add_dep(root_crate, crate_name.into(), other_crate) | ||
102 | .unwrap(); | ||
103 | } | 98 | } |
104 | } | 99 | } |
105 | change.add_file(source_root, file_id, path, Arc::new(contents)); | 100 | change.add_file(source_root, file_id, path, Arc::new(contents)); |
diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 617908aed..a2e4b6506 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs | |||
@@ -72,10 +72,7 @@ impl NavigationTarget { | |||
72 | 72 | ||
73 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 73 | pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
74 | let (file_id, source) = module.definition_source(db); | 74 | let (file_id, source) = module.definition_source(db); |
75 | let name = module | 75 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
76 | .name(db) | ||
77 | .map(|it| it.to_string().into()) | ||
78 | .unwrap_or_default(); | ||
79 | match source { | 76 | match source { |
80 | ModuleSource::SourceFile(node) => { | 77 | ModuleSource::SourceFile(node) => { |
81 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) | 78 | NavigationTarget::from_syntax(file_id, name, None, node.syntax()) |
@@ -87,10 +84,7 @@ impl NavigationTarget { | |||
87 | } | 84 | } |
88 | 85 | ||
89 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { | 86 | pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { |
90 | let name = module | 87 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
91 | .name(db) | ||
92 | .map(|it| it.to_string().into()) | ||
93 | .unwrap_or_default(); | ||
94 | if let Some((file_id, source)) = module.declaration_source(db) { | 88 | if let Some((file_id, source)) = module.declaration_source(db) { |
95 | return NavigationTarget::from_syntax(file_id, name, None, source.syntax()); | 89 | return NavigationTarget::from_syntax(file_id, name, None, source.syntax()); |
96 | } | 90 | } |
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index b129f3134..2cb1cc9be 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs | |||
@@ -305,9 +305,7 @@ mod tests { | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | } | 307 | } |
308 | let result = text_edit_bulder | 308 | let result = text_edit_bulder.finish().apply(&*analysis.file_text(file_id.unwrap())); |
309 | .finish() | ||
310 | .apply(&*analysis.file_text(file_id.unwrap())); | ||
311 | assert_eq_text!(expected, &*result); | 309 | assert_eq_text!(expected, &*result); |
312 | } | 310 | } |
313 | } | 311 | } |
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs index dc8c40ea6..d64b5a4e0 100644 --- a/crates/ra_ide_api/src/runnables.rs +++ b/crates/ra_ide_api/src/runnables.rs | |||
@@ -23,11 +23,7 @@ pub enum RunnableKind { | |||
23 | 23 | ||
24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 24 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
25 | let source_file = db.parse(file_id); | 25 | let source_file = db.parse(file_id); |
26 | source_file | 26 | source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect() |
27 | .syntax() | ||
28 | .descendants() | ||
29 | .filter_map(|i| runnable(db, file_id, i)) | ||
30 | .collect() | ||
31 | } | 27 | } |
32 | 28 | ||
33 | fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> { | 29 | fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> { |
@@ -45,20 +41,13 @@ fn runnable_fn(fn_def: &ast::FnDef) -> Option<Runnable> { | |||
45 | let kind = if name == "main" { | 41 | let kind = if name == "main" { |
46 | RunnableKind::Bin | 42 | RunnableKind::Bin |
47 | } else if fn_def.has_atom_attr("test") { | 43 | } else if fn_def.has_atom_attr("test") { |
48 | RunnableKind::Test { | 44 | RunnableKind::Test { name: name.to_string() } |
49 | name: name.to_string(), | ||
50 | } | ||
51 | } else if fn_def.has_atom_attr("bench") { | 45 | } else if fn_def.has_atom_attr("bench") { |
52 | RunnableKind::Bench { | 46 | RunnableKind::Bench { name: name.to_string() } |
53 | name: name.to_string(), | ||
54 | } | ||
55 | } else { | 47 | } else { |
56 | return None; | 48 | return None; |
57 | }; | 49 | }; |
58 | Some(Runnable { | 50 | Some(Runnable { range: fn_def.syntax().range(), kind }) |
59 | range: fn_def.syntax().range(), | ||
60 | kind, | ||
61 | }) | ||
62 | } | 51 | } |
63 | 52 | ||
64 | fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Option<Runnable> { | 53 | fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Option<Runnable> { |
@@ -77,16 +66,8 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: &ast::Module) -> Opt | |||
77 | let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?; | 66 | let module = hir::source_binder::module_from_child_node(db, file_id, module.syntax())?; |
78 | 67 | ||
79 | // FIXME: thread cancellation instead of `.ok`ing | 68 | // FIXME: thread cancellation instead of `.ok`ing |
80 | let path = module | 69 | let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); |
81 | .path_to_root(db) | 70 | Some(Runnable { range, kind: RunnableKind::TestMod { path } }) |
82 | .into_iter() | ||
83 | .rev() | ||
84 | .filter_map(|it| it.name(db)) | ||
85 | .join("::"); | ||
86 | Some(Runnable { | ||
87 | range, | ||
88 | kind: RunnableKind::TestMod { path }, | ||
89 | }) | ||
90 | } | 71 | } |
91 | 72 | ||
92 | #[cfg(test)] | 73 | #[cfg(test)] |
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index bd355dd78..e0fc1c123 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs | |||
@@ -22,9 +22,7 @@ pub(crate) fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { | |||
22 | pub(crate) fn status(db: &RootDatabase) -> String { | 22 | pub(crate) fn status(db: &RootDatabase) -> String { |
23 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); | 23 | let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); |
24 | let syntax_tree_stats = syntax_tree_stats(db); | 24 | let syntax_tree_stats = syntax_tree_stats(db); |
25 | let symbols_stats = db | 25 | let symbols_stats = db.query(LibrarySymbolsQuery).entries::<LibrarySymbolsStats>(); |
26 | .query(LibrarySymbolsQuery) | ||
27 | .entries::<LibrarySymbolsStats>(); | ||
28 | let n_defs = { | 26 | let n_defs = { |
29 | let interner: &hir::HirInterner = db.as_ref(); | 27 | let interner: &hir::HirInterner = db.as_ref(); |
30 | interner.len() | 28 | interner.len() |
@@ -75,11 +73,7 @@ pub(crate) struct SyntaxTreeStats { | |||
75 | 73 | ||
76 | impl fmt::Display for SyntaxTreeStats { | 74 | impl fmt::Display for SyntaxTreeStats { |
77 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 75 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
78 | write!( | 76 | write!(fmt, "{} trees, {} ({}) retained", self.total, self.retained, self.retained_size,) |
79 | fmt, | ||
80 | "{} trees, {} ({}) retained", | ||
81 | self.total, self.retained, self.retained_size, | ||
82 | ) | ||
83 | } | 77 | } |
84 | } | 78 | } |
85 | 79 | ||
@@ -144,20 +138,13 @@ impl MemoryStats { | |||
144 | 138 | ||
145 | #[cfg(not(feature = "jemalloc"))] | 139 | #[cfg(not(feature = "jemalloc"))] |
146 | fn current() -> MemoryStats { | 140 | fn current() -> MemoryStats { |
147 | MemoryStats { | 141 | MemoryStats { allocated: Bytes(0), resident: Bytes(0) } |
148 | allocated: Bytes(0), | ||
149 | resident: Bytes(0), | ||
150 | } | ||
151 | } | 142 | } |
152 | } | 143 | } |
153 | 144 | ||
154 | impl fmt::Display for MemoryStats { | 145 | impl fmt::Display for MemoryStats { |
155 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 146 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
156 | write!( | 147 | write!(fmt, "{} allocated {} resident", self.allocated, self.resident,) |
157 | fmt, | ||
158 | "{} allocated {} resident", | ||
159 | self.allocated, self.resident, | ||
160 | ) | ||
161 | } | 148 | } |
162 | } | 149 | } |
163 | 150 | ||
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 3d0b2369e..de0f46134 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -101,10 +101,7 @@ pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> | |||
101 | } | 101 | } |
102 | 102 | ||
103 | let snap = Snap(db.snapshot()); | 103 | let snap = Snap(db.snapshot()); |
104 | files | 104 | files.par_iter().map_with(snap, |db, &file_id| db.0.file_symbols(file_id)).collect() |
105 | .par_iter() | ||
106 | .map_with(snap, |db, &file_id| db.0.file_symbols(file_id)) | ||
107 | .collect() | ||
108 | }; | 105 | }; |
109 | query.search(&buf) | 106 | query.search(&buf) |
110 | } | 107 | } |
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 6c4391e1e..a435fe56e 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs | |||
@@ -9,20 +9,12 @@ use crate::{ | |||
9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 9 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { |
10 | let source_file = db.parse(file_id); | 10 | let source_file = db.parse(file_id); |
11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); | 11 | let mut res = ra_ide_api_light::highlight(source_file.syntax()); |
12 | for macro_call in source_file | 12 | for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) { |
13 | .syntax() | ||
14 | .descendants() | ||
15 | .filter_map(ast::MacroCall::cast) | ||
16 | { | ||
17 | if let Some((off, exp)) = hir::MacroDef::ast_expand(macro_call) { | 13 | if let Some((off, exp)) = hir::MacroDef::ast_expand(macro_call) { |
18 | let mapped_ranges = ra_ide_api_light::highlight(&exp.syntax()) | 14 | let mapped_ranges = |
19 | .into_iter() | 15 | ra_ide_api_light::highlight(&exp.syntax()).into_iter().filter_map(|r| { |
20 | .filter_map(|r| { | ||
21 | let mapped_range = exp.map_range_back(r.range)?; | 16 | let mapped_range = exp.map_range_back(r.range)?; |
22 | let res = HighlightedRange { | 17 | let res = HighlightedRange { range: mapped_range + off, tag: r.tag }; |
23 | range: mapped_range + off, | ||
24 | tag: r.tag, | ||
25 | }; | ||
26 | Some(res) | 18 | Some(res) |
27 | }); | 19 | }); |
28 | res.extend(mapped_ranges); | 20 | res.extend(mapped_ranges); |
diff --git a/crates/ra_ide_api_light/src/diagnostics.rs b/crates/ra_ide_api_light/src/diagnostics.rs index 2b695dfdf..7c383ca2a 100644 --- a/crates/ra_ide_api_light/src/diagnostics.rs +++ b/crates/ra_ide_api_light/src/diagnostics.rs | |||
@@ -72,14 +72,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement( | |||
72 | single_use_tree: &ast::UseTree, | 72 | single_use_tree: &ast::UseTree, |
73 | ) -> Option<TextEdit> { | 73 | ) -> Option<TextEdit> { |
74 | let use_tree_list_node = single_use_tree.syntax().parent()?; | 74 | let use_tree_list_node = single_use_tree.syntax().parent()?; |
75 | if single_use_tree | 75 | if single_use_tree.path()?.segment()?.syntax().first_child()?.kind() == SyntaxKind::SELF_KW { |
76 | .path()? | ||
77 | .segment()? | ||
78 | .syntax() | ||
79 | .first_child()? | ||
80 | .kind() | ||
81 | == SyntaxKind::SELF_KW | ||
82 | { | ||
83 | let start = use_tree_list_node.prev_sibling()?.range().start(); | 76 | let start = use_tree_list_node.prev_sibling()?.range().start(); |
84 | let end = use_tree_list_node.range().end(); | 77 | let end = use_tree_list_node.range().end(); |
85 | let range = TextRange::from_to(start, end); | 78 | let range = TextRange::from_to(start, end); |
@@ -145,9 +138,8 @@ mod tests { | |||
145 | for node in file.syntax().descendants() { | 138 | for node in file.syntax().descendants() { |
146 | func(&mut diagnostics, node); | 139 | func(&mut diagnostics, node); |
147 | } | 140 | } |
148 | let diagnostic = diagnostics | 141 | let diagnostic = |
149 | .pop() | 142 | diagnostics.pop().unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before)); |
150 | .unwrap_or_else(|| panic!("no diagnostics for:\n{}\n", before)); | ||
151 | let fix = diagnostic.fix.unwrap(); | 143 | let fix = diagnostic.fix.unwrap(); |
152 | let actual = fix.edit.apply(&before); | 144 | let actual = fix.edit.apply(&before); |
153 | assert_eq_text!(after, &actual); | 145 | assert_eq_text!(after, &actual); |
@@ -162,21 +154,9 @@ mod tests { | |||
162 | ", | 154 | ", |
163 | check_unnecessary_braces_in_use_statement, | 155 | check_unnecessary_braces_in_use_statement, |
164 | ); | 156 | ); |
165 | check_apply( | 157 | check_apply("use {b};", "use b;", check_unnecessary_braces_in_use_statement); |
166 | "use {b};", | 158 | check_apply("use a::{c};", "use a::c;", check_unnecessary_braces_in_use_statement); |
167 | "use b;", | 159 | check_apply("use a::{self};", "use a;", check_unnecessary_braces_in_use_statement); |
168 | check_unnecessary_braces_in_use_statement, | ||
169 | ); | ||
170 | check_apply( | ||
171 | "use a::{c};", | ||
172 | "use a::c;", | ||
173 | check_unnecessary_braces_in_use_statement, | ||
174 | ); | ||
175 | check_apply( | ||
176 | "use a::{self};", | ||
177 | "use a;", | ||
178 | check_unnecessary_braces_in_use_statement, | ||
179 | ); | ||
180 | check_apply( | 160 | check_apply( |
181 | "use a::{c, d::{e}};", | 161 | "use a::{c, d::{e}};", |
182 | "use a::{c, d::e};", | 162 | "use a::{c, d::e};", |
diff --git a/crates/ra_ide_api_light/src/extend_selection.rs b/crates/ra_ide_api_light/src/extend_selection.rs index f396dfe3f..28d62f290 100644 --- a/crates/ra_ide_api_light/src/extend_selection.rs +++ b/crates/ra_ide_api_light/src/extend_selection.rs | |||
@@ -43,11 +43,7 @@ pub fn extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
43 | let node = find_covering_node(root, range); | 43 | let node = find_covering_node(root, range); |
44 | 44 | ||
45 | // Using shallowest node with same range allows us to traverse siblings. | 45 | // Using shallowest node with same range allows us to traverse siblings. |
46 | let node = node | 46 | let node = node.ancestors().take_while(|n| n.range() == node.range()).last().unwrap(); |
47 | .ancestors() | ||
48 | .take_while(|n| n.range() == node.range()) | ||
49 | .last() | ||
50 | .unwrap(); | ||
51 | 47 | ||
52 | if range == node.range() { | 48 | if range == node.range() { |
53 | if string_kinds.contains(&node.kind()) { | 49 | if string_kinds.contains(&node.kind()) { |
@@ -145,10 +141,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
145 | } | 141 | } |
146 | 142 | ||
147 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { | 143 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { |
148 | return Some(TextRange::from_to( | 144 | return Some(TextRange::from_to(comma_node.range().start(), node.range().end())); |
149 | comma_node.range().start(), | ||
150 | node.range().end(), | ||
151 | )); | ||
152 | } | 145 | } |
153 | 146 | ||
154 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { | 147 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { |
@@ -160,10 +153,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
160 | .filter(|node| is_single_line_ws(node)) | 153 | .filter(|node| is_single_line_ws(node)) |
161 | .unwrap_or(comma_node); | 154 | .unwrap_or(comma_node); |
162 | 155 | ||
163 | return Some(TextRange::from_to( | 156 | return Some(TextRange::from_to(node.range().start(), final_node.range().end())); |
164 | node.range().start(), | ||
165 | final_node.range().end(), | ||
166 | )); | ||
167 | } | 157 | } |
168 | 158 | ||
169 | return None; | 159 | return None; |
@@ -217,36 +207,15 @@ mod tests { | |||
217 | #[test] | 207 | #[test] |
218 | fn test_extend_selection_list() { | 208 | fn test_extend_selection_list() { |
219 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); | 209 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); |
220 | do_check( | 210 | do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); |
221 | r#"fn foo(<|>x: i32, y: i32) {}"#, | 211 | do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,"]); |
222 | &["x", "x: i32", "x: i32, "], | 212 | do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); |
223 | ); | 213 | do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", ", y: i32"]); |
224 | do_check( | 214 | do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); |
225 | r#"fn foo(<|>x: i32,y: i32) {}"#, | ||
226 | &["x", "x: i32", "x: i32,"], | ||
227 | ); | ||
228 | do_check( | ||
229 | r#"fn foo(x: i32, <|>y: i32) {}"#, | ||
230 | &["y", "y: i32", ", y: i32"], | ||
231 | ); | ||
232 | do_check( | ||
233 | r#"fn foo(x: i32, <|>y: i32, ) {}"#, | ||
234 | &["y", "y: i32", ", y: i32"], | ||
235 | ); | ||
236 | do_check( | ||
237 | r#"fn foo(x: i32,<|>y: i32) {}"#, | ||
238 | &["y", "y: i32", ",y: i32"], | ||
239 | ); | ||
240 | 215 | ||
241 | do_check( | 216 | do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); |
242 | r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, | ||
243 | &["22", "22 , "], | ||
244 | ); | ||
245 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); | 217 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); |
246 | do_check( | 218 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", ", 33"]); |
247 | r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, | ||
248 | &["33", ", 33"], | ||
249 | ); | ||
250 | 219 | ||
251 | do_check( | 220 | do_check( |
252 | r#" | 221 | r#" |
@@ -292,11 +261,7 @@ struct B { | |||
292 | <|> | 261 | <|> |
293 | } | 262 | } |
294 | "#, | 263 | "#, |
295 | &[ | 264 | &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"], |
296 | "\n \n", | ||
297 | "{\n \n}", | ||
298 | "/// bla\n/// bla\nstruct B {\n \n}", | ||
299 | ], | ||
300 | ) | 265 | ) |
301 | } | 266 | } |
302 | 267 | ||
diff --git a/crates/ra_ide_api_light/src/folding_ranges.rs b/crates/ra_ide_api_light/src/folding_ranges.rs index c73637323..357a7dee1 100644 --- a/crates/ra_ide_api_light/src/folding_ranges.rs +++ b/crates/ra_ide_api_light/src/folding_ranges.rs | |||
@@ -30,30 +30,21 @@ pub fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
30 | // Fold items that span multiple lines | 30 | // Fold items that span multiple lines |
31 | if let Some(kind) = fold_kind(node.kind()) { | 31 | if let Some(kind) = fold_kind(node.kind()) { |
32 | if node.text().contains('\n') { | 32 | if node.text().contains('\n') { |
33 | res.push(Fold { | 33 | res.push(Fold { range: node.range(), kind }); |
34 | range: node.range(), | ||
35 | kind, | ||
36 | }); | ||
37 | } | 34 | } |
38 | } | 35 | } |
39 | 36 | ||
40 | // Fold groups of comments | 37 | // Fold groups of comments |
41 | if node.kind() == COMMENT && !visited_comments.contains(&node) { | 38 | if node.kind() == COMMENT && !visited_comments.contains(&node) { |
42 | if let Some(range) = contiguous_range_for_comment(node, &mut visited_comments) { | 39 | if let Some(range) = contiguous_range_for_comment(node, &mut visited_comments) { |
43 | res.push(Fold { | 40 | res.push(Fold { range, kind: FoldKind::Comment }) |
44 | range, | ||
45 | kind: FoldKind::Comment, | ||
46 | }) | ||
47 | } | 41 | } |
48 | } | 42 | } |
49 | 43 | ||
50 | // Fold groups of imports | 44 | // Fold groups of imports |
51 | if node.kind() == USE_ITEM && !visited_imports.contains(&node) { | 45 | if node.kind() == USE_ITEM && !visited_imports.contains(&node) { |
52 | if let Some(range) = contiguous_range_for_group(node, &mut visited_imports) { | 46 | if let Some(range) = contiguous_range_for_group(node, &mut visited_imports) { |
53 | res.push(Fold { | 47 | res.push(Fold { range, kind: FoldKind::Imports }) |
54 | range, | ||
55 | kind: FoldKind::Imports, | ||
56 | }) | ||
57 | } | 48 | } |
58 | } | 49 | } |
59 | 50 | ||
@@ -62,10 +53,7 @@ pub fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
62 | if let Some(range) = | 53 | if let Some(range) = |
63 | contiguous_range_for_group_unless(node, has_visibility, &mut visited_mods) | 54 | contiguous_range_for_group_unless(node, has_visibility, &mut visited_mods) |
64 | { | 55 | { |
65 | res.push(Fold { | 56 | res.push(Fold { range, kind: FoldKind::Mods }) |
66 | range, | ||
67 | kind: FoldKind::Mods, | ||
68 | }) | ||
69 | } | 57 | } |
70 | } | 58 | } |
71 | } | 59 | } |
@@ -84,9 +72,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> { | |||
84 | } | 72 | } |
85 | 73 | ||
86 | fn has_visibility(node: &SyntaxNode) -> bool { | 74 | fn has_visibility(node: &SyntaxNode) -> bool { |
87 | ast::Module::cast(node) | 75 | ast::Module::cast(node).and_then(|m| m.visibility()).is_some() |
88 | .and_then(|m| m.visibility()) | ||
89 | .is_some() | ||
90 | } | 76 | } |
91 | 77 | ||
92 | fn contiguous_range_for_group<'a>( | 78 | fn contiguous_range_for_group<'a>( |
@@ -125,10 +111,7 @@ fn contiguous_range_for_group_unless<'a>( | |||
125 | } | 111 | } |
126 | 112 | ||
127 | if first != last { | 113 | if first != last { |
128 | Some(TextRange::from_to( | 114 | Some(TextRange::from_to(first.range().start(), last.range().end())) |
129 | first.range().start(), | ||
130 | last.range().end(), | ||
131 | )) | ||
132 | } else { | 115 | } else { |
133 | // The group consists of only one element, therefore it cannot be folded | 116 | // The group consists of only one element, therefore it cannot be folded |
134 | None | 117 | None |
@@ -169,10 +152,7 @@ fn contiguous_range_for_comment<'a>( | |||
169 | } | 152 | } |
170 | 153 | ||
171 | if first != last { | 154 | if first != last { |
172 | Some(TextRange::from_to( | 155 | Some(TextRange::from_to(first.range().start(), last.range().end())) |
173 | first.range().start(), | ||
174 | last.range().end(), | ||
175 | )) | ||
176 | } else { | 156 | } else { |
177 | // The group consists of only one element, therefore it cannot be folded | 157 | // The group consists of only one element, therefore it cannot be folded |
178 | None | 158 | None |
@@ -199,10 +179,8 @@ mod tests { | |||
199 | fold_kinds.len(), | 179 | fold_kinds.len(), |
200 | "The amount of fold kinds is different than the expected amount" | 180 | "The amount of fold kinds is different than the expected amount" |
201 | ); | 181 | ); |
202 | for ((fold, range), fold_kind) in folds | 182 | for ((fold, range), fold_kind) in |
203 | .into_iter() | 183 | folds.into_iter().zip(ranges.into_iter()).zip(fold_kinds.into_iter()) |
204 | .zip(ranges.into_iter()) | ||
205 | .zip(fold_kinds.into_iter()) | ||
206 | { | 184 | { |
207 | assert_eq!(fold.range.start(), range.start()); | 185 | assert_eq!(fold.range.start(), range.start()); |
208 | assert_eq!(fold.range.end(), range.end()); | 186 | assert_eq!(fold.range.end(), range.end()); |
@@ -280,12 +258,7 @@ mod with_attribute_next;</fold> | |||
280 | fn main() <fold>{ | 258 | fn main() <fold>{ |
281 | }</fold>"#; | 259 | }</fold>"#; |
282 | 260 | ||
283 | let folds = &[ | 261 | let folds = &[FoldKind::Mods, FoldKind::Mods, FoldKind::Mods, FoldKind::Block]; |
284 | FoldKind::Mods, | ||
285 | FoldKind::Mods, | ||
286 | FoldKind::Mods, | ||
287 | FoldKind::Block, | ||
288 | ]; | ||
289 | do_check(text, folds); | 262 | do_check(text, folds); |
290 | } | 263 | } |
291 | 264 | ||
diff --git a/crates/ra_ide_api_light/src/formatting.rs b/crates/ra_ide_api_light/src/formatting.rs index 46ffa7d96..8bc03f974 100644 --- a/crates/ra_ide_api_light/src/formatting.rs +++ b/crates/ra_ide_api_light/src/formatting.rs | |||
@@ -32,10 +32,7 @@ fn prev_leaves(node: &SyntaxNode) -> impl Iterator<Item = &SyntaxNode> { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> { | 34 | fn prev_leaf(node: &SyntaxNode) -> Option<&SyntaxNode> { |
35 | generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| { | 35 | generate(node.ancestors().find_map(SyntaxNode::prev_sibling), |it| it.last_child()).last() |
36 | it.last_child() | ||
37 | }) | ||
38 | .last() | ||
39 | } | 36 | } |
40 | 37 | ||
41 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { | 38 | pub fn extract_trivial_expression(block: &ast::Block) -> Option<&ast::Expr> { |
diff --git a/crates/ra_ide_api_light/src/join_lines.rs b/crates/ra_ide_api_light/src/join_lines.rs index ab7c5b4b5..03770c52e 100644 --- a/crates/ra_ide_api_light/src/join_lines.rs +++ b/crates/ra_ide_api_light/src/join_lines.rs | |||
@@ -50,11 +50,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> LocalEdit { | |||
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | LocalEdit { | 53 | LocalEdit { label: "join lines".to_string(), edit: edit.finish(), cursor_position: None } |
54 | label: "join lines".to_string(), | ||
55 | edit: edit.finish(), | ||
56 | cursor_position: None, | ||
57 | } | ||
58 | } | 54 | } |
59 | 55 | ||
60 | fn remove_newline( | 56 | fn remove_newline( |
@@ -71,10 +67,7 @@ fn remove_newline( | |||
71 | )]; | 67 | )]; |
72 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); | 68 | let spaces = suff.bytes().take_while(|&b| b == b' ').count(); |
73 | 69 | ||
74 | edit.replace( | 70 | edit.replace(TextRange::offset_len(offset, ((spaces + 1) as u32).into()), " ".to_string()); |
75 | TextRange::offset_len(offset, ((spaces + 1) as u32).into()), | ||
76 | " ".to_string(), | ||
77 | ); | ||
78 | return; | 71 | return; |
79 | } | 72 | } |
80 | 73 | ||
@@ -109,11 +102,7 @@ fn remove_newline( | |||
109 | edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); | 102 | edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); |
110 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { | 103 | } else if prev.kind() == COMMA && next.kind() == R_CURLY { |
111 | // Removes: comma, newline (incl. surrounding whitespace) | 104 | // Removes: comma, newline (incl. surrounding whitespace) |
112 | let space = if let Some(left) = prev.prev_sibling() { | 105 | let space = if let Some(left) = prev.prev_sibling() { compute_ws(left, next) } else { " " }; |
113 | compute_ws(left, next) | ||
114 | } else { | ||
115 | " " | ||
116 | }; | ||
117 | edit.replace( | 106 | edit.replace( |
118 | TextRange::from_to(prev.range().start(), node.range().end()), | 107 | TextRange::from_to(prev.range().start(), node.range().end()), |
119 | space.to_string(), | 108 | space.to_string(), |
@@ -134,20 +123,14 @@ fn join_single_expr_block(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Opti | |||
134 | let block = ast::Block::cast(node.parent()?)?; | 123 | let block = ast::Block::cast(node.parent()?)?; |
135 | let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; | 124 | let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; |
136 | let expr = extract_trivial_expression(block)?; | 125 | let expr = extract_trivial_expression(block)?; |
137 | edit.replace( | 126 | edit.replace(block_expr.syntax().range(), expr.syntax().text().to_string()); |
138 | block_expr.syntax().range(), | ||
139 | expr.syntax().text().to_string(), | ||
140 | ); | ||
141 | Some(()) | 127 | Some(()) |
142 | } | 128 | } |
143 | 129 | ||
144 | fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> { | 130 | fn join_single_use_tree(edit: &mut TextEditBuilder, node: &SyntaxNode) -> Option<()> { |
145 | let use_tree_list = ast::UseTreeList::cast(node.parent()?)?; | 131 | let use_tree_list = ast::UseTreeList::cast(node.parent()?)?; |
146 | let (tree,) = use_tree_list.use_trees().collect_tuple()?; | 132 | let (tree,) = use_tree_list.use_trees().collect_tuple()?; |
147 | edit.replace( | 133 | edit.replace(use_tree_list.syntax().range(), tree.syntax().text().to_string()); |
148 | use_tree_list.syntax().range(), | ||
149 | tree.syntax().text().to_string(), | ||
150 | ); | ||
151 | Some(()) | 134 | Some(()) |
152 | } | 135 | } |
153 | 136 | ||
diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs index 17044270c..f3078f51e 100644 --- a/crates/ra_ide_api_light/src/lib.rs +++ b/crates/ra_ide_api_light/src/lib.rs | |||
@@ -63,9 +63,8 @@ pub struct Diagnostic { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | 65 | pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { |
66 | const BRACES: &[SyntaxKind] = &[ | 66 | const BRACES: &[SyntaxKind] = |
67 | L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE, | 67 | &[L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE]; |
68 | ]; | ||
69 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) | 68 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) |
70 | .filter_map(|node| { | 69 | .filter_map(|node| { |
71 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; | 70 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; |
@@ -74,9 +73,7 @@ pub fn matching_brace(file: &SourceFile, offset: TextUnit) -> Option<TextUnit> { | |||
74 | .next()?; | 73 | .next()?; |
75 | let parent = brace_node.parent()?; | 74 | let parent = brace_node.parent()?; |
76 | let matching_kind = BRACES[brace_idx ^ 1]; | 75 | let matching_kind = BRACES[brace_idx ^ 1]; |
77 | let matching_node = parent | 76 | let matching_node = parent.children().find(|node| node.kind() == matching_kind)?; |
78 | .children() | ||
79 | .find(|node| node.kind() == matching_kind)?; | ||
80 | Some(matching_node.range().start()) | 77 | Some(matching_node.range().start()) |
81 | } | 78 | } |
82 | 79 | ||
@@ -122,10 +119,7 @@ pub fn highlight(root: &SyntaxNode) -> Vec<HighlightedRange> { | |||
122 | continue; | 119 | continue; |
123 | } | 120 | } |
124 | }; | 121 | }; |
125 | res.push(HighlightedRange { | 122 | res.push(HighlightedRange { range: node.range(), tag }) |
126 | range: node.range(), | ||
127 | tag, | ||
128 | }) | ||
129 | } | 123 | } |
130 | res | 124 | res |
131 | } | 125 | } |
diff --git a/crates/ra_ide_api_light/src/line_index.rs b/crates/ra_ide_api_light/src/line_index.rs index 131737743..bf004c33a 100644 --- a/crates/ra_ide_api_light/src/line_index.rs +++ b/crates/ra_ide_api_light/src/line_index.rs | |||
@@ -54,10 +54,7 @@ impl LineIndex { | |||
54 | 54 | ||
55 | let char_len = TextUnit::of_char(c); | 55 | let char_len = TextUnit::of_char(c); |
56 | if char_len.to_usize() > 1 { | 56 | if char_len.to_usize() > 1 { |
57 | utf16_chars.push(Utf16Char { | 57 | utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len }); |
58 | start: curr_col, | ||
59 | end: curr_col + char_len, | ||
60 | }); | ||
61 | } | 58 | } |
62 | 59 | ||
63 | curr_col += char_len; | 60 | curr_col += char_len; |
@@ -68,10 +65,7 @@ impl LineIndex { | |||
68 | utf16_lines.insert(line, utf16_chars); | 65 | utf16_lines.insert(line, utf16_chars); |
69 | } | 66 | } |
70 | 67 | ||
71 | LineIndex { | 68 | LineIndex { newlines, utf16_lines } |
72 | newlines, | ||
73 | utf16_lines, | ||
74 | } | ||
75 | } | 69 | } |
76 | 70 | ||
77 | pub fn line_col(&self, offset: TextUnit) -> LineCol { | 71 | pub fn line_col(&self, offset: TextUnit) -> LineCol { |
@@ -79,10 +73,7 @@ impl LineIndex { | |||
79 | let line_start_offset = self.newlines[line]; | 73 | let line_start_offset = self.newlines[line]; |
80 | let col = offset - line_start_offset; | 74 | let col = offset - line_start_offset; |
81 | 75 | ||
82 | LineCol { | 76 | LineCol { line: line as u32, col_utf16: self.utf8_to_utf16_col(line as u32, col) as u32 } |
83 | line: line as u32, | ||
84 | col_utf16: self.utf8_to_utf16_col(line as u32, col) as u32, | ||
85 | } | ||
86 | } | 77 | } |
87 | 78 | ||
88 | pub fn offset(&self, line_col: LineCol) -> TextUnit { | 79 | pub fn offset(&self, line_col: LineCol) -> TextUnit { |
@@ -131,10 +122,7 @@ impl LineIndex { | |||
131 | #[cfg(test)] | 122 | #[cfg(test)] |
132 | /// Simple reference implementation to use in proptests | 123 | /// Simple reference implementation to use in proptests |
133 | pub fn to_line_col(text: &str, offset: TextUnit) -> LineCol { | 124 | pub fn to_line_col(text: &str, offset: TextUnit) -> LineCol { |
134 | let mut res = LineCol { | 125 | let mut res = LineCol { line: 0, col_utf16: 0 }; |
135 | line: 0, | ||
136 | col_utf16: 0, | ||
137 | }; | ||
138 | for (i, c) in text.char_indices() { | 126 | for (i, c) in text.char_indices() { |
139 | if i + c.len_utf8() > offset.to_usize() { | 127 | if i + c.len_utf8() > offset.to_usize() { |
140 | // if it's an invalid offset, inside a multibyte char | 128 | // if it's an invalid offset, inside a multibyte char |
@@ -161,120 +149,31 @@ mod test_line_index { | |||
161 | fn test_line_index() { | 149 | fn test_line_index() { |
162 | let text = "hello\nworld"; | 150 | let text = "hello\nworld"; |
163 | let index = LineIndex::new(text); | 151 | let index = LineIndex::new(text); |
164 | assert_eq!( | 152 | assert_eq!(index.line_col(0.into()), LineCol { line: 0, col_utf16: 0 }); |
165 | index.line_col(0.into()), | 153 | assert_eq!(index.line_col(1.into()), LineCol { line: 0, col_utf16: 1 }); |
166 | LineCol { | 154 | assert_eq!(index.line_col(5.into()), LineCol { line: 0, col_utf16: 5 }); |
167 | line: 0, | 155 | assert_eq!(index.line_col(6.into()), LineCol { line: 1, col_utf16: 0 }); |
168 | col_utf16: 0 | 156 | assert_eq!(index.line_col(7.into()), LineCol { line: 1, col_utf16: 1 }); |
169 | } | 157 | assert_eq!(index.line_col(8.into()), LineCol { line: 1, col_utf16: 2 }); |
170 | ); | 158 | assert_eq!(index.line_col(10.into()), LineCol { line: 1, col_utf16: 4 }); |
171 | assert_eq!( | 159 | assert_eq!(index.line_col(11.into()), LineCol { line: 1, col_utf16: 5 }); |
172 | index.line_col(1.into()), | 160 | assert_eq!(index.line_col(12.into()), LineCol { line: 1, col_utf16: 6 }); |
173 | LineCol { | ||
174 | line: 0, | ||
175 | col_utf16: 1 | ||
176 | } | ||
177 | ); | ||
178 | assert_eq!( | ||
179 | index.line_col(5.into()), | ||
180 | LineCol { | ||
181 | line: 0, | ||
182 | col_utf16: 5 | ||
183 | } | ||
184 | ); | ||
185 | assert_eq!( | ||
186 | index.line_col(6.into()), | ||
187 | LineCol { | ||
188 | line: 1, | ||
189 | col_utf16: 0 | ||
190 | } | ||
191 | ); | ||
192 | assert_eq!( | ||
193 | index.line_col(7.into()), | ||
194 | LineCol { | ||
195 | line: 1, | ||
196 | col_utf16: 1 | ||
197 | } | ||
198 | ); | ||
199 | assert_eq!( | ||
200 | index.line_col(8.into()), | ||
201 | LineCol { | ||
202 | line: 1, | ||
203 | col_utf16: 2 | ||
204 | } | ||
205 | ); | ||
206 | assert_eq!( | ||
207 | index.line_col(10.into()), | ||
208 | LineCol { | ||
209 | line: 1, | ||
210 | col_utf16: 4 | ||
211 | } | ||
212 | ); | ||
213 | assert_eq!( | ||
214 | index.line_col(11.into()), | ||
215 | LineCol { | ||
216 | line: 1, | ||
217 | col_utf16: 5 | ||
218 | } | ||
219 | ); | ||
220 | assert_eq!( | ||
221 | index.line_col(12.into()), | ||
222 | LineCol { | ||
223 | line: 1, | ||
224 | col_utf16: 6 | ||
225 | } | ||
226 | ); | ||
227 | 161 | ||
228 | let text = "\nhello\nworld"; | 162 | let text = "\nhello\nworld"; |
229 | let index = LineIndex::new(text); | 163 | let index = LineIndex::new(text); |
230 | assert_eq!( | 164 | assert_eq!(index.line_col(0.into()), LineCol { line: 0, col_utf16: 0 }); |
231 | index.line_col(0.into()), | 165 | assert_eq!(index.line_col(1.into()), LineCol { line: 1, col_utf16: 0 }); |
232 | LineCol { | 166 | assert_eq!(index.line_col(2.into()), LineCol { line: 1, col_utf16: 1 }); |
233 | line: 0, | 167 | assert_eq!(index.line_col(6.into()), LineCol { line: 1, col_utf16: 5 }); |
234 | col_utf16: 0 | 168 | assert_eq!(index.line_col(7.into()), LineCol { line: 2, col_utf16: 0 }); |
235 | } | ||
236 | ); | ||
237 | assert_eq!( | ||
238 | index.line_col(1.into()), | ||
239 | LineCol { | ||
240 | line: 1, | ||
241 | col_utf16: 0 | ||
242 | } | ||
243 | ); | ||
244 | assert_eq!( | ||
245 | index.line_col(2.into()), | ||
246 | LineCol { | ||
247 | line: 1, | ||
248 | col_utf16: 1 | ||
249 | } | ||
250 | ); | ||
251 | assert_eq!( | ||
252 | index.line_col(6.into()), | ||
253 | LineCol { | ||
254 | line: 1, | ||
255 | col_utf16: 5 | ||
256 | } | ||
257 | ); | ||
258 | assert_eq!( | ||
259 | index.line_col(7.into()), | ||
260 | LineCol { | ||
261 | line: 2, | ||
262 | col_utf16: 0 | ||
263 | } | ||
264 | ); | ||
265 | } | 169 | } |
266 | 170 | ||
267 | fn arb_text_with_offset() -> BoxedStrategy<(TextUnit, String)> { | 171 | fn arb_text_with_offset() -> BoxedStrategy<(TextUnit, String)> { |
268 | arb_text() | 172 | arb_text().prop_flat_map(|text| (arb_offset(&text), Just(text))).boxed() |
269 | .prop_flat_map(|text| (arb_offset(&text), Just(text))) | ||
270 | .boxed() | ||
271 | } | 173 | } |
272 | 174 | ||
273 | fn to_line_col(text: &str, offset: TextUnit) -> LineCol { | 175 | fn to_line_col(text: &str, offset: TextUnit) -> LineCol { |
274 | let mut res = LineCol { | 176 | let mut res = LineCol { line: 0, col_utf16: 0 }; |
275 | line: 0, | ||
276 | col_utf16: 0, | ||
277 | }; | ||
278 | for (i, c) in text.char_indices() { | 177 | for (i, c) in text.char_indices() { |
279 | if i + c.len_utf8() > offset.to_usize() { | 178 | if i + c.len_utf8() > offset.to_usize() { |
280 | // if it's an invalid offset, inside a multibyte char | 179 | // if it's an invalid offset, inside a multibyte char |
@@ -333,13 +232,7 @@ const C: char = 'メ'; | |||
333 | 232 | ||
334 | assert_eq!(col_index.utf16_lines.len(), 1); | 233 | assert_eq!(col_index.utf16_lines.len(), 1); |
335 | assert_eq!(col_index.utf16_lines[&1].len(), 1); | 234 | assert_eq!(col_index.utf16_lines[&1].len(), 1); |
336 | assert_eq!( | 235 | assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() }); |
337 | col_index.utf16_lines[&1][0], | ||
338 | Utf16Char { | ||
339 | start: 17.into(), | ||
340 | end: 20.into() | ||
341 | } | ||
342 | ); | ||
343 | 236 | ||
344 | // UTF-8 to UTF-16, no changes | 237 | // UTF-8 to UTF-16, no changes |
345 | assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15); | 238 | assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15); |
@@ -364,20 +257,8 @@ const C: char = \"メ メ\"; | |||
364 | 257 | ||
365 | assert_eq!(col_index.utf16_lines.len(), 1); | 258 | assert_eq!(col_index.utf16_lines.len(), 1); |
366 | assert_eq!(col_index.utf16_lines[&1].len(), 2); | 259 | assert_eq!(col_index.utf16_lines[&1].len(), 2); |
367 | assert_eq!( | 260 | assert_eq!(col_index.utf16_lines[&1][0], Utf16Char { start: 17.into(), end: 20.into() }); |
368 | col_index.utf16_lines[&1][0], | 261 | assert_eq!(col_index.utf16_lines[&1][1], Utf16Char { start: 21.into(), end: 24.into() }); |
369 | Utf16Char { | ||
370 | start: 17.into(), | ||
371 | end: 20.into() | ||
372 | } | ||
373 | ); | ||
374 | assert_eq!( | ||
375 | col_index.utf16_lines[&1][1], | ||
376 | Utf16Char { | ||
377 | start: 21.into(), | ||
378 | end: 24.into() | ||
379 | } | ||
380 | ); | ||
381 | 262 | ||
382 | // UTF-8 to UTF-16 | 263 | // UTF-8 to UTF-16 |
383 | assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15); | 264 | assert_eq!(col_index.utf8_to_utf16_col(1, 15.into()), 15); |
diff --git a/crates/ra_ide_api_light/src/line_index_utils.rs b/crates/ra_ide_api_light/src/line_index_utils.rs index 5d9ab6fd2..799a920ad 100644 --- a/crates/ra_ide_api_light/src/line_index_utils.rs +++ b/crates/ra_ide_api_light/src/line_index_utils.rs | |||
@@ -17,11 +17,7 @@ struct LineIndexStepIter<'a> { | |||
17 | 17 | ||
18 | impl<'a> LineIndexStepIter<'a> { | 18 | impl<'a> LineIndexStepIter<'a> { |
19 | fn from(line_index: &LineIndex) -> LineIndexStepIter { | 19 | fn from(line_index: &LineIndex) -> LineIndexStepIter { |
20 | let mut x = LineIndexStepIter { | 20 | let mut x = LineIndexStepIter { line_index, next_newline_idx: 0, utf16_chars: None }; |
21 | line_index, | ||
22 | next_newline_idx: 0, | ||
23 | utf16_chars: None, | ||
24 | }; | ||
25 | // skip first newline since it's not real | 21 | // skip first newline since it's not real |
26 | x.next(); | 22 | x.next(); |
27 | x | 23 | x |
@@ -35,10 +31,7 @@ impl<'a> Iterator for LineIndexStepIter<'a> { | |||
35 | .as_mut() | 31 | .as_mut() |
36 | .and_then(|(newline, x)| { | 32 | .and_then(|(newline, x)| { |
37 | let x = x.next()?; | 33 | let x = x.next()?; |
38 | Some(Step::Utf16Char(TextRange::from_to( | 34 | Some(Step::Utf16Char(TextRange::from_to(*newline + x.start, *newline + x.end))) |
39 | *newline + x.start, | ||
40 | *newline + x.end, | ||
41 | ))) | ||
42 | }) | 35 | }) |
43 | .or_else(|| { | 36 | .or_else(|| { |
44 | let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?; | 37 | let next_newline = *self.line_index.newlines.get(self.next_newline_idx)?; |
@@ -113,11 +106,7 @@ struct Edits<'a> { | |||
113 | 106 | ||
114 | impl<'a> Edits<'a> { | 107 | impl<'a> Edits<'a> { |
115 | fn from_text_edit(text_edit: &'a TextEdit) -> Edits<'a> { | 108 | fn from_text_edit(text_edit: &'a TextEdit) -> Edits<'a> { |
116 | let mut x = Edits { | 109 | let mut x = Edits { edits: text_edit.as_atoms(), current: None, acc_diff: 0 }; |
117 | edits: text_edit.as_atoms(), | ||
118 | current: None, | ||
119 | acc_diff: 0, | ||
120 | }; | ||
121 | x.advance_edit(); | 110 | x.advance_edit(); |
122 | x | 111 | x |
123 | } | 112 | } |
@@ -127,11 +116,7 @@ impl<'a> Edits<'a> { | |||
127 | Some((next, rest)) => { | 116 | Some((next, rest)) => { |
128 | let delete = self.translate_range(next.delete); | 117 | let delete = self.translate_range(next.delete); |
129 | let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64; | 118 | let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64; |
130 | self.current = Some(TranslatedEdit { | 119 | self.current = Some(TranslatedEdit { delete, insert: &next.insert, diff }); |
131 | delete, | ||
132 | insert: &next.insert, | ||
133 | diff, | ||
134 | }); | ||
135 | self.edits = rest; | 120 | self.edits = rest; |
136 | } | 121 | } |
137 | None => { | 122 | None => { |
@@ -142,10 +127,7 @@ impl<'a> Edits<'a> { | |||
142 | 127 | ||
143 | fn next_inserted_steps(&mut self) -> Option<OffsetStepIter<'a>> { | 128 | fn next_inserted_steps(&mut self) -> Option<OffsetStepIter<'a>> { |
144 | let cur = self.current.as_ref()?; | 129 | let cur = self.current.as_ref()?; |
145 | let res = Some(OffsetStepIter { | 130 | let res = Some(OffsetStepIter { offset: cur.delete.start(), text: &cur.insert }); |
146 | offset: cur.delete.start(), | ||
147 | text: &cur.insert, | ||
148 | }); | ||
149 | self.advance_edit(); | 131 | self.advance_edit(); |
150 | res | 132 | res |
151 | } | 133 | } |
@@ -160,18 +142,12 @@ impl<'a> Edits<'a> { | |||
160 | if step_pos <= edit.delete.start() { | 142 | if step_pos <= edit.delete.start() { |
161 | NextSteps::Use | 143 | NextSteps::Use |
162 | } else if step_pos <= edit.delete.end() { | 144 | } else if step_pos <= edit.delete.end() { |
163 | let iter = OffsetStepIter { | 145 | let iter = OffsetStepIter { offset: edit.delete.start(), text: &edit.insert }; |
164 | offset: edit.delete.start(), | ||
165 | text: &edit.insert, | ||
166 | }; | ||
167 | // empty slice to avoid returning steps again | 146 | // empty slice to avoid returning steps again |
168 | edit.insert = &edit.insert[edit.insert.len()..]; | 147 | edit.insert = &edit.insert[edit.insert.len()..]; |
169 | NextSteps::ReplaceMany(iter) | 148 | NextSteps::ReplaceMany(iter) |
170 | } else { | 149 | } else { |
171 | let iter = OffsetStepIter { | 150 | let iter = OffsetStepIter { offset: edit.delete.start(), text: &edit.insert }; |
172 | offset: edit.delete.start(), | ||
173 | text: &edit.insert, | ||
174 | }; | ||
175 | // empty slice to avoid returning steps again | 151 | // empty slice to avoid returning steps again |
176 | edit.insert = &edit.insert[edit.insert.len()..]; | 152 | edit.insert = &edit.insert[edit.insert.len()..]; |
177 | self.advance_edit(); | 153 | self.advance_edit(); |
@@ -222,11 +198,7 @@ struct RunningLineCol { | |||
222 | 198 | ||
223 | impl RunningLineCol { | 199 | impl RunningLineCol { |
224 | fn new() -> RunningLineCol { | 200 | fn new() -> RunningLineCol { |
225 | RunningLineCol { | 201 | RunningLineCol { line: 0, last_newline: TextUnit::from(0), col_adjust: TextUnit::from(0) } |
226 | line: 0, | ||
227 | last_newline: TextUnit::from(0), | ||
228 | col_adjust: TextUnit::from(0), | ||
229 | } | ||
230 | } | 202 | } |
231 | 203 | ||
232 | fn to_line_col(&self, offset: TextUnit) -> LineCol { | 204 | fn to_line_col(&self, offset: TextUnit) -> LineCol { |
@@ -339,12 +311,7 @@ mod test { | |||
339 | let edited_text = x.edit.apply(&x.text); | 311 | let edited_text = x.edit.apply(&x.text); |
340 | let arb_offset = arb_offset(&edited_text); | 312 | let arb_offset = arb_offset(&edited_text); |
341 | (Just(x), Just(edited_text), arb_offset).prop_map(|(x, edited_text, offset)| { | 313 | (Just(x), Just(edited_text), arb_offset).prop_map(|(x, edited_text, offset)| { |
342 | ArbTextWithEditAndOffset { | 314 | ArbTextWithEditAndOffset { text: x.text, edit: x.edit, edited_text, offset } |
343 | text: x.text, | ||
344 | edit: x.edit, | ||
345 | edited_text, | ||
346 | offset, | ||
347 | } | ||
348 | }) | 315 | }) |
349 | }) | 316 | }) |
350 | .boxed() | 317 | .boxed() |
diff --git a/crates/ra_ide_api_light/src/structure.rs b/crates/ra_ide_api_light/src/structure.rs index 330a3694c..75afd1181 100644 --- a/crates/ra_ide_api_light/src/structure.rs +++ b/crates/ra_ide_api_light/src/structure.rs | |||
@@ -70,10 +70,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
70 | node_range: node.syntax().range(), | 70 | node_range: node.syntax().range(), |
71 | kind: node.syntax().kind(), | 71 | kind: node.syntax().kind(), |
72 | detail, | 72 | detail, |
73 | deprecated: node | 73 | deprecated: node.attrs().filter_map(|x| x.as_named()).any(|x| x == "deprecated"), |
74 | .attrs() | ||
75 | .filter_map(|x| x.as_named()) | ||
76 | .any(|x| x == "deprecated"), | ||
77 | }) | 74 | }) |
78 | } | 75 | } |
79 | 76 | ||
@@ -123,11 +120,9 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
123 | let target_trait = im.target_trait(); | 120 | let target_trait = im.target_trait(); |
124 | let label = match target_trait { | 121 | let label = match target_trait { |
125 | None => format!("impl {}", target_type.syntax().text()), | 122 | None => format!("impl {}", target_type.syntax().text()), |
126 | Some(t) => format!( | 123 | Some(t) => { |
127 | "impl {} for {}", | 124 | format!("impl {} for {}", t.syntax().text(), target_type.syntax().text(),) |
128 | t.syntax().text(), | 125 | } |
129 | target_type.syntax().text(), | ||
130 | ), | ||
131 | }; | 126 | }; |
132 | 127 | ||
133 | let node = StructureNode { | 128 | let node = StructureNode { |
diff --git a/crates/ra_ide_api_light/src/typing.rs b/crates/ra_ide_api_light/src/typing.rs index 861027b9f..a08a5a8c5 100644 --- a/crates/ra_ide_api_light/src/typing.rs +++ b/crates/ra_ide_api_light/src/typing.rs | |||
@@ -8,9 +8,8 @@ use ra_syntax::{ | |||
8 | use crate::{LocalEdit, TextEditBuilder, formatting::leading_indent}; | 8 | use crate::{LocalEdit, TextEditBuilder, formatting::leading_indent}; |
9 | 9 | ||
10 | pub fn on_enter(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> { | 10 | pub fn on_enter(file: &SourceFile, offset: TextUnit) -> Option<LocalEdit> { |
11 | let comment = find_leaf_at_offset(file.syntax(), offset) | 11 | let comment = |
12 | .left_biased() | 12 | find_leaf_at_offset(file.syntax(), offset).left_biased().and_then(ast::Comment::cast)?; |
13 | .and_then(ast::Comment::cast)?; | ||
14 | 13 | ||
15 | if let ast::CommentFlavor::Multiline = comment.flavor() { | 14 | if let ast::CommentFlavor::Multiline = comment.flavor() { |
16 | return None; | 15 | return None; |
@@ -64,12 +63,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<LocalEdit> | |||
64 | if expr_range.contains(eq_offset) && eq_offset != expr_range.start() { | 63 | if expr_range.contains(eq_offset) && eq_offset != expr_range.start() { |
65 | return None; | 64 | return None; |
66 | } | 65 | } |
67 | if file | 66 | if file.syntax().text().slice(eq_offset..expr_range.start()).contains('\n') { |
68 | .syntax() | ||
69 | .text() | ||
70 | .slice(eq_offset..expr_range.start()) | ||
71 | .contains('\n') | ||
72 | { | ||
73 | return None; | 67 | return None; |
74 | } | 68 | } |
75 | } else { | 69 | } else { |
@@ -100,10 +94,7 @@ pub fn on_dot_typed(file: &SourceFile, dot_offset: TextUnit) -> Option<LocalEdit | |||
100 | let current_indent_len = TextUnit::of_str(current_indent); | 94 | let current_indent_len = TextUnit::of_str(current_indent); |
101 | 95 | ||
102 | // Make sure dot is a part of call chain | 96 | // Make sure dot is a part of call chain |
103 | let field_expr = whitespace | 97 | let field_expr = whitespace.syntax().parent().and_then(ast::FieldExpr::cast)?; |
104 | .syntax() | ||
105 | .parent() | ||
106 | .and_then(ast::FieldExpr::cast)?; | ||
107 | let prev_indent = leading_indent(field_expr.syntax())?; | 98 | let prev_indent = leading_indent(field_expr.syntax())?; |
108 | let target_indent = format!(" {}", prev_indent); | 99 | let target_indent = format!(" {}", prev_indent); |
109 | let target_indent_len = TextUnit::of_str(&target_indent); | 100 | let target_indent_len = TextUnit::of_str(&target_indent); |
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 39992788d..2af2b89fe 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs | |||
@@ -7,15 +7,13 @@ use lsp_types::{ | |||
7 | 7 | ||
8 | pub fn server_capabilities() -> ServerCapabilities { | 8 | pub fn server_capabilities() -> ServerCapabilities { |
9 | ServerCapabilities { | 9 | ServerCapabilities { |
10 | text_document_sync: Some(TextDocumentSyncCapability::Options( | 10 | text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { |
11 | TextDocumentSyncOptions { | 11 | open_close: Some(true), |
12 | open_close: Some(true), | 12 | change: Some(TextDocumentSyncKind::Full), |
13 | change: Some(TextDocumentSyncKind::Full), | 13 | will_save: None, |
14 | will_save: None, | 14 | will_save_wait_until: None, |
15 | will_save_wait_until: None, | 15 | save: None, |
16 | save: None, | 16 | })), |
17 | }, | ||
18 | )), | ||
19 | hover_provider: Some(true), | 17 | hover_provider: Some(true), |
20 | completion_provider: Some(CompletionOptions { | 18 | completion_provider: Some(CompletionOptions { |
21 | resolve_provider: None, | 19 | resolve_provider: None, |
@@ -32,9 +30,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
32 | document_symbol_provider: Some(true), | 30 | document_symbol_provider: Some(true), |
33 | workspace_symbol_provider: Some(true), | 31 | workspace_symbol_provider: Some(true), |
34 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), | 32 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), |
35 | code_lens_provider: Some(CodeLensOptions { | 33 | code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), |
36 | resolve_provider: Some(true), | ||
37 | }), | ||
38 | document_formatting_provider: Some(true), | 34 | document_formatting_provider: Some(true), |
39 | document_range_formatting_provider: None, | 35 | document_range_formatting_provider: None, |
40 | document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions { | 36 | document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions { |
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index db9496bbe..e011eab7c 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs | |||
@@ -64,10 +64,7 @@ impl CargoTargetSpec { | |||
64 | None => return Ok(None), | 64 | None => return Ok(None), |
65 | }; | 65 | }; |
66 | let file_id = world.analysis().crate_root(crate_id)?; | 66 | let file_id = world.analysis().crate_root(crate_id)?; |
67 | let path = world | 67 | let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0.into())); |
68 | .vfs | ||
69 | .read() | ||
70 | .file2path(ra_vfs::VfsFile(file_id.0.into())); | ||
71 | let res = world.workspaces.iter().find_map(|ws| { | 68 | let res = world.workspaces.iter().find_map(|ws| { |
72 | let tgt = ws.cargo.target_by_root(&path)?; | 69 | let tgt = ws.cargo.target_by_root(&path)?; |
73 | let res = CargoTargetSpec { | 70 | let res = CargoTargetSpec { |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 981385466..20077a48a 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -82,11 +82,8 @@ impl ConvWith for CompletionItem { | |||
82 | fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { | 82 | fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { |
83 | let atom_text_edit = AtomTextEdit::replace(self.source_range(), self.insert_text()); | 83 | let atom_text_edit = AtomTextEdit::replace(self.source_range(), self.insert_text()); |
84 | let text_edit = (&atom_text_edit).conv_with(ctx); | 84 | let text_edit = (&atom_text_edit).conv_with(ctx); |
85 | let additional_text_edits = if let Some(edit) = self.take_text_edit() { | 85 | let additional_text_edits = |
86 | Some(edit.conv_with(ctx)) | 86 | if let Some(edit) = self.take_text_edit() { Some(edit.conv_with(ctx)) } else { None }; |
87 | } else { | ||
88 | None | ||
89 | }; | ||
90 | 87 | ||
91 | let mut res = lsp_types::CompletionItem { | 88 | let mut res = lsp_types::CompletionItem { |
92 | label: self.label().to_string(), | 89 | label: self.label().to_string(), |
@@ -112,10 +109,7 @@ impl ConvWith for Position { | |||
112 | type Output = TextUnit; | 109 | type Output = TextUnit; |
113 | 110 | ||
114 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { | 111 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { |
115 | let line_col = LineCol { | 112 | let line_col = LineCol { line: self.line as u32, col_utf16: self.character as u32 }; |
116 | line: self.line as u32, | ||
117 | col_utf16: self.character as u32, | ||
118 | }; | ||
119 | line_index.offset(line_col) | 113 | line_index.offset(line_col) |
120 | } | 114 | } |
121 | } | 115 | } |
@@ -135,10 +129,7 @@ impl ConvWith for TextRange { | |||
135 | type Output = Range; | 129 | type Output = Range; |
136 | 130 | ||
137 | fn conv_with(self, line_index: &LineIndex) -> Range { | 131 | fn conv_with(self, line_index: &LineIndex) -> Range { |
138 | Range::new( | 132 | Range::new(self.start().conv_with(line_index), self.end().conv_with(line_index)) |
139 | self.start().conv_with(line_index), | ||
140 | self.end().conv_with(line_index), | ||
141 | ) | ||
142 | } | 133 | } |
143 | } | 134 | } |
144 | 135 | ||
@@ -147,10 +138,7 @@ impl ConvWith for Range { | |||
147 | type Output = TextRange; | 138 | type Output = TextRange; |
148 | 139 | ||
149 | fn conv_with(self, line_index: &LineIndex) -> TextRange { | 140 | fn conv_with(self, line_index: &LineIndex) -> TextRange { |
150 | TextRange::from_to( | 141 | TextRange::from_to(self.start.conv_with(line_index), self.end.conv_with(line_index)) |
151 | self.start.conv_with(line_index), | ||
152 | self.end.conv_with(line_index), | ||
153 | ) | ||
154 | } | 142 | } |
155 | } | 143 | } |
156 | 144 | ||
@@ -303,11 +291,7 @@ impl TryConvWith for SourceChange { | |||
303 | changes: None, | 291 | changes: None, |
304 | document_changes: Some(DocumentChanges::Operations(document_changes)), | 292 | document_changes: Some(DocumentChanges::Operations(document_changes)), |
305 | }; | 293 | }; |
306 | Ok(req::SourceChange { | 294 | Ok(req::SourceChange { label: self.label, workspace_edit, cursor_position }) |
307 | label: self.label, | ||
308 | workspace_edit, | ||
309 | cursor_position, | ||
310 | }) | ||
311 | } | 295 | } |
312 | } | 296 | } |
313 | 297 | ||
@@ -320,16 +304,8 @@ impl TryConvWith for SourceFileEdit { | |||
320 | version: None, | 304 | version: None, |
321 | }; | 305 | }; |
322 | let line_index = world.analysis().file_line_index(self.file_id); | 306 | let line_index = world.analysis().file_line_index(self.file_id); |
323 | let edits = self | 307 | let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); |
324 | .edit | 308 | Ok(TextDocumentEdit { text_document, edits }) |
325 | .as_atoms() | ||
326 | .iter() | ||
327 | .map_conv_with(&line_index) | ||
328 | .collect(); | ||
329 | Ok(TextDocumentEdit { | ||
330 | text_document, | ||
331 | edits, | ||
332 | }) | ||
333 | } | 309 | } |
334 | } | 310 | } |
335 | 311 | ||
@@ -342,18 +318,10 @@ impl TryConvWith for FileSystemEdit { | |||
342 | let uri = world.path_to_uri(source_root, &path)?; | 318 | let uri = world.path_to_uri(source_root, &path)?; |
343 | ResourceOp::Create(CreateFile { uri, options: None }) | 319 | ResourceOp::Create(CreateFile { uri, options: None }) |
344 | } | 320 | } |
345 | FileSystemEdit::MoveFile { | 321 | FileSystemEdit::MoveFile { src, dst_source_root, dst_path } => { |
346 | src, | ||
347 | dst_source_root, | ||
348 | dst_path, | ||
349 | } => { | ||
350 | let old_uri = world.file_id_to_uri(src)?; | 322 | let old_uri = world.file_id_to_uri(src)?; |
351 | let new_uri = world.path_to_uri(dst_source_root, &dst_path)?; | 323 | let new_uri = world.path_to_uri(dst_source_root, &dst_path)?; |
352 | ResourceOp::Rename(RenameFile { | 324 | ResourceOp::Rename(RenameFile { old_uri, new_uri, options: None }) |
353 | old_uri, | ||
354 | new_uri, | ||
355 | options: None, | ||
356 | }) | ||
357 | } | 325 | } |
358 | }; | 326 | }; |
359 | Ok(res) | 327 | Ok(res) |
@@ -381,11 +349,8 @@ pub fn to_location_link( | |||
381 | 349 | ||
382 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | 350 | let target_range = target.info.full_range().conv_with(&tgt_line_index); |
383 | 351 | ||
384 | let target_selection_range = target | 352 | let target_selection_range = |
385 | .info | 353 | target.info.focus_range().map(|it| it.conv_with(&tgt_line_index)).unwrap_or(target_range); |
386 | .focus_range() | ||
387 | .map(|it| it.conv_with(&tgt_line_index)) | ||
388 | .unwrap_or(target_range); | ||
389 | 354 | ||
390 | let res = LocationLink { | 355 | let res = LocationLink { |
391 | origin_selection_range: Some(target.range.conv_with(line_index)), | 356 | origin_selection_range: Some(target.range.conv_with(line_index)), |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 33aa30d70..03f83c7be 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -36,23 +36,15 @@ struct InitializationOptions { | |||
36 | fn main_inner() -> Result<()> { | 36 | fn main_inner() -> Result<()> { |
37 | let (receiver, sender, threads) = stdio_transport(); | 37 | let (receiver, sender, threads) = stdio_transport(); |
38 | let cwd = ::std::env::current_dir()?; | 38 | let cwd = ::std::env::current_dir()?; |
39 | run_server( | 39 | run_server(ra_lsp_server::server_capabilities(), receiver, sender, |params, r, s| { |
40 | ra_lsp_server::server_capabilities(), | 40 | let root = params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); |
41 | receiver, | 41 | let supports_decorations = params |
42 | sender, | 42 | .initialization_options |
43 | |params, r, s| { | 43 | .and_then(|v| InitializationOptions::deserialize(v).ok()) |
44 | let root = params | 44 | .and_then(|it| it.publish_decorations) |
45 | .root_uri | 45 | == Some(true); |
46 | .and_then(|it| it.to_file_path().ok()) | 46 | ra_lsp_server::main_loop(false, root, supports_decorations, r, s) |
47 | .unwrap_or(cwd); | 47 | })?; |
48 | let supports_decorations = params | ||
49 | .initialization_options | ||
50 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | ||
51 | .and_then(|it| it.publish_decorations) | ||
52 | == Some(true); | ||
53 | ra_lsp_server::main_loop(false, root, supports_decorations, r, s) | ||
54 | }, | ||
55 | )?; | ||
56 | log::info!("shutting down IO..."); | 48 | log::info!("shutting down IO..."); |
57 | threads.join()?; | 49 | threads.join()?; |
58 | log::info!("... IO is down"); | 50 | log::info!("... IO is down"); |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 26b6fe54a..a51299851 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -25,10 +25,7 @@ use crate::{ | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | #[derive(Debug, Fail)] | 27 | #[derive(Debug, Fail)] |
28 | #[fail( | 28 | #[fail(display = "Language Server request failed with {}. ({})", code, message)] |
29 | display = "Language Server request failed with {}. ({})", | ||
30 | code, message | ||
31 | )] | ||
32 | pub struct LspError { | 29 | pub struct LspError { |
33 | pub code: i32, | 30 | pub code: i32, |
34 | pub message: String, | 31 | pub message: String, |
@@ -69,9 +66,7 @@ pub fn main_loop( | |||
69 | } | 66 | } |
70 | }; | 67 | }; |
71 | ws_worker.shutdown(); | 68 | ws_worker.shutdown(); |
72 | ws_watcher | 69 | ws_watcher.shutdown().map_err(|_| format_err!("ws watcher died"))?; |
73 | .shutdown() | ||
74 | .map_err(|_| format_err!("ws watcher died"))?; | ||
75 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); | 70 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); |
76 | 71 | ||
77 | log::info!("server initialized, serving requests"); | 72 | log::info!("server initialized, serving requests"); |
@@ -92,9 +87,7 @@ pub fn main_loop( | |||
92 | ); | 87 | ); |
93 | 88 | ||
94 | log::info!("waiting for tasks to finish..."); | 89 | log::info!("waiting for tasks to finish..."); |
95 | task_receiver | 90 | task_receiver.into_iter().for_each(|task| on_task(task, msg_sender, &mut pending_requests)); |
96 | .into_iter() | ||
97 | .for_each(|task| on_task(task, msg_sender, &mut pending_requests)); | ||
98 | log::info!("...tasks have finished"); | 91 | log::info!("...tasks have finished"); |
99 | log::info!("joining threadpool..."); | 92 | log::info!("joining threadpool..."); |
100 | drop(pool); | 93 | drop(pool); |
@@ -119,9 +112,7 @@ enum Event { | |||
119 | impl fmt::Debug for Event { | 112 | impl fmt::Debug for Event { |
120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
121 | let debug_verbose_not = |not: &RawNotification, f: &mut fmt::Formatter| { | 114 | let debug_verbose_not = |not: &RawNotification, f: &mut fmt::Formatter| { |
122 | f.debug_struct("RawNotification") | 115 | f.debug_struct("RawNotification").field("method", ¬.method).finish() |
123 | .field("method", ¬.method) | ||
124 | .finish() | ||
125 | }; | 116 | }; |
126 | 117 | ||
127 | match self { | 118 | match self { |
@@ -287,13 +278,7 @@ fn on_request( | |||
287 | sender: &Sender<Task>, | 278 | sender: &Sender<Task>, |
288 | req: RawRequest, | 279 | req: RawRequest, |
289 | ) -> Result<Option<RawRequest>> { | 280 | ) -> Result<Option<RawRequest>> { |
290 | let mut pool_dispatcher = PoolDispatcher { | 281 | let mut pool_dispatcher = PoolDispatcher { req: Some(req), res: None, pool, world, sender }; |
291 | req: Some(req), | ||
292 | res: None, | ||
293 | pool, | ||
294 | world, | ||
295 | sender, | ||
296 | }; | ||
297 | let req = pool_dispatcher | 282 | let req = pool_dispatcher |
298 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? | 283 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? |
299 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? | 284 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? |
@@ -362,13 +347,9 @@ fn on_notification( | |||
362 | let not = match not.cast::<req::DidOpenTextDocument>() { | 347 | let not = match not.cast::<req::DidOpenTextDocument>() { |
363 | Ok(params) => { | 348 | Ok(params) => { |
364 | let uri = params.text_document.uri; | 349 | let uri = params.text_document.uri; |
365 | let path = uri | 350 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
366 | .to_file_path() | 351 | if let Some(file_id) = |
367 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 352 | state.vfs.write().add_file_overlay(&path, params.text_document.text) |
368 | if let Some(file_id) = state | ||
369 | .vfs | ||
370 | .write() | ||
371 | .add_file_overlay(&path, params.text_document.text) | ||
372 | { | 353 | { |
373 | subs.add_sub(FileId(file_id.0.into())); | 354 | subs.add_sub(FileId(file_id.0.into())); |
374 | } | 355 | } |
@@ -379,14 +360,9 @@ fn on_notification( | |||
379 | let not = match not.cast::<req::DidChangeTextDocument>() { | 360 | let not = match not.cast::<req::DidChangeTextDocument>() { |
380 | Ok(mut params) => { | 361 | Ok(mut params) => { |
381 | let uri = params.text_document.uri; | 362 | let uri = params.text_document.uri; |
382 | let path = uri | 363 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
383 | .to_file_path() | 364 | let text = |
384 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 365 | params.content_changes.pop().ok_or_else(|| format_err!("empty changes"))?.text; |
385 | let text = params | ||
386 | .content_changes | ||
387 | .pop() | ||
388 | .ok_or_else(|| format_err!("empty changes"))? | ||
389 | .text; | ||
390 | state.vfs.write().change_file_overlay(path.as_path(), text); | 366 | state.vfs.write().change_file_overlay(path.as_path(), text); |
391 | return Ok(()); | 367 | return Ok(()); |
392 | } | 368 | } |
@@ -395,16 +371,11 @@ fn on_notification( | |||
395 | let not = match not.cast::<req::DidCloseTextDocument>() { | 371 | let not = match not.cast::<req::DidCloseTextDocument>() { |
396 | Ok(params) => { | 372 | Ok(params) => { |
397 | let uri = params.text_document.uri; | 373 | let uri = params.text_document.uri; |
398 | let path = uri | 374 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
399 | .to_file_path() | ||
400 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | ||
401 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { | 375 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { |
402 | subs.remove_sub(FileId(file_id.0.into())); | 376 | subs.remove_sub(FileId(file_id.0.into())); |
403 | } | 377 | } |
404 | let params = req::PublishDiagnosticsParams { | 378 | let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; |
405 | uri, | ||
406 | diagnostics: Vec::new(), | ||
407 | }; | ||
408 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); | 379 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); |
409 | msg_sender.send(RawMessage::Notification(not)).unwrap(); | 380 | msg_sender.send(RawMessage::Notification(not)).unwrap(); |
410 | return Ok(()); | 381 | return Ok(()); |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index aa55d1255..0cdb39c32 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -46,12 +46,7 @@ pub fn handle_extend_selection( | |||
46 | .into_iter() | 46 | .into_iter() |
47 | .map_conv_with(&line_index) | 47 | .map_conv_with(&line_index) |
48 | .map(|range| FileRange { file_id, range }) | 48 | .map(|range| FileRange { file_id, range }) |
49 | .map(|frange| { | 49 | .map(|frange| world.analysis().extend_selection(frange).map(|it| it.conv_with(&line_index))) |
50 | world | ||
51 | .analysis() | ||
52 | .extend_selection(frange) | ||
53 | .map(|it| it.conv_with(&line_index)) | ||
54 | }) | ||
55 | .collect::<Cancelable<Vec<_>>>()?; | 50 | .collect::<Cancelable<Vec<_>>>()?; |
56 | Ok(req::ExtendSelectionResult { selections }) | 51 | Ok(req::ExtendSelectionResult { selections }) |
57 | } | 52 | } |
@@ -67,10 +62,7 @@ pub fn handle_find_matching_brace( | |||
67 | .into_iter() | 62 | .into_iter() |
68 | .map_conv_with(&line_index) | 63 | .map_conv_with(&line_index) |
69 | .map(|offset| { | 64 | .map(|offset| { |
70 | world | 65 | world.analysis().matching_brace(FilePosition { file_id, offset }).unwrap_or(offset) |
71 | .analysis() | ||
72 | .matching_brace(FilePosition { file_id, offset }) | ||
73 | .unwrap_or(offset) | ||
74 | }) | 66 | }) |
75 | .map_conv_with(&line_index) | 67 | .map_conv_with(&line_index) |
76 | .collect(); | 68 | .collect(); |
@@ -171,11 +163,7 @@ pub fn handle_workspace_symbol( | |||
171 | let all_symbols = params.query.contains('#'); | 163 | let all_symbols = params.query.contains('#'); |
172 | let libs = params.query.contains('*'); | 164 | let libs = params.query.contains('*'); |
173 | let query = { | 165 | let query = { |
174 | let query: String = params | 166 | let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect(); |
175 | .query | ||
176 | .chars() | ||
177 | .filter(|&c| c != '#' && c != '*') | ||
178 | .collect(); | ||
179 | let mut q = Query::new(query); | 167 | let mut q = Query::new(query); |
180 | if !all_symbols { | 168 | if !all_symbols { |
181 | q.only_types(); | 169 | q.only_types(); |
@@ -367,10 +355,7 @@ pub fn handle_completion( | |||
367 | Some(items) => items, | 355 | Some(items) => items, |
368 | }; | 356 | }; |
369 | let line_index = world.analysis().file_line_index(position.file_id); | 357 | let line_index = world.analysis().file_line_index(position.file_id); |
370 | let items = items | 358 | let items = items.into_iter().map(|item| item.conv_with(&line_index)).collect(); |
371 | .into_iter() | ||
372 | .map(|item| item.conv_with(&line_index)) | ||
373 | .collect(); | ||
374 | 359 | ||
375 | Ok(Some(req::CompletionResponse::Array(items))) | 360 | Ok(Some(req::CompletionResponse::Array(items))) |
376 | } | 361 | } |
@@ -496,9 +481,8 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option< | |||
496 | .into()); | 481 | .into()); |
497 | } | 482 | } |
498 | 483 | ||
499 | let optional_change = world | 484 | let optional_change = |
500 | .analysis() | 485 | world.analysis().rename(FilePosition { file_id, offset }, &*params.new_name)?; |
501 | .rename(FilePosition { file_id, offset }, &*params.new_name)?; | ||
502 | let change = match optional_change { | 486 | let change = match optional_change { |
503 | None => return Ok(None), | 487 | None => return Ok(None), |
504 | Some(it) => it, | 488 | Some(it) => it, |
@@ -517,14 +501,10 @@ pub fn handle_references( | |||
517 | let line_index = world.analysis().file_line_index(file_id); | 501 | let line_index = world.analysis().file_line_index(file_id); |
518 | let offset = params.position.conv_with(&line_index); | 502 | let offset = params.position.conv_with(&line_index); |
519 | 503 | ||
520 | let refs = world | 504 | let refs = world.analysis().find_all_refs(FilePosition { file_id, offset })?; |
521 | .analysis() | ||
522 | .find_all_refs(FilePosition { file_id, offset })?; | ||
523 | 505 | ||
524 | Ok(Some( | 506 | Ok(Some( |
525 | refs.into_iter() | 507 | refs.into_iter().filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()).collect(), |
526 | .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()) | ||
527 | .collect(), | ||
528 | )) | 508 | )) |
529 | } | 509 | } |
530 | 510 | ||
@@ -540,9 +520,7 @@ pub fn handle_formatting( | |||
540 | 520 | ||
541 | use std::process; | 521 | use std::process; |
542 | let mut rustfmt = process::Command::new("rustfmt"); | 522 | let mut rustfmt = process::Command::new("rustfmt"); |
543 | rustfmt | 523 | rustfmt.stdin(process::Stdio::piped()).stdout(process::Stdio::piped()); |
544 | .stdin(process::Stdio::piped()) | ||
545 | .stdout(process::Stdio::piped()); | ||
546 | 524 | ||
547 | if let Ok(path) = params.text_document.uri.to_file_path() { | 525 | if let Ok(path) = params.text_document.uri.to_file_path() { |
548 | if let Some(parent) = path.parent() { | 526 | if let Some(parent) = path.parent() { |
@@ -582,10 +560,7 @@ pub fn handle_code_action( | |||
582 | let line_index = world.analysis().file_line_index(file_id); | 560 | let line_index = world.analysis().file_line_index(file_id); |
583 | let range = params.range.conv_with(&line_index); | 561 | let range = params.range.conv_with(&line_index); |
584 | 562 | ||
585 | let assists = world | 563 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); |
586 | .analysis() | ||
587 | .assists(FileRange { file_id, range })? | ||
588 | .into_iter(); | ||
589 | let fixes = world | 564 | let fixes = world |
590 | .analysis() | 565 | .analysis() |
591 | .diagnostics(file_id)? | 566 | .diagnostics(file_id)? |
@@ -720,18 +695,11 @@ pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Resu | |||
720 | to_value(locations).unwrap(), | 695 | to_value(locations).unwrap(), |
721 | ]), | 696 | ]), |
722 | }; | 697 | }; |
723 | Ok(CodeLens { | 698 | Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None }) |
724 | range: code_lens.range, | ||
725 | command: Some(cmd), | ||
726 | data: None, | ||
727 | }) | ||
728 | } | 699 | } |
729 | None => Ok(CodeLens { | 700 | None => Ok(CodeLens { |
730 | range: code_lens.range, | 701 | range: code_lens.range, |
731 | command: Some(Command { | 702 | command: Some(Command { title: "Error".into(), ..Default::default() }), |
732 | title: "Error".into(), | ||
733 | ..Default::default() | ||
734 | }), | ||
735 | data: None, | 703 | data: None, |
736 | }), | 704 | }), |
737 | } | 705 | } |
@@ -744,16 +712,11 @@ pub fn handle_document_highlight( | |||
744 | let file_id = params.text_document.try_conv_with(&world)?; | 712 | let file_id = params.text_document.try_conv_with(&world)?; |
745 | let line_index = world.analysis().file_line_index(file_id); | 713 | let line_index = world.analysis().file_line_index(file_id); |
746 | 714 | ||
747 | let refs = world | 715 | let refs = world.analysis().find_all_refs(params.try_conv_with(&world)?)?; |
748 | .analysis() | ||
749 | .find_all_refs(params.try_conv_with(&world)?)?; | ||
750 | 716 | ||
751 | Ok(Some( | 717 | Ok(Some( |
752 | refs.into_iter() | 718 | refs.into_iter() |
753 | .map(|r| DocumentHighlight { | 719 | .map(|r| DocumentHighlight { range: r.1.conv_with(&line_index), kind: None }) |
754 | range: r.1.conv_with(&line_index), | ||
755 | kind: None, | ||
756 | }) | ||
757 | .collect(), | 720 | .collect(), |
758 | )) | 721 | )) |
759 | } | 722 | } |
@@ -785,10 +748,7 @@ pub fn publish_decorations( | |||
785 | file_id: FileId, | 748 | file_id: FileId, |
786 | ) -> Result<req::PublishDecorationsParams> { | 749 | ) -> Result<req::PublishDecorationsParams> { |
787 | let uri = world.file_id_to_uri(file_id)?; | 750 | let uri = world.file_id_to_uri(file_id)?; |
788 | Ok(req::PublishDecorationsParams { | 751 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) |
789 | uri, | ||
790 | decorations: highlight(&world, file_id)?, | ||
791 | }) | ||
792 | } | 752 | } |
793 | 753 | ||
794 | fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { | 754 | fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { |
@@ -797,10 +757,7 @@ fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { | |||
797 | .analysis() | 757 | .analysis() |
798 | .highlight(file_id)? | 758 | .highlight(file_id)? |
799 | .into_iter() | 759 | .into_iter() |
800 | .map(|h| Decoration { | 760 | .map(|h| Decoration { range: h.range.conv_with(&line_index), tag: h.tag }) |
801 | range: h.range.conv_with(&line_index), | ||
802 | tag: h.tag, | ||
803 | }) | ||
804 | .collect(); | 761 | .collect(); |
805 | Ok(res) | 762 | Ok(res) |
806 | } | 763 | } |
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index a83e01557..11bd952d9 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs | |||
@@ -7,9 +7,7 @@ pub struct Subscriptions { | |||
7 | 7 | ||
8 | impl Subscriptions { | 8 | impl Subscriptions { |
9 | pub fn new() -> Subscriptions { | 9 | pub fn new() -> Subscriptions { |
10 | Subscriptions { | 10 | Subscriptions { subs: FxHashSet::default() } |
11 | subs: FxHashSet::default(), | ||
12 | } | ||
13 | } | 11 | } |
14 | pub fn add_sub(&mut self, file_id: FileId) { | 12 | pub fn add_sub(&mut self, file_id: FileId) { |
15 | self.subs.insert(file_id); | 13 | self.subs.insert(file_id); |
diff --git a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs index 8cf99d586..3b76389d2 100644 --- a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs +++ b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs | |||
@@ -118,14 +118,11 @@ impl Target { | |||
118 | impl CargoWorkspace { | 118 | impl CargoWorkspace { |
119 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { | 119 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { |
120 | let mut meta = MetadataCommand::new(); | 120 | let mut meta = MetadataCommand::new(); |
121 | meta.manifest_path(cargo_toml) | 121 | meta.manifest_path(cargo_toml).features(CargoOpt::AllFeatures); |
122 | .features(CargoOpt::AllFeatures); | ||
123 | if let Some(parent) = cargo_toml.parent() { | 122 | if let Some(parent) = cargo_toml.parent() { |
124 | meta.current_dir(parent); | 123 | meta.current_dir(parent); |
125 | } | 124 | } |
126 | let meta = meta | 125 | let meta = meta.exec().map_err(|e| format_err!("cargo metadata failed: {}", e))?; |
127 | .exec() | ||
128 | .map_err(|e| format_err!("cargo metadata failed: {}", e))?; | ||
129 | let mut pkg_by_id = FxHashMap::default(); | 126 | let mut pkg_by_id = FxHashMap::default(); |
130 | let mut packages = Arena::default(); | 127 | let mut packages = Arena::default(); |
131 | let mut targets = Arena::default(); | 128 | let mut targets = Arena::default(); |
@@ -157,10 +154,8 @@ impl CargoWorkspace { | |||
157 | for node in resolve.nodes { | 154 | for node in resolve.nodes { |
158 | let source = pkg_by_id[&node.id]; | 155 | let source = pkg_by_id[&node.id]; |
159 | for dep_node in node.deps { | 156 | for dep_node in node.deps { |
160 | let dep = PackageDependency { | 157 | let dep = |
161 | name: dep_node.name.into(), | 158 | PackageDependency { name: dep_node.name.into(), pkg: pkg_by_id[&dep_node.pkg] }; |
162 | pkg: pkg_by_id[&dep_node.pkg], | ||
163 | }; | ||
164 | packages[source].dependencies.push(dep); | 159 | packages[source].dependencies.push(dep); |
165 | } | 160 | } |
166 | } | 161 | } |
@@ -171,8 +166,6 @@ impl CargoWorkspace { | |||
171 | self.packages.iter().map(|(id, _pkg)| id) | 166 | self.packages.iter().map(|(id, _pkg)| id) |
172 | } | 167 | } |
173 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | 168 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { |
174 | self.packages() | 169 | self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() |
175 | .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) | ||
176 | .next() | ||
177 | } | 170 | } |
178 | } | 171 | } |
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_lsp_server/src/project_model/sysroot.rs index fb4685671..49210ac7a 100644 --- a/crates/ra_lsp_server/src/project_model/sysroot.rs +++ b/crates/ra_lsp_server/src/project_model/sysroot.rs | |||
@@ -53,9 +53,7 @@ impl Sysroot { | |||
53 | ); | 53 | ); |
54 | } | 54 | } |
55 | 55 | ||
56 | let mut sysroot = Sysroot { | 56 | let mut sysroot = Sysroot { crates: Arena::default() }; |
57 | crates: Arena::default(), | ||
58 | }; | ||
59 | for name in SYSROOT_CRATES.trim().lines() { | 57 | for name in SYSROOT_CRATES.trim().lines() { |
60 | let root = src.join(format!("lib{}", name)).join("lib.rs"); | 58 | let root = src.join(format!("lib{}", name)).join("lib.rs"); |
61 | if root.exists() { | 59 | if root.exists() { |
@@ -77,10 +75,7 @@ impl Sysroot { | |||
77 | } | 75 | } |
78 | 76 | ||
79 | fn by_name(&self, name: &str) -> Option<SysrootCrate> { | 77 | fn by_name(&self, name: &str) -> Option<SysrootCrate> { |
80 | self.crates | 78 | self.crates.iter().find(|(_id, data)| data.name == name).map(|(id, _data)| id) |
81 | .iter() | ||
82 | .find(|(_id, data)| data.name == name) | ||
83 | .map(|(id, _data)| id) | ||
84 | } | 79 | } |
85 | } | 80 | } |
86 | 81 | ||
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c2167c5d8..02f2a37a8 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -80,10 +80,7 @@ impl ServerWorldState { | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | let libstd = ws | 83 | let libstd = ws.sysroot.std().and_then(|it| sysroot_crates.get(&it).map(|&it| it)); |
84 | .sysroot | ||
85 | .std() | ||
86 | .and_then(|it| sysroot_crates.get(&it).map(|&it| it)); | ||
87 | 84 | ||
88 | let mut pkg_to_lib_crate = FxHashMap::default(); | 85 | let mut pkg_to_lib_crate = FxHashMap::default(); |
89 | let mut pkg_crates = FxHashMap::default(); | 86 | let mut pkg_crates = FxHashMap::default(); |
@@ -99,10 +96,7 @@ impl ServerWorldState { | |||
99 | lib_tgt = Some(crate_id); | 96 | lib_tgt = Some(crate_id); |
100 | pkg_to_lib_crate.insert(pkg, crate_id); | 97 | pkg_to_lib_crate.insert(pkg, crate_id); |
101 | } | 98 | } |
102 | pkg_crates | 99 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); |
103 | .entry(pkg) | ||
104 | .or_insert_with(Vec::new) | ||
105 | .push(crate_id); | ||
106 | } | 100 | } |
107 | } | 101 | } |
108 | 102 | ||
@@ -192,18 +186,8 @@ impl ServerWorldState { | |||
192 | libs.push((SourceRootId(root.0.into()), files)); | 186 | libs.push((SourceRootId(root.0.into()), files)); |
193 | } | 187 | } |
194 | } | 188 | } |
195 | VfsChange::AddFile { | 189 | VfsChange::AddFile { root, file, path, text } => { |
196 | root, | 190 | change.add_file(SourceRootId(root.0.into()), FileId(file.0.into()), path, text); |
197 | file, | ||
198 | path, | ||
199 | text, | ||
200 | } => { | ||
201 | change.add_file( | ||
202 | SourceRootId(root.0.into()), | ||
203 | FileId(file.0.into()), | ||
204 | path, | ||
205 | text, | ||
206 | ); | ||
207 | } | 191 | } |
208 | VfsChange::RemoveFile { root, file, path } => { | 192 | VfsChange::RemoveFile { root, file, path } => { |
209 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) | 193 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) |
@@ -247,9 +231,7 @@ impl ServerWorld { | |||
247 | } | 231 | } |
248 | 232 | ||
249 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { | 233 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { |
250 | let path = uri | 234 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
251 | .to_file_path() | ||
252 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | ||
253 | let file = self | 235 | let file = self |
254 | .vfs | 236 | .vfs |
255 | .read() | 237 | .read() |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index bfb0645a8..e49c87169 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs | |||
@@ -55,10 +55,7 @@ fn foo() { | |||
55 | ); | 55 | ); |
56 | server.wait_for_feedback("workspace loaded"); | 56 | server.wait_for_feedback("workspace loaded"); |
57 | server.request::<Runnables>( | 57 | server.request::<Runnables>( |
58 | RunnablesParams { | 58 | RunnablesParams { text_document: server.doc_id("lib.rs"), position: None }, |
59 | text_document: server.doc_id("lib.rs"), | ||
60 | position: None, | ||
61 | }, | ||
62 | json!([ | 59 | json!([ |
63 | { | 60 | { |
64 | "args": [ "test", "--", "foo", "--nocapture" ], | 61 | "args": [ "test", "--", "foo", "--nocapture" ], |
@@ -220,10 +217,7 @@ fn main() {} | |||
220 | "#, | 217 | "#, |
221 | ); | 218 | ); |
222 | server.wait_for_feedback("workspace loaded"); | 219 | server.wait_for_feedback("workspace loaded"); |
223 | let empty_context = || CodeActionContext { | 220 | let empty_context = || CodeActionContext { diagnostics: Vec::new(), only: None }; |
224 | diagnostics: Vec::new(), | ||
225 | only: None, | ||
226 | }; | ||
227 | server.request::<CodeActionRequest>( | 221 | server.request::<CodeActionRequest>( |
228 | CodeActionParams { | 222 | CodeActionParams { |
229 | text_document: server.doc_id("src/lib.rs"), | 223 | text_document: server.doc_id("src/lib.rs"), |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 57a8b4f4d..eee85f8c8 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -83,9 +83,7 @@ impl Server { | |||
83 | 83 | ||
84 | pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { | 84 | pub fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { |
85 | let path = self.dir.path().join(rel_path); | 85 | let path = self.dir.path().join(rel_path); |
86 | TextDocumentIdentifier { | 86 | TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } |
87 | uri: Url::from_file_path(path).unwrap(), | ||
88 | } | ||
89 | } | 87 | } |
90 | 88 | ||
91 | pub fn request<R>(&self, params: R::Params, expected_resp: Value) | 89 | pub fn request<R>(&self, params: R::Params, expected_resp: Value) |
@@ -119,11 +117,7 @@ impl Server { | |||
119 | } | 117 | } |
120 | fn send_request_(&self, r: RawRequest) -> Value { | 118 | fn send_request_(&self, r: RawRequest) -> Value { |
121 | let id = r.id; | 119 | let id = r.id; |
122 | self.worker | 120 | self.worker.as_ref().unwrap().send(RawMessage::Request(r)).unwrap(); |
123 | .as_ref() | ||
124 | .unwrap() | ||
125 | .send(RawMessage::Request(r)) | ||
126 | .unwrap(); | ||
127 | while let Some(msg) = self.recv() { | 121 | while let Some(msg) = self.recv() { |
128 | match msg { | 122 | match msg { |
129 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), | 123 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), |
@@ -169,11 +163,7 @@ impl Server { | |||
169 | }) | 163 | }) |
170 | } | 164 | } |
171 | fn send_notification(&self, not: RawNotification) { | 165 | fn send_notification(&self, not: RawNotification) { |
172 | self.worker | 166 | self.worker.as_ref().unwrap().send(RawMessage::Notification(not)).unwrap(); |
173 | .as_ref() | ||
174 | .unwrap() | ||
175 | .send(RawMessage::Notification(not)) | ||
176 | .unwrap(); | ||
177 | } | 167 | } |
178 | } | 168 | } |
179 | 169 | ||
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 2c8ad4429..b09837831 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs | |||
@@ -137,18 +137,12 @@ impl_froms!(TokenTree: Leaf, Subtree); | |||
137 | "#; | 137 | "#; |
138 | 138 | ||
139 | let source_file = ast::SourceFile::parse(macro_definition); | 139 | let source_file = ast::SourceFile::parse(macro_definition); |
140 | let macro_definition = source_file | 140 | let macro_definition = |
141 | .syntax() | 141 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); |
142 | .descendants() | ||
143 | .find_map(ast::MacroCall::cast) | ||
144 | .unwrap(); | ||
145 | 142 | ||
146 | let source_file = ast::SourceFile::parse(macro_invocation); | 143 | let source_file = ast::SourceFile::parse(macro_invocation); |
147 | let macro_invocation = source_file | 144 | let macro_invocation = |
148 | .syntax() | 145 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); |
149 | .descendants() | ||
150 | .find_map(ast::MacroCall::cast) | ||
151 | .unwrap(); | ||
152 | 146 | ||
153 | let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap(); | 147 | let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap(); |
154 | let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap(); | 148 | let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap(); |
@@ -163,11 +157,8 @@ impl_froms!(TokenTree: Leaf, Subtree); | |||
163 | 157 | ||
164 | fn create_rules(macro_definition: &str) -> MacroRules { | 158 | fn create_rules(macro_definition: &str) -> MacroRules { |
165 | let source_file = ast::SourceFile::parse(macro_definition); | 159 | let source_file = ast::SourceFile::parse(macro_definition); |
166 | let macro_definition = source_file | 160 | let macro_definition = |
167 | .syntax() | 161 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); |
168 | .descendants() | ||
169 | .find_map(ast::MacroCall::cast) | ||
170 | .unwrap(); | ||
171 | 162 | ||
172 | let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap(); | 163 | let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap(); |
173 | crate::MacroRules::parse(&definition_tt).unwrap() | 164 | crate::MacroRules::parse(&definition_tt).unwrap() |
@@ -175,11 +166,8 @@ impl_froms!(TokenTree: Leaf, Subtree); | |||
175 | 166 | ||
176 | fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { | 167 | fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { |
177 | let source_file = ast::SourceFile::parse(invocation); | 168 | let source_file = ast::SourceFile::parse(invocation); |
178 | let macro_invocation = source_file | 169 | let macro_invocation = |
179 | .syntax() | 170 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); |
180 | .descendants() | ||
181 | .find_map(ast::MacroCall::cast) | ||
182 | .unwrap(); | ||
183 | 171 | ||
184 | let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap(); | 172 | let invocation_tt = ast_to_token_tree(macro_invocation.token_tree().unwrap()).unwrap(); |
185 | 173 | ||
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index fb1066eec..31531f4c9 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -133,11 +133,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Option<Bindings> | |||
133 | } | 133 | } |
134 | _ => return None, | 134 | _ => return None, |
135 | }, | 135 | }, |
136 | crate::TokenTree::Repeat(crate::Repeat { | 136 | crate::TokenTree::Repeat(crate::Repeat { subtree, kind: _, separator }) => { |
137 | subtree, | ||
138 | kind: _, | ||
139 | separator, | ||
140 | }) => { | ||
141 | while let Some(nested) = match_lhs(subtree, input) { | 137 | while let Some(nested) = match_lhs(subtree, input) { |
142 | res.push_nested(nested)?; | 138 | res.push_nested(nested)?; |
143 | if let Some(separator) = *separator { | 139 | if let Some(separator) = *separator { |
@@ -166,10 +162,7 @@ fn expand_subtree( | |||
166 | .map(|it| expand_tt(it, bindings, nesting)) | 162 | .map(|it| expand_tt(it, bindings, nesting)) |
167 | .collect::<Option<Vec<_>>>()?; | 163 | .collect::<Option<Vec<_>>>()?; |
168 | 164 | ||
169 | Some(tt::Subtree { | 165 | Some(tt::Subtree { token_trees, delimiter: template.delimiter }) |
170 | token_trees, | ||
171 | delimiter: template.delimiter, | ||
172 | }) | ||
173 | } | 166 | } |
174 | 167 | ||
175 | fn expand_tt( | 168 | fn expand_tt( |
@@ -188,23 +181,15 @@ fn expand_tt( | |||
188 | token_trees.push(t.into()) | 181 | token_trees.push(t.into()) |
189 | } | 182 | } |
190 | nesting.pop().unwrap(); | 183 | nesting.pop().unwrap(); |
191 | tt::Subtree { | 184 | tt::Subtree { token_trees, delimiter: tt::Delimiter::None }.into() |
192 | token_trees, | ||
193 | delimiter: tt::Delimiter::None, | ||
194 | } | ||
195 | .into() | ||
196 | } | 185 | } |
197 | crate::TokenTree::Leaf(leaf) => match leaf { | 186 | crate::TokenTree::Leaf(leaf) => match leaf { |
198 | crate::Leaf::Ident(ident) => tt::Leaf::from(tt::Ident { | 187 | crate::Leaf::Ident(ident) => { |
199 | text: ident.text.clone(), | 188 | tt::Leaf::from(tt::Ident { text: ident.text.clone() }).into() |
200 | }) | 189 | } |
201 | .into(), | ||
202 | crate::Leaf::Punct(punct) => tt::Leaf::from(punct.clone()).into(), | 190 | crate::Leaf::Punct(punct) => tt::Leaf::from(punct.clone()).into(), |
203 | crate::Leaf::Var(v) => bindings.get(&v.text, nesting)?.clone(), | 191 | crate::Leaf::Var(v) => bindings.get(&v.text, nesting)?.clone(), |
204 | crate::Leaf::Literal(l) => tt::Leaf::from(tt::Literal { | 192 | crate::Leaf::Literal(l) => tt::Leaf::from(tt::Literal { text: l.text.clone() }).into(), |
205 | text: l.text.clone(), | ||
206 | }) | ||
207 | .into(), | ||
208 | }, | 193 | }, |
209 | }; | 194 | }; |
210 | Some(res) | 195 | Some(res) |
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs index abad2e8c8..60e566ed2 100644 --- a/crates/ra_mbe/src/mbe_parser.rs +++ b/crates/ra_mbe/src/mbe_parser.rs | |||
@@ -52,10 +52,7 @@ fn parse_subtree(tt: &tt::Subtree) -> Option<crate::Subtree> { | |||
52 | }; | 52 | }; |
53 | token_trees.push(child); | 53 | token_trees.push(child); |
54 | } | 54 | } |
55 | Some(crate::Subtree { | 55 | Some(crate::Subtree { token_trees, delimiter: tt.delimiter }) |
56 | token_trees, | ||
57 | delimiter: tt.delimiter, | ||
58 | }) | ||
59 | } | 56 | } |
60 | 57 | ||
61 | fn parse_var(p: &mut TtCursor) -> Option<crate::Var> { | 58 | fn parse_var(p: &mut TtCursor) -> Option<crate::Var> { |
@@ -92,9 +89,5 @@ fn parse_repeat(p: &mut TtCursor) -> Option<crate::Repeat> { | |||
92 | _ => return None, | 89 | _ => return None, |
93 | }; | 90 | }; |
94 | p.bump(); | 91 | p.bump(); |
95 | Some(crate::Repeat { | 92 | Some(crate::Repeat { subtree, kind, separator }) |
96 | subtree, | ||
97 | kind, | ||
98 | separator, | ||
99 | }) | ||
100 | } | 93 | } |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 2dc04d4e7..9a2eceaba 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -23,23 +23,14 @@ fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> { | |||
23 | for char in child.leaf_text().unwrap().chars() { | 23 | for char in child.leaf_text().unwrap().chars() { |
24 | if let Some(char) = prev { | 24 | if let Some(char) = prev { |
25 | token_trees.push( | 25 | token_trees.push( |
26 | tt::Leaf::from(tt::Punct { | 26 | tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Joint }).into(), |
27 | char, | ||
28 | spacing: tt::Spacing::Joint, | ||
29 | }) | ||
30 | .into(), | ||
31 | ); | 27 | ); |
32 | } | 28 | } |
33 | prev = Some(char) | 29 | prev = Some(char) |
34 | } | 30 | } |
35 | if let Some(char) = prev { | 31 | if let Some(char) = prev { |
36 | token_trees.push( | 32 | token_trees |
37 | tt::Leaf::from(tt::Punct { | 33 | .push(tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Alone }).into()); |
38 | char, | ||
39 | spacing: tt::Spacing::Alone, | ||
40 | }) | ||
41 | .into(), | ||
42 | ); | ||
43 | } | 34 | } |
44 | } else { | 35 | } else { |
45 | let child: tt::TokenTree = if child.kind() == TOKEN_TREE { | 36 | let child: tt::TokenTree = if child.kind() == TOKEN_TREE { |
@@ -48,10 +39,7 @@ fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> { | |||
48 | let text = child.leaf_text().unwrap().clone(); | 39 | let text = child.leaf_text().unwrap().clone(); |
49 | tt::Leaf::from(tt::Ident { text }).into() | 40 | tt::Leaf::from(tt::Ident { text }).into() |
50 | } else if child.kind().is_literal() { | 41 | } else if child.kind().is_literal() { |
51 | tt::Leaf::from(tt::Literal { | 42 | tt::Leaf::from(tt::Literal { text: child.leaf_text().unwrap().clone() }).into() |
52 | text: child.leaf_text().unwrap().clone(), | ||
53 | }) | ||
54 | .into() | ||
55 | } else { | 43 | } else { |
56 | return None; | 44 | return None; |
57 | }; | 45 | }; |
@@ -59,9 +47,6 @@ fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> { | |||
59 | } | 47 | } |
60 | } | 48 | } |
61 | 49 | ||
62 | let res = tt::Subtree { | 50 | let res = tt::Subtree { delimiter, token_trees }; |
63 | delimiter, | ||
64 | token_trees, | ||
65 | }; | ||
66 | Some(res) | 51 | Some(res) |
67 | } | 52 | } |
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs index 38f21594c..81a99228f 100644 --- a/crates/ra_syntax/src/algo/visit.rs +++ b/crates/ra_syntax/src/algo/visit.rs | |||
@@ -7,10 +7,7 @@ pub fn visitor<'a, T>() -> impl Visitor<'a, Output = T> { | |||
7 | } | 7 | } |
8 | 8 | ||
9 | pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output = T, Ctx = C> { | 9 | pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output = T, Ctx = C> { |
10 | EmptyVisitorCtx { | 10 | EmptyVisitorCtx { ph: PhantomData, ctx } |
11 | ph: PhantomData, | ||
12 | ctx, | ||
13 | } | ||
14 | } | 11 | } |
15 | 12 | ||
16 | pub trait Visitor<'a>: Sized { | 13 | pub trait Visitor<'a>: Sized { |
@@ -21,11 +18,7 @@ pub trait Visitor<'a>: Sized { | |||
21 | N: AstNode + 'a, | 18 | N: AstNode + 'a, |
22 | F: FnOnce(&'a N) -> Self::Output, | 19 | F: FnOnce(&'a N) -> Self::Output, |
23 | { | 20 | { |
24 | Vis { | 21 | Vis { inner: self, f, ph: PhantomData } |
25 | inner: self, | ||
26 | f, | ||
27 | ph: PhantomData, | ||
28 | } | ||
29 | } | 22 | } |
30 | } | 23 | } |
31 | 24 | ||
@@ -38,11 +31,7 @@ pub trait VisitorCtx<'a>: Sized { | |||
38 | N: AstNode + 'a, | 31 | N: AstNode + 'a, |
39 | F: FnOnce(&'a N, Self::Ctx) -> Self::Output, | 32 | F: FnOnce(&'a N, Self::Ctx) -> Self::Output, |
40 | { | 33 | { |
41 | VisCtx { | 34 | VisCtx { inner: self, f, ph: PhantomData } |
42 | inner: self, | ||
43 | f, | ||
44 | ph: PhantomData, | ||
45 | } | ||
46 | } | 35 | } |
47 | } | 36 | } |
48 | 37 | ||
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index d6237532b..cf5cfecc2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -127,16 +127,12 @@ pub trait DocCommentsOwner: AstNode { | |||
127 | let line = comment.text().as_str(); | 127 | let line = comment.text().as_str(); |
128 | 128 | ||
129 | // Determine if the prefix or prefix + 1 char is stripped | 129 | // Determine if the prefix or prefix + 1 char is stripped |
130 | let pos = if line | 130 | let pos = |
131 | .chars() | 131 | if line.chars().nth(prefix_len).map(|c| c.is_whitespace()).unwrap_or(false) { |
132 | .nth(prefix_len) | 132 | prefix_len + 1 |
133 | .map(|c| c.is_whitespace()) | 133 | } else { |
134 | .unwrap_or(false) | 134 | prefix_len |
135 | { | 135 | }; |
136 | prefix_len + 1 | ||
137 | } else { | ||
138 | prefix_len | ||
139 | }; | ||
140 | 136 | ||
141 | line[pos..].to_owned() | 137 | line[pos..].to_owned() |
142 | }) | 138 | }) |
@@ -357,10 +353,7 @@ pub enum PathSegmentKind<'a> { | |||
357 | 353 | ||
358 | impl PathSegment { | 354 | impl PathSegment { |
359 | pub fn parent_path(&self) -> &Path { | 355 | pub fn parent_path(&self) -> &Path { |
360 | self.syntax() | 356 | self.syntax().parent().and_then(Path::cast).expect("segments are always nested in paths") |
361 | .parent() | ||
362 | .and_then(Path::cast) | ||
363 | .expect("segments are always nested in paths") | ||
364 | } | 357 | } |
365 | 358 | ||
366 | pub fn kind(&self) -> Option<PathSegmentKind> { | 359 | pub fn kind(&self) -> Option<PathSegmentKind> { |
@@ -428,10 +421,7 @@ pub struct AstChildren<'a, N> { | |||
428 | 421 | ||
429 | impl<'a, N> AstChildren<'a, N> { | 422 | impl<'a, N> AstChildren<'a, N> { |
430 | fn new(parent: &'a SyntaxNode) -> Self { | 423 | fn new(parent: &'a SyntaxNode) -> Self { |
431 | AstChildren { | 424 | AstChildren { inner: parent.children(), ph: PhantomData } |
432 | inner: parent.children(), | ||
433 | ph: PhantomData, | ||
434 | } | ||
435 | } | 425 | } |
436 | } | 426 | } |
437 | 427 | ||
@@ -658,11 +648,7 @@ impl SelfParam { | |||
658 | let borrowed = self.syntax().children().any(|n| n.kind() == AMP); | 648 | let borrowed = self.syntax().children().any(|n| n.kind() == AMP); |
659 | if borrowed { | 649 | if borrowed { |
660 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` | 650 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` |
661 | if self | 651 | if self.syntax().children().skip_while(|n| n.kind() != AMP).any(|n| n.kind() == MUT_KW) |
662 | .syntax() | ||
663 | .children() | ||
664 | .skip_while(|n| n.kind() != AMP) | ||
665 | .any(|n| n.kind() == MUT_KW) | ||
666 | { | 652 | { |
667 | SelfParamFlavor::MutRef | 653 | SelfParamFlavor::MutRef |
668 | } else { | 654 | } else { |
@@ -769,8 +755,5 @@ fn test_doc_comment_preserves_indents() { | |||
769 | "#, | 755 | "#, |
770 | ); | 756 | ); |
771 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); | 757 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); |
772 | assert_eq!( | 758 | assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); |
773 | "doc1\n```\nfn foo() {\n // ...\n}\n```", | ||
774 | module.doc_comment_text().unwrap() | ||
775 | ); | ||
776 | } | 759 | } |
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index 6b88c5685..28fcb1f7d 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs | |||
@@ -7,26 +7,17 @@ use super::*; | |||
7 | const EXPR_FIRST: TokenSet = LHS_FIRST; | 7 | const EXPR_FIRST: TokenSet = LHS_FIRST; |
8 | 8 | ||
9 | pub(super) fn expr(p: &mut Parser) -> BlockLike { | 9 | pub(super) fn expr(p: &mut Parser) -> BlockLike { |
10 | let r = Restrictions { | 10 | let r = Restrictions { forbid_structs: false, prefer_stmt: false }; |
11 | forbid_structs: false, | ||
12 | prefer_stmt: false, | ||
13 | }; | ||
14 | expr_bp(p, r, 1) | 11 | expr_bp(p, r, 1) |
15 | } | 12 | } |
16 | 13 | ||
17 | pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { | 14 | pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { |
18 | let r = Restrictions { | 15 | let r = Restrictions { forbid_structs: false, prefer_stmt: true }; |
19 | forbid_structs: false, | ||
20 | prefer_stmt: true, | ||
21 | }; | ||
22 | expr_bp(p, r, 1) | 16 | expr_bp(p, r, 1) |
23 | } | 17 | } |
24 | 18 | ||
25 | fn expr_no_struct(p: &mut Parser) { | 19 | fn expr_no_struct(p: &mut Parser) { |
26 | let r = Restrictions { | 20 | let r = Restrictions { forbid_structs: true, prefer_stmt: false }; |
27 | forbid_structs: true, | ||
28 | prefer_stmt: false, | ||
29 | }; | ||
30 | expr_bp(p, r, 1); | 21 | expr_bp(p, r, 1); |
31 | } | 22 | } |
32 | 23 | ||
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs index 600774afd..27ba87657 100644 --- a/crates/ra_syntax/src/grammar/expressions/atom.rs +++ b/crates/ra_syntax/src/grammar/expressions/atom.rs | |||
@@ -141,14 +141,7 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker { | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | p.expect(R_PAREN); | 143 | p.expect(R_PAREN); |
144 | m.complete( | 144 | m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR }) |
145 | p, | ||
146 | if saw_expr && !saw_comma { | ||
147 | PAREN_EXPR | ||
148 | } else { | ||
149 | TUPLE_EXPR | ||
150 | }, | ||
151 | ) | ||
152 | } | 145 | } |
153 | 146 | ||
154 | // test array_expr | 147 | // test array_expr |
diff --git a/crates/ra_syntax/src/grammar/items.rs b/crates/ra_syntax/src/grammar/items.rs index 84c18a293..a61f260cf 100644 --- a/crates/ra_syntax/src/grammar/items.rs +++ b/crates/ra_syntax/src/grammar/items.rs | |||
@@ -155,11 +155,7 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { | |||
155 | IMPL_BLOCK | 155 | IMPL_BLOCK |
156 | } | 156 | } |
157 | _ => { | 157 | _ => { |
158 | return if has_mods { | 158 | return if has_mods { MaybeItem::Modifiers } else { MaybeItem::None }; |
159 | MaybeItem::Modifiers | ||
160 | } else { | ||
161 | MaybeItem::None | ||
162 | }; | ||
163 | } | 159 | } |
164 | }; | 160 | }; |
165 | 161 | ||
diff --git a/crates/ra_syntax/src/grammar/params.rs b/crates/ra_syntax/src/grammar/params.rs index 13158429a..185386569 100644 --- a/crates/ra_syntax/src/grammar/params.rs +++ b/crates/ra_syntax/src/grammar/params.rs | |||
@@ -36,11 +36,7 @@ impl Flavor { | |||
36 | } | 36 | } |
37 | 37 | ||
38 | fn list_(p: &mut Parser, flavor: Flavor) { | 38 | fn list_(p: &mut Parser, flavor: Flavor) { |
39 | let (bra, ket) = if flavor.type_required() { | 39 | let (bra, ket) = if flavor.type_required() { (L_PAREN, R_PAREN) } else { (PIPE, PIPE) }; |
40 | (L_PAREN, R_PAREN) | ||
41 | } else { | ||
42 | (PIPE, PIPE) | ||
43 | }; | ||
44 | assert!(p.at(bra)); | 40 | assert!(p.at(bra)); |
45 | let m = p.start(); | 41 | let m = p.start(); |
46 | p.bump(); | 42 | p.bump(); |
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index 1ac5efdf6..f3f400ae0 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs | |||
@@ -2,9 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST | 3 | pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST |
4 | .union(paths::PATH_FIRST) | 4 | .union(paths::PATH_FIRST) |
5 | .union(token_set![ | 5 | .union(token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE]); |
6 | REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE | ||
7 | ]); | ||
8 | 6 | ||
9 | pub(super) fn pattern(p: &mut Parser) { | 7 | pub(super) fn pattern(p: &mut Parser) { |
10 | pattern_r(p, PAT_RECOVERY_SET) | 8 | pattern_r(p, PAT_RECOVERY_SET) |
diff --git a/crates/ra_syntax/src/lexer/ptr.rs b/crates/ra_syntax/src/lexer/ptr.rs index 0a473c991..c341c4176 100644 --- a/crates/ra_syntax/src/lexer/ptr.rs +++ b/crates/ra_syntax/src/lexer/ptr.rs | |||
@@ -11,10 +11,7 @@ pub(crate) struct Ptr<'s> { | |||
11 | impl<'s> Ptr<'s> { | 11 | impl<'s> Ptr<'s> { |
12 | /// Creates a new `Ptr` from a string. | 12 | /// Creates a new `Ptr` from a string. |
13 | pub fn new(text: &'s str) -> Ptr<'s> { | 13 | pub fn new(text: &'s str) -> Ptr<'s> { |
14 | Ptr { | 14 | Ptr { text, len: 0.into() } |
15 | text, | ||
16 | len: 0.into(), | ||
17 | } | ||
18 | } | 15 | } |
19 | 16 | ||
20 | /// Gets the length of the remaining string. | 17 | /// Gets the length of the remaining string. |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 104f32851..088b2f5d7 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -11,11 +11,7 @@ | |||
11 | //! [rfc#2256]: <https://github.com/rust-lang/rfcs/pull/2256> | 11 | //! [rfc#2256]: <https://github.com/rust-lang/rfcs/pull/2256> |
12 | //! [RFC.md]: <https://github.com/matklad/libsyntax2/blob/master/docs/RFC.md> | 12 | //! [RFC.md]: <https://github.com/matklad/libsyntax2/blob/master/docs/RFC.md> |
13 | 13 | ||
14 | #![forbid( | 14 | #![forbid(missing_debug_implementations, unconditional_recursion, future_incompatible)] |
15 | missing_debug_implementations, | ||
16 | unconditional_recursion, | ||
17 | future_incompatible | ||
18 | )] | ||
19 | #![deny(bad_style, missing_docs)] | 15 | #![deny(bad_style, missing_docs)] |
20 | #![allow(missing_docs)] | 16 | #![allow(missing_docs)] |
21 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 | 17 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 |
@@ -70,8 +66,7 @@ impl SourceFile { | |||
70 | } | 66 | } |
71 | 67 | ||
72 | pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { | 68 | pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { |
73 | self.incremental_reparse(edit) | 69 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) |
74 | .unwrap_or_else(|| self.full_reparse(edit)) | ||
75 | } | 70 | } |
76 | 71 | ||
77 | pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { | 72 | pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { |
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs index 3148371c5..504df753e 100644 --- a/crates/ra_syntax/src/parser_api.rs +++ b/crates/ra_syntax/src/parser_api.rs | |||
@@ -136,10 +136,7 @@ pub(crate) struct Marker { | |||
136 | 136 | ||
137 | impl Marker { | 137 | impl Marker { |
138 | fn new(pos: u32) -> Marker { | 138 | fn new(pos: u32) -> Marker { |
139 | Marker { | 139 | Marker { pos, bomb: DropBomb::new("Marker must be either completed or abandoned") } |
140 | pos, | ||
141 | bomb: DropBomb::new("Marker must be either completed or abandoned"), | ||
142 | } | ||
143 | } | 140 | } |
144 | 141 | ||
145 | /// Finishes the syntax tree node and assigns `kind` to it, | 142 | /// Finishes the syntax tree node and assigns `kind` to it, |
diff --git a/crates/ra_syntax/src/parser_impl.rs b/crates/ra_syntax/src/parser_impl.rs index 01a51cd8d..f255dc23b 100644 --- a/crates/ra_syntax/src/parser_impl.rs +++ b/crates/ra_syntax/src/parser_impl.rs | |||
@@ -54,9 +54,7 @@ pub(crate) fn parse_with<S: Sink>( | |||
54 | parser(&mut parser_api); | 54 | parser(&mut parser_api); |
55 | parser_api.0.into_events() | 55 | parser_api.0.into_events() |
56 | }; | 56 | }; |
57 | EventProcessor::new(sink, text, tokens, &mut events) | 57 | EventProcessor::new(sink, text, tokens, &mut events).process().finish() |
58 | .process() | ||
59 | .finish() | ||
60 | } | 58 | } |
61 | 59 | ||
62 | /// Implementation details of `Parser`, extracted | 60 | /// Implementation details of `Parser`, extracted |
@@ -160,17 +158,13 @@ impl<'t> ParserImpl<'t> { | |||
160 | 158 | ||
161 | /// Append one Error event to the back of events. | 159 | /// Append one Error event to the back of events. |
162 | pub(super) fn error(&mut self, msg: String) { | 160 | pub(super) fn error(&mut self, msg: String) { |
163 | self.push_event(Event::Error { | 161 | self.push_event(Event::Error { msg: ParseError(msg) }) |
164 | msg: ParseError(msg), | ||
165 | }) | ||
166 | } | 162 | } |
167 | 163 | ||
168 | /// Complete an event with appending a `Finish` event. | 164 | /// Complete an event with appending a `Finish` event. |
169 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { | 165 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { |
170 | match self.events[pos as usize] { | 166 | match self.events[pos as usize] { |
171 | Event::Start { | 167 | Event::Start { kind: ref mut slot, .. } => { |
172 | kind: ref mut slot, .. | ||
173 | } => { | ||
174 | *slot = kind; | 168 | *slot = kind; |
175 | } | 169 | } |
176 | _ => unreachable!(), | 170 | _ => unreachable!(), |
@@ -183,10 +177,7 @@ impl<'t> ParserImpl<'t> { | |||
183 | let idx = pos as usize; | 177 | let idx = pos as usize; |
184 | if idx == self.events.len() - 1 { | 178 | if idx == self.events.len() - 1 { |
185 | match self.events.pop() { | 179 | match self.events.pop() { |
186 | Some(Event::Start { | 180 | Some(Event::Start { kind: TOMBSTONE, forward_parent: None }) => (), |
187 | kind: TOMBSTONE, | ||
188 | forward_parent: None, | ||
189 | }) => (), | ||
190 | _ => unreachable!(), | 181 | _ => unreachable!(), |
191 | } | 182 | } |
192 | } | 183 | } |
@@ -196,10 +187,7 @@ impl<'t> ParserImpl<'t> { | |||
196 | pub(super) fn precede(&mut self, pos: u32) -> u32 { | 187 | pub(super) fn precede(&mut self, pos: u32) -> u32 { |
197 | let new_pos = self.start(); | 188 | let new_pos = self.start(); |
198 | match self.events[pos as usize] { | 189 | match self.events[pos as usize] { |
199 | Event::Start { | 190 | Event::Start { ref mut forward_parent, .. } => { |
200 | ref mut forward_parent, | ||
201 | .. | ||
202 | } => { | ||
203 | *forward_parent = Some(new_pos - pos); | 191 | *forward_parent = Some(new_pos - pos); |
204 | } | 192 | } |
205 | _ => unreachable!(), | 193 | _ => unreachable!(), |
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs index 33e10ef85..677876ab5 100644 --- a/crates/ra_syntax/src/parser_impl/event.rs +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -86,10 +86,7 @@ pub(crate) enum Event { | |||
86 | 86 | ||
87 | impl Event { | 87 | impl Event { |
88 | pub(crate) fn tombstone() -> Self { | 88 | pub(crate) fn tombstone() -> Self { |
89 | Event::Start { | 89 | Event::Start { kind: TOMBSTONE, forward_parent: None } |
90 | kind: TOMBSTONE, | ||
91 | forward_parent: None, | ||
92 | } | ||
93 | } | 90 | } |
94 | } | 91 | } |
95 | 92 | ||
@@ -109,14 +106,7 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
109 | tokens: &'a [Token], | 106 | tokens: &'a [Token], |
110 | events: &'a mut [Event], | 107 | events: &'a mut [Event], |
111 | ) -> EventProcessor<'a, S> { | 108 | ) -> EventProcessor<'a, S> { |
112 | EventProcessor { | 109 | EventProcessor { sink, text_pos: 0.into(), text, token_pos: 0, tokens, events } |
113 | sink, | ||
114 | text_pos: 0.into(), | ||
115 | text, | ||
116 | token_pos: 0, | ||
117 | tokens, | ||
118 | events, | ||
119 | } | ||
120 | } | 110 | } |
121 | 111 | ||
122 | /// Generate the syntax tree with the control of events. | 112 | /// Generate the syntax tree with the control of events. |
@@ -125,14 +115,9 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
125 | 115 | ||
126 | for i in 0..self.events.len() { | 116 | for i in 0..self.events.len() { |
127 | match mem::replace(&mut self.events[i], Event::tombstone()) { | 117 | match mem::replace(&mut self.events[i], Event::tombstone()) { |
128 | Event::Start { | 118 | Event::Start { kind: TOMBSTONE, .. } => (), |
129 | kind: TOMBSTONE, .. | ||
130 | } => (), | ||
131 | 119 | ||
132 | Event::Start { | 120 | Event::Start { kind, forward_parent } => { |
133 | kind, | ||
134 | forward_parent, | ||
135 | } => { | ||
136 | // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, | 121 | // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, |
137 | // in the normal control flow, the parent-child relation: `A -> B -> C`, | 122 | // in the normal control flow, the parent-child relation: `A -> B -> C`, |
138 | // while with the magic forward_parent, it writes: `C <- B <- A`. | 123 | // while with the magic forward_parent, it writes: `C <- B <- A`. |
@@ -145,10 +130,7 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
145 | idx += fwd as usize; | 130 | idx += fwd as usize; |
146 | // append `A`'s forward_parent `B` | 131 | // append `A`'s forward_parent `B` |
147 | fp = match mem::replace(&mut self.events[idx], Event::tombstone()) { | 132 | fp = match mem::replace(&mut self.events[idx], Event::tombstone()) { |
148 | Event::Start { | 133 | Event::Start { kind, forward_parent } => { |
149 | kind, | ||
150 | forward_parent, | ||
151 | } => { | ||
152 | forward_parents.push(kind); | 134 | forward_parents.push(kind); |
153 | forward_parent | 135 | forward_parent |
154 | } | 136 | } |
@@ -174,10 +156,9 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
174 | .sum::<TextUnit>(); | 156 | .sum::<TextUnit>(); |
175 | self.leaf(kind, len, n_raw_tokens); | 157 | self.leaf(kind, len, n_raw_tokens); |
176 | } | 158 | } |
177 | Event::Error { msg } => self.sink.error(SyntaxError::new( | 159 | Event::Error { msg } => self |
178 | SyntaxErrorKind::ParseError(msg), | 160 | .sink |
179 | self.text_pos, | 161 | .error(SyntaxError::new(SyntaxErrorKind::ParseError(msg), self.text_pos)), |
180 | )), | ||
181 | } | 162 | } |
182 | } | 163 | } |
183 | self.sink | 164 | self.sink |
@@ -189,10 +170,8 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
189 | self.sink.start_branch(kind); | 170 | self.sink.start_branch(kind); |
190 | return; | 171 | return; |
191 | } | 172 | } |
192 | let n_trivias = self.tokens[self.token_pos..] | 173 | let n_trivias = |
193 | .iter() | 174 | self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count(); |
194 | .take_while(|it| it.kind.is_trivia()) | ||
195 | .count(); | ||
196 | let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias]; | 175 | let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias]; |
197 | let mut trivia_end = | 176 | let mut trivia_end = |
198 | self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextUnit>(); | 177 | self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextUnit>(); |
diff --git a/crates/ra_syntax/src/parser_impl/input.rs b/crates/ra_syntax/src/parser_impl/input.rs index 7fde5b3ab..616a26fdc 100644 --- a/crates/ra_syntax/src/parser_impl/input.rs +++ b/crates/ra_syntax/src/parser_impl/input.rs | |||
@@ -36,11 +36,7 @@ impl<'t> ParserInput<'t> { | |||
36 | len += token.len; | 36 | len += token.len; |
37 | } | 37 | } |
38 | 38 | ||
39 | ParserInput { | 39 | ParserInput { text, start_offsets, tokens } |
40 | text, | ||
41 | start_offsets, | ||
42 | tokens, | ||
43 | } | ||
44 | } | 40 | } |
45 | 41 | ||
46 | /// Get the syntax kind of token at given input position. | 42 | /// Get the syntax kind of token at given input position. |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 13ee1305f..aae590cb6 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -15,16 +15,12 @@ pub struct SyntaxNodePtr { | |||
15 | 15 | ||
16 | impl SyntaxNodePtr { | 16 | impl SyntaxNodePtr { |
17 | pub fn new(node: &SyntaxNode) -> SyntaxNodePtr { | 17 | pub fn new(node: &SyntaxNode) -> SyntaxNodePtr { |
18 | SyntaxNodePtr { | 18 | SyntaxNodePtr { range: node.range(), kind: node.kind() } |
19 | range: node.range(), | ||
20 | kind: node.kind(), | ||
21 | } | ||
22 | } | 19 | } |
23 | 20 | ||
24 | pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode { | 21 | pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode { |
25 | generate(Some(source_file.syntax()), |&node| { | 22 | generate(Some(source_file.syntax()), |&node| { |
26 | node.children() | 23 | node.children().find(|it| self.range.is_subrange(&it.range())) |
27 | .find(|it| self.range.is_subrange(&it.range())) | ||
28 | }) | 24 | }) |
29 | .find(|it| it.range() == self.range && it.kind() == self.kind) | 25 | .find(|it| it.range() == self.range && it.kind() == self.kind) |
30 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | 26 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) |
@@ -55,10 +51,7 @@ impl<N: AstNode> Clone for AstPtr<N> { | |||
55 | 51 | ||
56 | impl<N: AstNode> AstPtr<N> { | 52 | impl<N: AstNode> AstPtr<N> { |
57 | pub fn new(node: &N) -> AstPtr<N> { | 53 | pub fn new(node: &N) -> AstPtr<N> { |
58 | AstPtr { | 54 | AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData } |
59 | raw: SyntaxNodePtr::new(node.syntax()), | ||
60 | _ty: PhantomData, | ||
61 | } | ||
62 | } | 55 | } |
63 | 56 | ||
64 | pub fn to_node(self, source_file: &SourceFile) -> &N { | 57 | pub fn to_node(self, source_file: &SourceFile) -> &N { |
@@ -76,11 +69,7 @@ fn test_local_syntax_ptr() { | |||
76 | use crate::{ast, AstNode}; | 69 | use crate::{ast, AstNode}; |
77 | 70 | ||
78 | let file = SourceFile::parse("struct Foo { f: u32, }"); | 71 | let file = SourceFile::parse("struct Foo { f: u32, }"); |
79 | let field = file | 72 | let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap(); |
80 | .syntax() | ||
81 | .descendants() | ||
82 | .find_map(ast::NamedFieldDef::cast) | ||
83 | .unwrap(); | ||
84 | let ptr = SyntaxNodePtr::new(field.syntax()); | 73 | let ptr = SyntaxNodePtr::new(field.syntax()); |
85 | let field_syntax = ptr.to_node(&file); | 74 | let field_syntax = ptr.to_node(&file); |
86 | assert_eq!(field.syntax(), &*field_syntax); | 75 | assert_eq!(field.syntax(), &*field_syntax); |
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs index 2f1de6b02..c5c609ad5 100644 --- a/crates/ra_syntax/src/reparsing.rs +++ b/crates/ra_syntax/src/reparsing.rs | |||
@@ -75,10 +75,7 @@ fn is_contextual_kw(text: &str) -> bool { | |||
75 | type ParseFn = fn(&mut Parser); | 75 | type ParseFn = fn(&mut Parser); |
76 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(&SyntaxNode, ParseFn)> { | 76 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(&SyntaxNode, ParseFn)> { |
77 | let node = algo::find_covering_node(node, range); | 77 | let node = algo::find_covering_node(node, range); |
78 | return node | 78 | return node.ancestors().filter_map(|node| reparser(node).map(|r| (node, r))).next(); |
79 | .ancestors() | ||
80 | .filter_map(|node| reparser(node).map(|r| (node, r))) | ||
81 | .next(); | ||
82 | 79 | ||
83 | fn reparser(node: &SyntaxNode) -> Option<ParseFn> { | 80 | fn reparser(node: &SyntaxNode) -> Option<ParseFn> { |
84 | let res = match node.kind() { | 81 | let res = match node.kind() { |
@@ -169,10 +166,7 @@ mod tests { | |||
169 | let fully_reparsed = SourceFile::parse(&after); | 166 | let fully_reparsed = SourceFile::parse(&after); |
170 | let incrementally_reparsed = { | 167 | let incrementally_reparsed = { |
171 | let f = SourceFile::parse(&before); | 168 | let f = SourceFile::parse(&before); |
172 | let edit = AtomTextEdit { | 169 | let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() }; |
173 | delete: range, | ||
174 | insert: replace_with.to_string(), | ||
175 | }; | ||
176 | let (node, green, new_errors) = | 170 | let (node, green, new_errors) = |
177 | reparser(f.syntax(), &edit).expect("cannot incrementally reparse"); | 171 | reparser(f.syntax(), &edit).expect("cannot incrementally reparse"); |
178 | let green_root = node.replace_with(green); | 172 | let green_root = node.replace_with(green); |
diff --git a/crates/ra_syntax/src/string_lexing/parser.rs b/crates/ra_syntax/src/string_lexing/parser.rs index e835382fc..7469eb903 100644 --- a/crates/ra_syntax/src/string_lexing/parser.rs +++ b/crates/ra_syntax/src/string_lexing/parser.rs | |||
@@ -24,9 +24,7 @@ impl<'a> Parser<'a> { | |||
24 | } | 24 | } |
25 | 25 | ||
26 | pub fn advance(&mut self) -> char { | 26 | pub fn advance(&mut self) -> char { |
27 | let next = self | 27 | let next = self.peek().expect("cannot advance if end of input is reached"); |
28 | .peek() | ||
29 | .expect("cannot advance if end of input is reached"); | ||
30 | self.pos += next.len_utf8(); | 28 | self.pos += next.len_utf8(); |
31 | next | 29 | next |
32 | } | 30 | } |
@@ -133,10 +131,7 @@ impl<'a> Parser<'a> { | |||
133 | Some(self.parse_escape(start)) | 131 | Some(self.parse_escape(start)) |
134 | } else { | 132 | } else { |
135 | let end = self.get_pos(); | 133 | let end = self.get_pos(); |
136 | Some(StringComponent::new( | 134 | Some(StringComponent::new(TextRange::from_to(start, end), CodePoint)) |
137 | TextRange::from_to(start, end), | ||
138 | CodePoint, | ||
139 | )) | ||
140 | } | 135 | } |
141 | } | 136 | } |
142 | 137 | ||
diff --git a/crates/ra_syntax/src/string_lexing/string.rs b/crates/ra_syntax/src/string_lexing/string.rs index 064f08544..a4742a0d1 100644 --- a/crates/ra_syntax/src/string_lexing/string.rs +++ b/crates/ra_syntax/src/string_lexing/string.rs | |||
@@ -120,12 +120,7 @@ mod tests { | |||
120 | fn closed_char_component(src: &str) -> StringComponent { | 120 | fn closed_char_component(src: &str) -> StringComponent { |
121 | let (has_closing_quote, components) = parse(src); | 121 | let (has_closing_quote, components) = parse(src); |
122 | assert!(has_closing_quote, "char should have closing quote"); | 122 | assert!(has_closing_quote, "char should have closing quote"); |
123 | assert!( | 123 | assert!(components.len() == 1, "Literal: {}\nComponents: {:#?}", src, components); |
124 | components.len() == 1, | ||
125 | "Literal: {}\nComponents: {:#?}", | ||
126 | src, | ||
127 | components | ||
128 | ); | ||
129 | components[0].clone() | 124 | components[0].clone() |
130 | } | 125 | } |
131 | 126 | ||
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs index 9e1949124..4e77c15b6 100644 --- a/crates/ra_syntax/src/validation/block.rs +++ b/crates/ra_syntax/src/validation/block.rs | |||
@@ -17,8 +17,6 @@ pub(crate) fn validate_block_node(node: &ast::Block, errors: &mut Vec<SyntaxErro | |||
17 | _ => {} | 17 | _ => {} |
18 | } | 18 | } |
19 | } | 19 | } |
20 | errors.extend( | 20 | errors |
21 | node.attrs() | 21 | .extend(node.attrs().map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range()))) |
22 | .map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range())), | ||
23 | ) | ||
24 | } | 22 | } |
diff --git a/crates/ra_syntax/src/validation/byte.rs b/crates/ra_syntax/src/validation/byte.rs index 9bddabc80..d51fabcf9 100644 --- a/crates/ra_syntax/src/validation/byte.rs +++ b/crates/ra_syntax/src/validation/byte.rs | |||
@@ -28,10 +28,7 @@ pub(super) fn validate_byte_node(node: &ast::Byte, errors: &mut Vec<SyntaxError> | |||
28 | } | 28 | } |
29 | 29 | ||
30 | if let Some(range) = components.suffix { | 30 | if let Some(range) = components.suffix { |
31 | errors.push(SyntaxError::new( | 31 | errors.push(SyntaxError::new(InvalidSuffix, range + literal_range.start())); |
32 | InvalidSuffix, | ||
33 | range + literal_range.start(), | ||
34 | )); | ||
35 | } | 32 | } |
36 | 33 | ||
37 | if len == 0 { | 34 | if len == 0 { |
@@ -55,10 +52,7 @@ pub(super) fn validate_byte_component( | |||
55 | AsciiCodeEscape => validate_byte_code_escape(text, range, errors), | 52 | AsciiCodeEscape => validate_byte_code_escape(text, range, errors), |
56 | UnicodeEscape => errors.push(SyntaxError::new(UnicodeEscapeForbidden, range)), | 53 | UnicodeEscape => errors.push(SyntaxError::new(UnicodeEscapeForbidden, range)), |
57 | CodePoint => { | 54 | CodePoint => { |
58 | let c = text | 55 | let c = text.chars().next().expect("Code points should be one character long"); |
59 | .chars() | ||
60 | .next() | ||
61 | .expect("Code points should be one character long"); | ||
62 | 56 | ||
63 | // These bytes must always be escaped | 57 | // These bytes must always be escaped |
64 | if c == '\t' || c == '\r' || c == '\n' { | 58 | if c == '\t' || c == '\r' || c == '\n' { |
@@ -93,10 +87,7 @@ fn validate_byte_code_escape(text: &str, range: TextRange, errors: &mut Vec<Synt | |||
93 | } else if text.chars().count() < 4 { | 87 | } else if text.chars().count() < 4 { |
94 | errors.push(SyntaxError::new(TooShortByteCodeEscape, range)); | 88 | errors.push(SyntaxError::new(TooShortByteCodeEscape, range)); |
95 | } else { | 89 | } else { |
96 | assert!( | 90 | assert!(text.chars().count() == 4, "ByteCodeEscape cannot be longer than 4 chars"); |
97 | text.chars().count() == 4, | ||
98 | "ByteCodeEscape cannot be longer than 4 chars" | ||
99 | ); | ||
100 | 91 | ||
101 | if u8::from_str_radix(&text[2..], 16).is_err() { | 92 | if u8::from_str_radix(&text[2..], 16).is_err() { |
102 | errors.push(SyntaxError::new(MalformedByteCodeEscape, range)); | 93 | errors.push(SyntaxError::new(MalformedByteCodeEscape, range)); |
@@ -115,12 +106,7 @@ mod test { | |||
115 | 106 | ||
116 | fn assert_valid_byte(literal: &str) { | 107 | fn assert_valid_byte(literal: &str) { |
117 | let file = build_file(literal); | 108 | let file = build_file(literal); |
118 | assert!( | 109 | assert!(file.errors().len() == 0, "Errors for literal '{}': {:?}", literal, file.errors()); |
119 | file.errors().len() == 0, | ||
120 | "Errors for literal '{}': {:?}", | ||
121 | literal, | ||
122 | file.errors() | ||
123 | ); | ||
124 | } | 110 | } |
125 | 111 | ||
126 | fn assert_invalid_byte(literal: &str) { | 112 | fn assert_invalid_byte(literal: &str) { |
@@ -193,13 +179,7 @@ mod test { | |||
193 | 179 | ||
194 | #[test] | 180 | #[test] |
195 | fn test_invalid_unicode_escape() { | 181 | fn test_invalid_unicode_escape() { |
196 | let well_formed = [ | 182 | let well_formed = [r"\u{FF}", r"\u{0}", r"\u{F}", r"\u{10FFFF}", r"\u{1_0__FF___FF_____}"]; |
197 | r"\u{FF}", | ||
198 | r"\u{0}", | ||
199 | r"\u{F}", | ||
200 | r"\u{10FFFF}", | ||
201 | r"\u{1_0__FF___FF_____}", | ||
202 | ]; | ||
203 | for c in &well_formed { | 183 | for c in &well_formed { |
204 | assert_invalid_byte(c); | 184 | assert_invalid_byte(c); |
205 | } | 185 | } |
diff --git a/crates/ra_syntax/src/validation/byte_string.rs b/crates/ra_syntax/src/validation/byte_string.rs index bdb147545..7abe8f330 100644 --- a/crates/ra_syntax/src/validation/byte_string.rs +++ b/crates/ra_syntax/src/validation/byte_string.rs | |||
@@ -34,10 +34,7 @@ pub(crate) fn validate_byte_string_node(node: &ast::ByteString, errors: &mut Vec | |||
34 | } | 34 | } |
35 | 35 | ||
36 | if let Some(range) = components.suffix { | 36 | if let Some(range) = components.suffix { |
37 | errors.push(SyntaxError::new( | 37 | errors.push(SyntaxError::new(InvalidSuffix, range + literal_range.start())); |
38 | InvalidSuffix, | ||
39 | range + literal_range.start(), | ||
40 | )); | ||
41 | } | 38 | } |
42 | } | 39 | } |
43 | 40 | ||
@@ -53,12 +50,7 @@ mod test { | |||
53 | 50 | ||
54 | fn assert_valid_str(literal: &str) { | 51 | fn assert_valid_str(literal: &str) { |
55 | let file = build_file(literal); | 52 | let file = build_file(literal); |
56 | assert!( | 53 | assert!(file.errors().len() == 0, "Errors for literal '{}': {:?}", literal, file.errors()); |
57 | file.errors().len() == 0, | ||
58 | "Errors for literal '{}': {:?}", | ||
59 | literal, | ||
60 | file.errors() | ||
61 | ); | ||
62 | } | 54 | } |
63 | 55 | ||
64 | fn assert_invalid_str(literal: &str) { | 56 | fn assert_invalid_str(literal: &str) { |
@@ -130,13 +122,7 @@ mod test { | |||
130 | 122 | ||
131 | #[test] | 123 | #[test] |
132 | fn test_invalid_unicode_escape() { | 124 | fn test_invalid_unicode_escape() { |
133 | let well_formed = [ | 125 | let well_formed = [r"\u{FF}", r"\u{0}", r"\u{F}", r"\u{10FFFF}", r"\u{1_0__FF___FF_____}"]; |
134 | r"\u{FF}", | ||
135 | r"\u{0}", | ||
136 | r"\u{F}", | ||
137 | r"\u{10FFFF}", | ||
138 | r"\u{1_0__FF___FF_____}", | ||
139 | ]; | ||
140 | for c in &well_formed { | 126 | for c in &well_formed { |
141 | assert_invalid_str(c); | 127 | assert_invalid_str(c); |
142 | } | 128 | } |
diff --git a/crates/ra_syntax/src/validation/char.rs b/crates/ra_syntax/src/validation/char.rs index e3ac5836b..012594db3 100644 --- a/crates/ra_syntax/src/validation/char.rs +++ b/crates/ra_syntax/src/validation/char.rs | |||
@@ -31,10 +31,7 @@ pub(super) fn validate_char_node(node: &ast::Char, errors: &mut Vec<SyntaxError> | |||
31 | } | 31 | } |
32 | 32 | ||
33 | if let Some(range) = components.suffix { | 33 | if let Some(range) = components.suffix { |
34 | errors.push(SyntaxError::new( | 34 | errors.push(SyntaxError::new(InvalidSuffix, range + literal_range.start())); |
35 | InvalidSuffix, | ||
36 | range + literal_range.start(), | ||
37 | )); | ||
38 | } | 35 | } |
39 | 36 | ||
40 | if len == 0 { | 37 | if len == 0 { |
@@ -184,12 +181,7 @@ mod test { | |||
184 | 181 | ||
185 | fn assert_valid_char(literal: &str) { | 182 | fn assert_valid_char(literal: &str) { |
186 | let file = build_file(literal); | 183 | let file = build_file(literal); |
187 | assert!( | 184 | assert!(file.errors().len() == 0, "Errors for literal '{}': {:?}", literal, file.errors()); |
188 | file.errors().len() == 0, | ||
189 | "Errors for literal '{}': {:?}", | ||
190 | literal, | ||
191 | file.errors() | ||
192 | ); | ||
193 | } | 185 | } |
194 | 186 | ||
195 | fn assert_invalid_char(literal: &str) { | 187 | fn assert_invalid_char(literal: &str) { |
@@ -258,13 +250,7 @@ mod test { | |||
258 | 250 | ||
259 | #[test] | 251 | #[test] |
260 | fn test_valid_unicode_escape() { | 252 | fn test_valid_unicode_escape() { |
261 | let valid = [ | 253 | let valid = [r"\u{FF}", r"\u{0}", r"\u{F}", r"\u{10FFFF}", r"\u{1_0__FF___FF_____}"]; |
262 | r"\u{FF}", | ||
263 | r"\u{0}", | ||
264 | r"\u{F}", | ||
265 | r"\u{10FFFF}", | ||
266 | r"\u{1_0__FF___FF_____}", | ||
267 | ]; | ||
268 | for c in &valid { | 254 | for c in &valid { |
269 | assert_valid_char(c); | 255 | assert_valid_char(c); |
270 | } | 256 | } |
diff --git a/crates/ra_syntax/src/validation/string.rs b/crates/ra_syntax/src/validation/string.rs index 365fe8d2d..4fd7fffdf 100644 --- a/crates/ra_syntax/src/validation/string.rs +++ b/crates/ra_syntax/src/validation/string.rs | |||
@@ -29,10 +29,7 @@ pub(crate) fn validate_string_node(node: &ast::String, errors: &mut Vec<SyntaxEr | |||
29 | } | 29 | } |
30 | 30 | ||
31 | if let Some(range) = components.suffix { | 31 | if let Some(range) = components.suffix { |
32 | errors.push(SyntaxError::new( | 32 | errors.push(SyntaxError::new(InvalidSuffix, range + literal_range.start())); |
33 | InvalidSuffix, | ||
34 | range + literal_range.start(), | ||
35 | )); | ||
36 | } | 33 | } |
37 | } | 34 | } |
38 | 35 | ||
@@ -48,12 +45,7 @@ mod test { | |||
48 | 45 | ||
49 | fn assert_valid_str(literal: &str) { | 46 | fn assert_valid_str(literal: &str) { |
50 | let file = build_file(literal); | 47 | let file = build_file(literal); |
51 | assert!( | 48 | assert!(file.errors().len() == 0, "Errors for literal '{}': {:?}", literal, file.errors()); |
52 | file.errors().len() == 0, | ||
53 | "Errors for literal '{}': {:?}", | ||
54 | literal, | ||
55 | file.errors() | ||
56 | ); | ||
57 | } | 49 | } |
58 | 50 | ||
59 | fn assert_invalid_str(literal: &str) { | 51 | fn assert_invalid_str(literal: &str) { |
@@ -121,13 +113,7 @@ mod test { | |||
121 | 113 | ||
122 | #[test] | 114 | #[test] |
123 | fn test_valid_unicode_escape() { | 115 | fn test_valid_unicode_escape() { |
124 | let valid = [ | 116 | let valid = [r"\u{FF}", r"\u{0}", r"\u{F}", r"\u{10FFFF}", r"\u{1_0__FF___FF_____}"]; |
125 | r"\u{FF}", | ||
126 | r"\u{0}", | ||
127 | r"\u{F}", | ||
128 | r"\u{10FFFF}", | ||
129 | r"\u{1_0__FF___FF_____}", | ||
130 | ]; | ||
131 | for c in &valid { | 117 | for c in &valid { |
132 | assert_valid_str(c); | 118 | assert_valid_str(c); |
133 | } | 119 | } |
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs index 37ae6329b..e8b9112d4 100644 --- a/crates/ra_syntax/src/yellow/builder.rs +++ b/crates/ra_syntax/src/yellow/builder.rs | |||
@@ -12,10 +12,7 @@ pub(crate) struct GreenBuilder { | |||
12 | 12 | ||
13 | impl GreenBuilder { | 13 | impl GreenBuilder { |
14 | pub(crate) fn new() -> GreenBuilder { | 14 | pub(crate) fn new() -> GreenBuilder { |
15 | GreenBuilder { | 15 | GreenBuilder { errors: Vec::new(), inner: GreenNodeBuilder::new() } |
16 | errors: Vec::new(), | ||
17 | inner: GreenNodeBuilder::new(), | ||
18 | } | ||
19 | } | 16 | } |
20 | } | 17 | } |
21 | 18 | ||
diff --git a/crates/ra_syntax/src/yellow/syntax_error.rs b/crates/ra_syntax/src/yellow/syntax_error.rs index c52c44cc3..412cf82cc 100644 --- a/crates/ra_syntax/src/yellow/syntax_error.rs +++ b/crates/ra_syntax/src/yellow/syntax_error.rs | |||
@@ -28,10 +28,7 @@ impl Into<Location> for TextRange { | |||
28 | 28 | ||
29 | impl SyntaxError { | 29 | impl SyntaxError { |
30 | pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { | 30 | pub fn new<L: Into<Location>>(kind: SyntaxErrorKind, loc: L) -> SyntaxError { |
31 | SyntaxError { | 31 | SyntaxError { kind, location: loc.into() } |
32 | kind, | ||
33 | location: loc.into(), | ||
34 | } | ||
35 | } | 32 | } |
36 | 33 | ||
37 | pub fn kind(&self) -> SyntaxErrorKind { | 34 | pub fn kind(&self) -> SyntaxErrorKind { |
@@ -119,10 +116,9 @@ impl fmt::Display for SyntaxErrorKind { | |||
119 | InvalidByteEscape => write!(f, "Invalid escape sequence"), | 116 | InvalidByteEscape => write!(f, "Invalid escape sequence"), |
120 | TooShortByteCodeEscape => write!(f, "Escape sequence should have two digits"), | 117 | TooShortByteCodeEscape => write!(f, "Escape sequence should have two digits"), |
121 | MalformedByteCodeEscape => write!(f, "Escape sequence should be a hexadecimal number"), | 118 | MalformedByteCodeEscape => write!(f, "Escape sequence should be a hexadecimal number"), |
122 | UnicodeEscapeForbidden => write!( | 119 | UnicodeEscapeForbidden => { |
123 | f, | 120 | write!(f, "Unicode escapes are not allowed in byte literals or byte strings") |
124 | "Unicode escapes are not allowed in byte literals or byte strings" | 121 | } |
125 | ), | ||
126 | TooShortAsciiCodeEscape => write!(f, "Escape sequence should have two digits"), | 122 | TooShortAsciiCodeEscape => write!(f, "Escape sequence should have two digits"), |
127 | AsciiCodeEscapeOutOfRange => { | 123 | AsciiCodeEscapeOutOfRange => { |
128 | write!(f, "Escape sequence should be between \\x00 and \\x7F") | 124 | write!(f, "Escape sequence should be between \\x00 and \\x7F") |
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs index 378cd1b2e..84e5b231a 100644 --- a/crates/ra_syntax/src/yellow/syntax_text.rs +++ b/crates/ra_syntax/src/yellow/syntax_text.rs | |||
@@ -10,10 +10,7 @@ pub struct SyntaxText<'a> { | |||
10 | 10 | ||
11 | impl<'a> SyntaxText<'a> { | 11 | impl<'a> SyntaxText<'a> { |
12 | pub(crate) fn new(node: &'a SyntaxNode) -> SyntaxText<'a> { | 12 | pub(crate) fn new(node: &'a SyntaxNode) -> SyntaxText<'a> { |
13 | SyntaxText { | 13 | SyntaxText { node, range: node.range() } |
14 | node, | ||
15 | range: node.range(), | ||
16 | } | ||
17 | } | 14 | } |
18 | 15 | ||
19 | pub fn chunks(&self) -> impl Iterator<Item = &'a str> { | 16 | pub fn chunks(&self) -> impl Iterator<Item = &'a str> { |
@@ -58,10 +55,7 @@ impl<'a> SyntaxText<'a> { | |||
58 | let range = range.restrict(self.range).unwrap_or_else(|| { | 55 | let range = range.restrict(self.range).unwrap_or_else(|| { |
59 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) | 56 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) |
60 | }); | 57 | }); |
61 | SyntaxText { | 58 | SyntaxText { node: self.node, range } |
62 | node: self.node, | ||
63 | range, | ||
64 | } | ||
65 | } | 59 | } |
66 | 60 | ||
67 | pub fn char_at(&self, offset: impl Into<TextUnit>) -> Option<char> { | 61 | pub fn char_at(&self, offset: impl Into<TextUnit>) -> Option<char> { |
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs index 3243b27ae..168d0623d 100644 --- a/crates/ra_syntax/tests/test.rs +++ b/crates/ra_syntax/tests/test.rs | |||
@@ -23,36 +23,28 @@ fn lexer_tests() { | |||
23 | 23 | ||
24 | #[test] | 24 | #[test] |
25 | fn parser_tests() { | 25 | fn parser_tests() { |
26 | dir_tests( | 26 | dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { |
27 | &test_data_dir(), | 27 | let file = SourceFile::parse(text); |
28 | &["parser/inline/ok", "parser/ok"], | 28 | let errors = file.errors(); |
29 | |text, path| { | 29 | assert_eq!( |
30 | let file = SourceFile::parse(text); | 30 | &*errors, |
31 | let errors = file.errors(); | 31 | &[] as &[ra_syntax::SyntaxError], |
32 | assert_eq!( | 32 | "There should be no errors in the file {:?}", |
33 | &*errors, | 33 | path.display() |
34 | &[] as &[ra_syntax::SyntaxError], | 34 | ); |
35 | "There should be no errors in the file {:?}", | 35 | dump_tree(file.syntax()) |
36 | path.display() | 36 | }); |
37 | ); | 37 | dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { |
38 | dump_tree(file.syntax()) | 38 | let file = SourceFile::parse(text); |
39 | }, | 39 | let errors = file.errors(); |
40 | ); | 40 | assert_ne!( |
41 | dir_tests( | 41 | &*errors, |
42 | &test_data_dir(), | 42 | &[] as &[ra_syntax::SyntaxError], |
43 | &["parser/err", "parser/inline/err"], | 43 | "There should be errors in the file {:?}", |
44 | |text, path| { | 44 | path.display() |
45 | let file = SourceFile::parse(text); | 45 | ); |
46 | let errors = file.errors(); | 46 | dump_tree(file.syntax()) |
47 | assert_ne!( | 47 | }); |
48 | &*errors, | ||
49 | &[] as &[ra_syntax::SyntaxError], | ||
50 | "There should be errors in the file {:?}", | ||
51 | path.display() | ||
52 | ); | ||
53 | dump_tree(file.syntax()) | ||
54 | }, | ||
55 | ); | ||
56 | } | 48 | } |
57 | 49 | ||
58 | #[test] | 50 | #[test] |
@@ -87,12 +79,7 @@ fn self_hosting_parsing() { | |||
87 | let text = read_text(entry.path()); | 79 | let text = read_text(entry.path()); |
88 | let node = SourceFile::parse(&text); | 80 | let node = SourceFile::parse(&text); |
89 | let errors = node.errors(); | 81 | let errors = node.errors(); |
90 | assert_eq!( | 82 | assert_eq!(&*errors, &[], "There should be no errors in the file {:?}", entry); |
91 | &*errors, | ||
92 | &[], | ||
93 | "There should be no errors in the file {:?}", | ||
94 | entry | ||
95 | ); | ||
96 | } | 83 | } |
97 | assert!( | 84 | assert!( |
98 | count > 30, | 85 | count > 30, |
diff --git a/crates/ra_text_edit/src/lib.rs b/crates/ra_text_edit/src/lib.rs index fb693b3ae..df673ba18 100644 --- a/crates/ra_text_edit/src/lib.rs +++ b/crates/ra_text_edit/src/lib.rs | |||
@@ -15,10 +15,7 @@ pub struct AtomTextEdit { | |||
15 | 15 | ||
16 | impl AtomTextEdit { | 16 | impl AtomTextEdit { |
17 | pub fn replace(range: TextRange, replace_with: String) -> AtomTextEdit { | 17 | pub fn replace(range: TextRange, replace_with: String) -> AtomTextEdit { |
18 | AtomTextEdit { | 18 | AtomTextEdit { delete: range, insert: replace_with } |
19 | delete: range, | ||
20 | insert: replace_with, | ||
21 | } | ||
22 | } | 19 | } |
23 | 20 | ||
24 | pub fn delete(range: TextRange) -> AtomTextEdit { | 21 | pub fn delete(range: TextRange) -> AtomTextEdit { |
diff --git a/crates/ra_text_edit/src/test_utils.rs b/crates/ra_text_edit/src/test_utils.rs index 745f21c93..9e21b24f6 100644 --- a/crates/ra_text_edit/src/test_utils.rs +++ b/crates/ra_text_edit/src/test_utils.rs | |||
@@ -8,9 +8,7 @@ pub fn arb_text() -> proptest::string::RegexGeneratorStrategy<String> { | |||
8 | } | 8 | } |
9 | 9 | ||
10 | fn text_offsets(text: &str) -> Vec<TextUnit> { | 10 | fn text_offsets(text: &str) -> Vec<TextUnit> { |
11 | text.char_indices() | 11 | text.char_indices().map(|(i, _)| TextUnit::from_usize(i)).collect() |
12 | .map(|(i, _)| TextUnit::from_usize(i)) | ||
13 | .collect() | ||
14 | } | 12 | } |
15 | 13 | ||
16 | pub fn arb_offset(text: &str) -> BoxedStrategy<TextUnit> { | 14 | pub fn arb_offset(text: &str) -> BoxedStrategy<TextUnit> { |
@@ -56,9 +54,7 @@ pub fn arb_text_edit(text: &str) -> BoxedStrategy<TextEdit> { | |||
56 | ) | 54 | ) |
57 | .boxed() | 55 | .boxed() |
58 | } | 56 | } |
59 | &[x] => arb_text() | 57 | &[x] => arb_text().prop_map(move |text| AtomTextEdit::insert(x, text)).boxed(), |
60 | .prop_map(move |text| AtomTextEdit::insert(x, text)) | ||
61 | .boxed(), | ||
62 | _ => unreachable!(), | 58 | _ => unreachable!(), |
63 | }) | 59 | }) |
64 | .collect(); | 60 | .collect(); |
diff --git a/crates/ra_text_edit/src/text_edit.rs b/crates/ra_text_edit/src/text_edit.rs index 363b3d8c0..8522f99bd 100644 --- a/crates/ra_text_edit/src/text_edit.rs +++ b/crates/ra_text_edit/src/text_edit.rs | |||
@@ -25,9 +25,7 @@ impl TextEditBuilder { | |||
25 | TextEdit::from_atoms(self.atoms) | 25 | TextEdit::from_atoms(self.atoms) |
26 | } | 26 | } |
27 | pub fn invalidates_offset(&self, offset: TextUnit) -> bool { | 27 | pub fn invalidates_offset(&self, offset: TextUnit) -> bool { |
28 | self.atoms | 28 | self.atoms.iter().any(|atom| atom.delete.contains_inclusive(offset)) |
29 | .iter() | ||
30 | .any(|atom| atom.delete.contains_inclusive(offset)) | ||
31 | } | 29 | } |
32 | } | 30 | } |
33 | 31 | ||
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index d764c534a..ff5ae3a19 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs | |||
@@ -14,32 +14,15 @@ use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watc | |||
14 | use crate::{RootConfig, Roots, VfsRoot}; | 14 | use crate::{RootConfig, Roots, VfsRoot}; |
15 | 15 | ||
16 | pub(crate) enum Task { | 16 | pub(crate) enum Task { |
17 | AddRoot { | 17 | AddRoot { root: VfsRoot, config: Arc<RootConfig> }, |
18 | root: VfsRoot, | ||
19 | config: Arc<RootConfig>, | ||
20 | }, | ||
21 | } | 18 | } |
22 | 19 | ||
23 | #[derive(Debug)] | 20 | #[derive(Debug)] |
24 | pub enum TaskResult { | 21 | pub enum TaskResult { |
25 | BulkLoadRoot { | 22 | BulkLoadRoot { root: VfsRoot, files: Vec<(RelativePathBuf, String)> }, |
26 | root: VfsRoot, | 23 | AddSingleFile { root: VfsRoot, path: RelativePathBuf, text: String }, |
27 | files: Vec<(RelativePathBuf, String)>, | 24 | ChangeSingleFile { root: VfsRoot, path: RelativePathBuf, text: String }, |
28 | }, | 25 | RemoveSingleFile { root: VfsRoot, path: RelativePathBuf }, |
29 | AddSingleFile { | ||
30 | root: VfsRoot, | ||
31 | path: RelativePathBuf, | ||
32 | text: String, | ||
33 | }, | ||
34 | ChangeSingleFile { | ||
35 | root: VfsRoot, | ||
36 | path: RelativePathBuf, | ||
37 | text: String, | ||
38 | }, | ||
39 | RemoveSingleFile { | ||
40 | root: VfsRoot, | ||
41 | path: RelativePathBuf, | ||
42 | }, | ||
43 | } | 26 | } |
44 | 27 | ||
45 | #[derive(Debug)] | 28 | #[derive(Debug)] |
@@ -127,10 +110,7 @@ impl Worker { | |||
127 | }, | 110 | }, |
128 | ); | 111 | ); |
129 | 112 | ||
130 | Worker { | 113 | Worker { worker, worker_handle } |
131 | worker, | ||
132 | worker_handle, | ||
133 | } | ||
134 | } | 114 | } |
135 | 115 | ||
136 | pub(crate) fn sender(&self) -> &Sender<Task> { | 116 | pub(crate) fn sender(&self) -> &Sender<Task> { |
@@ -162,9 +142,7 @@ fn watch_root( | |||
162 | Some((path, text)) | 142 | Some((path, text)) |
163 | }) | 143 | }) |
164 | .collect(); | 144 | .collect(); |
165 | sender | 145 | sender.send(TaskResult::BulkLoadRoot { root, files }).unwrap(); |
166 | .send(TaskResult::BulkLoadRoot { root, files }) | ||
167 | .unwrap(); | ||
168 | log::debug!("... loaded {}", config.root.as_path().display()); | 146 | log::debug!("... loaded {}", config.root.as_path().display()); |
169 | } | 147 | } |
170 | 148 | ||
@@ -233,21 +211,12 @@ fn handle_change( | |||
233 | } | 211 | } |
234 | ChangeKind::Write => { | 212 | ChangeKind::Write => { |
235 | if let Some(text) = read_to_string(&path) { | 213 | if let Some(text) = read_to_string(&path) { |
236 | sender | 214 | sender.send(TaskResult::ChangeSingleFile { root, path: rel_path, text }).unwrap(); |
237 | .send(TaskResult::ChangeSingleFile { | ||
238 | root, | ||
239 | path: rel_path, | ||
240 | text, | ||
241 | }) | ||
242 | .unwrap(); | ||
243 | } | 215 | } |
244 | } | 216 | } |
245 | ChangeKind::Remove => sender | 217 | ChangeKind::Remove => { |
246 | .send(TaskResult::RemoveSingleFile { | 218 | sender.send(TaskResult::RemoveSingleFile { root, path: rel_path }).unwrap() |
247 | root, | 219 | } |
248 | path: rel_path, | ||
249 | }) | ||
250 | .unwrap(), | ||
251 | } | 220 | } |
252 | } | 221 | } |
253 | 222 | ||
@@ -282,7 +251,5 @@ fn watch_one(watcher: &mut RecommendedWatcher, dir: &Path) { | |||
282 | } | 251 | } |
283 | 252 | ||
284 | fn read_to_string(path: &Path) -> Option<String> { | 253 | fn read_to_string(path: &Path) -> Option<String> { |
285 | fs::read_to_string(&path) | 254 | fs::read_to_string(&path).map_err(|e| log::warn!("failed to read file {}", e)).ok() |
286 | .map_err(|e| log::warn!("failed to read file {}", e)) | ||
287 | .ok() | ||
288 | } | 255 | } |
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 71a3f807d..6b4eb6842 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs | |||
@@ -58,10 +58,7 @@ impl std::ops::Deref for Roots { | |||
58 | 58 | ||
59 | impl RootConfig { | 59 | impl RootConfig { |
60 | fn new(root: PathBuf, excluded_dirs: Vec<PathBuf>) -> RootConfig { | 60 | fn new(root: PathBuf, excluded_dirs: Vec<PathBuf>) -> RootConfig { |
61 | RootConfig { | 61 | RootConfig { root, excluded_dirs } |
62 | root, | ||
63 | excluded_dirs, | ||
64 | } | ||
65 | } | 62 | } |
66 | /// Cheks if root contains a path and returns a root-relative path. | 63 | /// Cheks if root contains a path and returns a root-relative path. |
67 | pub(crate) fn contains(&self, path: &Path) -> Option<RelativePathBuf> { | 64 | pub(crate) fn contains(&self, path: &Path) -> Option<RelativePathBuf> { |
@@ -111,9 +108,7 @@ impl Roots { | |||
111 | Roots { roots } | 108 | Roots { roots } |
112 | } | 109 | } |
113 | pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> { | 110 | pub(crate) fn find(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf)> { |
114 | self.roots | 111 | self.roots.iter().find_map(|(root, data)| data.contains(path).map(|it| (root, it))) |
115 | .iter() | ||
116 | .find_map(|(root, data)| data.contains(path).map(|it| (root, it))) | ||
117 | } | 112 | } |
118 | } | 113 | } |
119 | 114 | ||
@@ -154,21 +149,10 @@ impl Vfs { | |||
154 | 149 | ||
155 | for (root, config) in roots.iter() { | 150 | for (root, config) in roots.iter() { |
156 | root2files.insert(root, Default::default()); | 151 | root2files.insert(root, Default::default()); |
157 | worker | 152 | worker.sender().send(io::Task::AddRoot { root, config: Arc::clone(config) }).unwrap(); |
158 | .sender() | ||
159 | .send(io::Task::AddRoot { | ||
160 | root, | ||
161 | config: Arc::clone(config), | ||
162 | }) | ||
163 | .unwrap(); | ||
164 | } | 153 | } |
165 | let res = Vfs { | 154 | let res = |
166 | roots, | 155 | Vfs { roots, files: Arena::default(), root2files, worker, pending_changes: Vec::new() }; |
167 | files: Arena::default(), | ||
168 | root2files, | ||
169 | worker, | ||
170 | pending_changes: Vec::new(), | ||
171 | }; | ||
172 | let vfs_roots = res.roots.iter().map(|(id, _)| id).collect(); | 156 | let vfs_roots = res.roots.iter().map(|(id, _)| id).collect(); |
173 | (res, vfs_roots) | 157 | (res, vfs_roots) |
174 | } | 158 | } |
@@ -205,12 +189,7 @@ impl Vfs { | |||
205 | let text = fs::read_to_string(path).unwrap_or_default(); | 189 | let text = fs::read_to_string(path).unwrap_or_default(); |
206 | let text = Arc::new(text); | 190 | let text = Arc::new(text); |
207 | let file = self.add_file(root, rel_path.clone(), Arc::clone(&text), false); | 191 | let file = self.add_file(root, rel_path.clone(), Arc::clone(&text), false); |
208 | let change = VfsChange::AddFile { | 192 | let change = VfsChange::AddFile { file, text, root, path: rel_path }; |
209 | file, | ||
210 | text, | ||
211 | root, | ||
212 | path: rel_path, | ||
213 | }; | ||
214 | self.pending_changes.push(change); | 193 | self.pending_changes.push(change); |
215 | Some(file) | 194 | Some(file) |
216 | }; | 195 | }; |
@@ -243,10 +222,7 @@ impl Vfs { | |||
243 | cur_files.push((file, path, text)); | 222 | cur_files.push((file, path, text)); |
244 | } | 223 | } |
245 | 224 | ||
246 | let change = VfsChange::AddRoot { | 225 | let change = VfsChange::AddRoot { root, files: cur_files }; |
247 | root, | ||
248 | files: cur_files, | ||
249 | }; | ||
250 | self.pending_changes.push(change); | 226 | self.pending_changes.push(change); |
251 | } | 227 | } |
252 | TaskResult::AddSingleFile { root, path, text } => { | 228 | TaskResult::AddSingleFile { root, path, text } => { |
@@ -278,12 +254,7 @@ impl Vfs { | |||
278 | ) -> Option<VfsFile> { | 254 | ) -> Option<VfsFile> { |
279 | let text = Arc::new(text); | 255 | let text = Arc::new(text); |
280 | let file = self.add_file(root, path.clone(), text.clone(), is_overlay); | 256 | let file = self.add_file(root, path.clone(), text.clone(), is_overlay); |
281 | self.pending_changes.push(VfsChange::AddFile { | 257 | self.pending_changes.push(VfsChange::AddFile { file, root, path, text }); |
282 | file, | ||
283 | root, | ||
284 | path, | ||
285 | text, | ||
286 | }); | ||
287 | Some(file) | 258 | Some(file) |
288 | } | 259 | } |
289 | 260 | ||
@@ -293,8 +264,7 @@ impl Vfs { | |||
293 | } | 264 | } |
294 | let text = Arc::new(text); | 265 | let text = Arc::new(text); |
295 | self.change_file(file, text.clone(), is_overlay); | 266 | self.change_file(file, text.clone(), is_overlay); |
296 | self.pending_changes | 267 | self.pending_changes.push(VfsChange::ChangeFile { file, text }); |
297 | .push(VfsChange::ChangeFile { file, text }); | ||
298 | } | 268 | } |
299 | 269 | ||
300 | fn do_remove_file( | 270 | fn do_remove_file( |
@@ -308,8 +278,7 @@ impl Vfs { | |||
308 | return; | 278 | return; |
309 | } | 279 | } |
310 | self.remove_file(file); | 280 | self.remove_file(file); |
311 | self.pending_changes | 281 | self.pending_changes.push(VfsChange::RemoveFile { root, path, file }); |
312 | .push(VfsChange::RemoveFile { root, path, file }); | ||
313 | } | 282 | } |
314 | 283 | ||
315 | pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { | 284 | pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { |
@@ -363,12 +332,7 @@ impl Vfs { | |||
363 | text: Arc<String>, | 332 | text: Arc<String>, |
364 | is_overlayed: bool, | 333 | is_overlayed: bool, |
365 | ) -> VfsFile { | 334 | ) -> VfsFile { |
366 | let data = VfsFileData { | 335 | let data = VfsFileData { root, path, text, is_overlayed }; |
367 | root, | ||
368 | path, | ||
369 | text, | ||
370 | is_overlayed, | ||
371 | }; | ||
372 | let file = self.files.alloc(data); | 336 | let file = self.files.alloc(data); |
373 | self.root2files.get_mut(root).unwrap().insert(file); | 337 | self.root2files.get_mut(root).unwrap().insert(file); |
374 | file | 338 | file |
@@ -396,32 +360,14 @@ impl Vfs { | |||
396 | } | 360 | } |
397 | 361 | ||
398 | fn find_file(&self, root: VfsRoot, path: &RelativePath) -> Option<VfsFile> { | 362 | fn find_file(&self, root: VfsRoot, path: &RelativePath) -> Option<VfsFile> { |
399 | self.root2files[root] | 363 | self.root2files[root].iter().map(|&it| it).find(|&file| self.files[file].path == path) |
400 | .iter() | ||
401 | .map(|&it| it) | ||
402 | .find(|&file| self.files[file].path == path) | ||
403 | } | 364 | } |
404 | } | 365 | } |
405 | 366 | ||
406 | #[derive(Debug, Clone)] | 367 | #[derive(Debug, Clone)] |
407 | pub enum VfsChange { | 368 | pub enum VfsChange { |
408 | AddRoot { | 369 | AddRoot { root: VfsRoot, files: Vec<(VfsFile, RelativePathBuf, Arc<String>)> }, |
409 | root: VfsRoot, | 370 | AddFile { root: VfsRoot, file: VfsFile, path: RelativePathBuf, text: Arc<String> }, |
410 | files: Vec<(VfsFile, RelativePathBuf, Arc<String>)>, | 371 | RemoveFile { root: VfsRoot, file: VfsFile, path: RelativePathBuf }, |
411 | }, | 372 | ChangeFile { file: VfsFile, text: Arc<String> }, |
412 | AddFile { | ||
413 | root: VfsRoot, | ||
414 | file: VfsFile, | ||
415 | path: RelativePathBuf, | ||
416 | text: Arc<String>, | ||
417 | }, | ||
418 | RemoveFile { | ||
419 | root: VfsRoot, | ||
420 | file: VfsFile, | ||
421 | path: RelativePathBuf, | ||
422 | }, | ||
423 | ChangeFile { | ||
424 | file: VfsFile, | ||
425 | text: Arc<String>, | ||
426 | }, | ||
427 | } | 373 | } |
diff --git a/crates/ra_vfs/tests/vfs.rs b/crates/ra_vfs/tests/vfs.rs index 545e1dbdd..649ef96c9 100644 --- a/crates/ra_vfs/tests/vfs.rs +++ b/crates/ra_vfs/tests/vfs.rs | |||
@@ -7,10 +7,7 @@ use tempfile::tempdir; | |||
7 | 7 | ||
8 | fn process_tasks(vfs: &mut Vfs, num_tasks: u32) { | 8 | fn process_tasks(vfs: &mut Vfs, num_tasks: u32) { |
9 | for _ in 0..num_tasks { | 9 | for _ in 0..num_tasks { |
10 | let task = vfs | 10 | let task = vfs.task_receiver().recv_timeout(Duration::from_secs(3)).unwrap(); |
11 | .task_receiver() | ||
12 | .recv_timeout(Duration::from_secs(3)) | ||
13 | .unwrap(); | ||
14 | log::debug!("{:?}", task); | 11 | log::debug!("{:?}", task); |
15 | vfs.handle_task(task); | 12 | vfs.handle_task(task); |
16 | } | 13 | } |
@@ -32,11 +29,7 @@ macro_rules! assert_match { | |||
32 | fn test_vfs_works() -> std::io::Result<()> { | 29 | fn test_vfs_works() -> std::io::Result<()> { |
33 | // Logger::with_str("vfs=debug,ra_vfs=debug").start().unwrap(); | 30 | // Logger::with_str("vfs=debug,ra_vfs=debug").start().unwrap(); |
34 | 31 | ||
35 | let files = [ | 32 | let files = [("a/foo.rs", "hello"), ("a/bar.rs", "world"), ("a/b/baz.rs", "nested hello")]; |
36 | ("a/foo.rs", "hello"), | ||
37 | ("a/bar.rs", "world"), | ||
38 | ("a/b/baz.rs", "nested hello"), | ||
39 | ]; | ||
40 | 33 | ||
41 | let dir = tempdir().unwrap(); | 34 | let dir = tempdir().unwrap(); |
42 | for (path, text) in files.iter() { | 35 | for (path, text) in files.iter() { |
@@ -66,14 +59,10 @@ fn test_vfs_works() -> std::io::Result<()> { | |||
66 | }) | 59 | }) |
67 | .collect::<HashSet<_>>(); | 60 | .collect::<HashSet<_>>(); |
68 | 61 | ||
69 | let expected_files = [ | 62 | let expected_files = [("foo.rs", "hello"), ("bar.rs", "world"), ("baz.rs", "nested hello")] |
70 | ("foo.rs", "hello"), | 63 | .iter() |
71 | ("bar.rs", "world"), | 64 | .map(|(path, text)| (path.to_string(), text.to_string())) |
72 | ("baz.rs", "nested hello"), | 65 | .collect::<HashSet<_>>(); |
73 | ] | ||
74 | .iter() | ||
75 | .map(|(path, text)| (path.to_string(), text.to_string())) | ||
76 | .collect::<HashSet<_>>(); | ||
77 | 66 | ||
78 | assert_eq!(files, expected_files); | 67 | assert_eq!(files, expected_files); |
79 | } | 68 | } |
@@ -107,14 +96,10 @@ fn test_vfs_works() -> std::io::Result<()> { | |||
107 | ); | 96 | ); |
108 | 97 | ||
109 | vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); | 98 | vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); |
110 | assert_match!( | 99 | assert_match!(vfs.commit_changes().as_slice(), [VfsChange::AddFile { text, path, .. }], { |
111 | vfs.commit_changes().as_slice(), | 100 | assert_eq!(text.as_str(), "spam"); |
112 | [VfsChange::AddFile { text, path, .. }], | 101 | assert_eq!(path, "spam.rs"); |
113 | { | 102 | }); |
114 | assert_eq!(text.as_str(), "spam"); | ||
115 | assert_eq!(path, "spam.rs"); | ||
116 | } | ||
117 | ); | ||
118 | 103 | ||
119 | vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); | 104 | vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); |
120 | assert_match!( | 105 | assert_match!( |
@@ -126,30 +111,17 @@ fn test_vfs_works() -> std::io::Result<()> { | |||
126 | fs::create_dir_all(dir.path().join("a/sub1/sub2")).unwrap(); | 111 | fs::create_dir_all(dir.path().join("a/sub1/sub2")).unwrap(); |
127 | fs::write(dir.path().join("a/sub1/sub2/new.rs"), "new hello").unwrap(); | 112 | fs::write(dir.path().join("a/sub1/sub2/new.rs"), "new hello").unwrap(); |
128 | process_tasks(&mut vfs, 1); | 113 | process_tasks(&mut vfs, 1); |
129 | assert_match!( | 114 | assert_match!(vfs.commit_changes().as_slice(), [VfsChange::AddFile { text, path, .. }], { |
130 | vfs.commit_changes().as_slice(), | 115 | assert_eq!(text.as_str(), "new hello"); |
131 | [VfsChange::AddFile { text, path, .. }], | 116 | assert_eq!(path, "sub1/sub2/new.rs"); |
132 | { | 117 | }); |
133 | assert_eq!(text.as_str(), "new hello"); | ||
134 | assert_eq!(path, "sub1/sub2/new.rs"); | ||
135 | } | ||
136 | ); | ||
137 | 118 | ||
138 | fs::rename( | 119 | fs::rename(&dir.path().join("a/sub1/sub2/new.rs"), &dir.path().join("a/sub1/sub2/new1.rs")) |
139 | &dir.path().join("a/sub1/sub2/new.rs"), | 120 | .unwrap(); |
140 | &dir.path().join("a/sub1/sub2/new1.rs"), | ||
141 | ) | ||
142 | .unwrap(); | ||
143 | process_tasks(&mut vfs, 2); | 121 | process_tasks(&mut vfs, 2); |
144 | assert_match!( | 122 | assert_match!( |
145 | vfs.commit_changes().as_slice(), | 123 | vfs.commit_changes().as_slice(), |
146 | [VfsChange::RemoveFile { | 124 | [VfsChange::RemoveFile { path: removed_path, .. }, VfsChange::AddFile { text, path: added_path, .. }], |
147 | path: removed_path, .. | ||
148 | }, VfsChange::AddFile { | ||
149 | text, | ||
150 | path: added_path, | ||
151 | .. | ||
152 | }], | ||
153 | { | 125 | { |
154 | assert_eq!(removed_path, "sub1/sub2/new.rs"); | 126 | assert_eq!(removed_path, "sub1/sub2/new.rs"); |
155 | assert_eq!(added_path, "sub1/sub2/new1.rs"); | 127 | assert_eq!(added_path, "sub1/sub2/new1.rs"); |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 35a679aea..09fc2e659 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -85,9 +85,7 @@ pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) { | |||
85 | stack.push(from); | 85 | stack.push(from); |
86 | } else if text.starts_with(&close) { | 86 | } else if text.starts_with(&close) { |
87 | text = &text[close.len()..]; | 87 | text = &text[close.len()..]; |
88 | let from = stack | 88 | let from = stack.pop().unwrap_or_else(|| panic!("unmatched </{}>", tag)); |
89 | .pop() | ||
90 | .unwrap_or_else(|| panic!("unmatched </{}>", tag)); | ||
91 | let to = TextUnit::of_str(&res); | 89 | let to = TextUnit::of_str(&res); |
92 | ranges.push(TextRange::from_to(from, to)); | 90 | ranges.push(TextRange::from_to(from, to)); |
93 | } | 91 | } |
@@ -131,10 +129,7 @@ pub fn parse_fixture(fixture: &str) -> Vec<FixtureEntry> { | |||
131 | macro_rules! flush { | 129 | macro_rules! flush { |
132 | () => { | 130 | () => { |
133 | if let Some(meta) = meta { | 131 | if let Some(meta) = meta { |
134 | res.push(FixtureEntry { | 132 | res.push(FixtureEntry { meta: meta.to_string(), text: buf.clone() }); |
135 | meta: meta.to_string(), | ||
136 | text: buf.clone(), | ||
137 | }); | ||
138 | buf.clear(); | 133 | buf.clear(); |
139 | } | 134 | } |
140 | }; | 135 | }; |
@@ -226,15 +221,13 @@ pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a | |||
226 | let mut l = l.iter().collect::<Vec<_>>(); | 221 | let mut l = l.iter().collect::<Vec<_>>(); |
227 | let mut r = r.iter().collect::<Vec<_>>(); | 222 | let mut r = r.iter().collect::<Vec<_>>(); |
228 | 223 | ||
229 | l.retain( | 224 | l.retain(|l| match r.iter().position(|r| find_mismatch(l, r).is_none()) { |
230 | |l| match r.iter().position(|r| find_mismatch(l, r).is_none()) { | 225 | Some(i) => { |
231 | Some(i) => { | 226 | r.remove(i); |
232 | r.remove(i); | 227 | false |
233 | false | 228 | } |
234 | } | 229 | None => true, |
235 | None => true, | 230 | }); |
236 | }, | ||
237 | ); | ||
238 | 231 | ||
239 | if !l.is_empty() { | 232 | if !l.is_empty() { |
240 | assert!(!r.is_empty()); | 233 | assert!(!r.is_empty()); |
@@ -250,10 +243,7 @@ pub fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a | |||
250 | return Some((expected, actual)); | 243 | return Some((expected, actual)); |
251 | } | 244 | } |
252 | 245 | ||
253 | l.values() | 246 | l.values().zip(r.values()).filter_map(|(l, r)| find_mismatch(l, r)).nth(0) |
254 | .zip(r.values()) | ||
255 | .filter_map(|(l, r)| find_mismatch(l, r)) | ||
256 | .nth(0) | ||
257 | } | 247 | } |
258 | (&Null, &Null) => None, | 248 | (&Null, &Null) => None, |
259 | // magic string literal "{...}" acts as wildcard for any sub-JSON | 249 | // magic string literal "{...}" acts as wildcard for any sub-JSON |
@@ -312,12 +302,7 @@ fn test_from_dir(dir: &Path) -> Vec<PathBuf> { | |||
312 | 302 | ||
313 | pub fn project_dir() -> PathBuf { | 303 | pub fn project_dir() -> PathBuf { |
314 | let dir = env!("CARGO_MANIFEST_DIR"); | 304 | let dir = env!("CARGO_MANIFEST_DIR"); |
315 | PathBuf::from(dir) | 305 | PathBuf::from(dir).parent().unwrap().parent().unwrap().to_owned() |
316 | .parent() | ||
317 | .unwrap() | ||
318 | .parent() | ||
319 | .unwrap() | ||
320 | .to_owned() | ||
321 | } | 306 | } |
322 | 307 | ||
323 | /// Read file and normalize newlines. | 308 | /// Read file and normalize newlines. |
diff --git a/crates/test_utils/src/marks.rs b/crates/test_utils/src/marks.rs index ee47b5219..d2a84643c 100644 --- a/crates/test_utils/src/marks.rs +++ b/crates/test_utils/src/marks.rs | |||
@@ -64,10 +64,7 @@ pub struct MarkChecker { | |||
64 | impl MarkChecker { | 64 | impl MarkChecker { |
65 | pub fn new(mark: &'static AtomicUsize) -> MarkChecker { | 65 | pub fn new(mark: &'static AtomicUsize) -> MarkChecker { |
66 | let value_on_entry = mark.load(Ordering::SeqCst); | 66 | let value_on_entry = mark.load(Ordering::SeqCst); |
67 | MarkChecker { | 67 | MarkChecker { mark, value_on_entry } |
68 | mark, | ||
69 | value_on_entry, | ||
70 | } | ||
71 | } | 68 | } |
72 | } | 69 | } |
73 | 70 | ||
diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs index 5e46f62fe..ca0aad136 100644 --- a/crates/thread_worker/src/lib.rs +++ b/crates/thread_worker/src/lib.rs | |||
@@ -71,12 +71,5 @@ impl WorkerHandle { | |||
71 | fn worker_chan<I, O>(buf: usize) -> (Worker<I, O>, Receiver<I>, Sender<O>) { | 71 | fn worker_chan<I, O>(buf: usize) -> (Worker<I, O>, Receiver<I>, Sender<O>) { |
72 | let (input_sender, input_receiver) = bounded::<I>(buf); | 72 | let (input_sender, input_receiver) = bounded::<I>(buf); |
73 | let (output_sender, output_receiver) = unbounded::<O>(); | 73 | let (output_sender, output_receiver) = unbounded::<O>(); |
74 | ( | 74 | (Worker { inp: input_sender, out: output_receiver }, input_receiver, output_sender) |
75 | Worker { | ||
76 | inp: input_sender, | ||
77 | out: output_receiver, | ||
78 | }, | ||
79 | input_receiver, | ||
80 | output_sender, | ||
81 | ) | ||
82 | } | 75 | } |
diff --git a/crates/tools/src/bin/pre-commit.rs b/crates/tools/src/bin/pre-commit.rs index e00bd0d3d..ea18c0863 100644 --- a/crates/tools/src/bin/pre-commit.rs +++ b/crates/tools/src/bin/pre-commit.rs | |||
@@ -19,19 +19,10 @@ fn update_staged() -> Result<()> { | |||
19 | .current_dir(&root) | 19 | .current_dir(&root) |
20 | .output()?; | 20 | .output()?; |
21 | if !output.status.success() { | 21 | if !output.status.success() { |
22 | bail!( | 22 | bail!("`git diff --diff-filter=MAR --name-only --cached` exited with {}", output.status); |
23 | "`git diff --diff-filter=MAR --name-only --cached` exited with {}", | ||
24 | output.status | ||
25 | ); | ||
26 | } | 23 | } |
27 | for line in String::from_utf8(output.stdout)?.lines() { | 24 | for line in String::from_utf8(output.stdout)?.lines() { |
28 | run( | 25 | run(&format!("git update-index --add {}", root.join(line).to_string_lossy()), ".")?; |
29 | &format!( | ||
30 | "git update-index --add {}", | ||
31 | root.join(line).to_string_lossy() | ||
32 | ), | ||
33 | ".", | ||
34 | )?; | ||
35 | } | 26 | } |
36 | Ok(()) | 27 | Ok(()) |
37 | } | 28 | } |
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 311bcb4d8..ef9c613a7 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs | |||
@@ -58,10 +58,8 @@ pub fn collect_tests(s: &str) -> Vec<(usize, Test)> { | |||
58 | None => continue 'outer, | 58 | None => continue 'outer, |
59 | } | 59 | } |
60 | }; | 60 | }; |
61 | let text: String = itertools::join( | 61 | let text: String = |
62 | block.map(|(_, line)| line).chain(::std::iter::once("")), | 62 | itertools::join(block.map(|(_, line)| line).chain(::std::iter::once("")), "\n"); |
63 | "\n", | ||
64 | ); | ||
65 | assert!(!text.trim().is_empty() && text.ends_with('\n')); | 63 | assert!(!text.trim().is_empty() && text.ends_with('\n')); |
66 | res.push((start_line, Test { name, text, ok })) | 64 | res.push((start_line, Test { name, text, ok })) |
67 | } | 65 | } |
@@ -78,11 +76,7 @@ pub fn generate(mode: Mode) -> Result<()> { | |||
78 | } | 76 | } |
79 | 77 | ||
80 | pub fn project_root() -> PathBuf { | 78 | pub fn project_root() -> PathBuf { |
81 | Path::new(&env!("CARGO_MANIFEST_DIR")) | 79 | Path::new(&env!("CARGO_MANIFEST_DIR")).ancestors().nth(2).unwrap().to_path_buf() |
82 | .ancestors() | ||
83 | .nth(2) | ||
84 | .unwrap() | ||
85 | .to_path_buf() | ||
86 | } | 80 | } |
87 | 81 | ||
88 | pub fn run(cmdline: &str, dir: &str) -> Result<()> { | 82 | pub fn run(cmdline: &str, dir: &str) -> Result<()> { |
@@ -90,10 +84,7 @@ pub fn run(cmdline: &str, dir: &str) -> Result<()> { | |||
90 | let project_dir = project_root().join(dir); | 84 | let project_dir = project_root().join(dir); |
91 | let mut args = cmdline.split_whitespace(); | 85 | let mut args = cmdline.split_whitespace(); |
92 | let exec = args.next().unwrap(); | 86 | let exec = args.next().unwrap(); |
93 | let status = Command::new(exec) | 87 | let status = Command::new(exec).args(args).current_dir(project_dir).status()?; |
94 | .args(args) | ||
95 | .current_dir(project_dir) | ||
96 | .status()?; | ||
97 | if !status.success() { | 88 | if !status.success() { |
98 | bail!("`{}` exited with {}", cmdline, status); | 89 | bail!("`{}` exited with {}", cmdline, status); |
99 | } | 90 | } |
@@ -112,10 +103,7 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> { | |||
112 | }; | 103 | }; |
113 | 104 | ||
114 | if mode == Verify { | 105 | if mode == Verify { |
115 | run( | 106 | run(&format!("rustup run {} -- cargo fmt -- --check", TOOLCHAIN), ".")?; |
116 | &format!("rustup run {} -- cargo fmt -- --check", TOOLCHAIN), | ||
117 | ".", | ||
118 | )?; | ||
119 | } else { | 107 | } else { |
120 | run(&format!("rustup run {} -- cargo fmt", TOOLCHAIN), ".")?; | 108 | run(&format!("rustup run {} -- cargo fmt", TOOLCHAIN), ".")?; |
121 | } | 109 | } |
@@ -124,10 +112,7 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> { | |||
124 | 112 | ||
125 | pub fn install_rustfmt() -> Result<()> { | 113 | pub fn install_rustfmt() -> Result<()> { |
126 | run(&format!("rustup install {}", TOOLCHAIN), ".")?; | 114 | run(&format!("rustup install {}", TOOLCHAIN), ".")?; |
127 | run( | 115 | run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".") |
128 | &format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), | ||
129 | ".", | ||
130 | ) | ||
131 | } | 116 | } |
132 | 117 | ||
133 | pub fn install_format_hook() -> Result<()> { | 118 | pub fn install_format_hook() -> Result<()> { |
@@ -156,10 +141,7 @@ pub fn run_fuzzer() -> Result<()> { | |||
156 | _ => run("cargo install cargo-fuzz", ".")?, | 141 | _ => run("cargo install cargo-fuzz", ".")?, |
157 | }; | 142 | }; |
158 | 143 | ||
159 | run( | 144 | run("rustup run nightly -- cargo fuzz run parser", "./crates/ra_syntax") |
160 | "rustup run nightly -- cargo fuzz run parser", | ||
161 | "./crates/ra_syntax", | ||
162 | ) | ||
163 | } | 145 | } |
164 | 146 | ||
165 | pub fn gen_tests(mode: Mode) -> Result<()> { | 147 | pub fn gen_tests(mode: Mode) -> Result<()> { |
@@ -245,11 +227,7 @@ fn existing_tests(dir: &Path, ok: bool) -> Result<HashMap<String, (PathBuf, Test | |||
245 | file_name[5..file_name.len() - 3].to_string() | 227 | file_name[5..file_name.len() - 3].to_string() |
246 | }; | 228 | }; |
247 | let text = fs::read_to_string(&path)?; | 229 | let text = fs::read_to_string(&path)?; |
248 | let test = Test { | 230 | let test = Test { name: name.clone(), text, ok }; |
249 | name: name.clone(), | ||
250 | text, | ||
251 | ok, | ||
252 | }; | ||
253 | if let Some(old) = res.insert(name, (path, test)) { | 231 | if let Some(old) = res.insert(name, (path, test)) { |
254 | println!("Duplicate test: {:?}", old); | 232 | println!("Duplicate test: {:?}", old); |
255 | } | 233 | } |
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs index c3e293911..963ffbe98 100644 --- a/crates/tools/src/main.rs +++ b/crates/tools/src/main.rs | |||
@@ -15,10 +15,7 @@ fn main() -> Result<()> { | |||
15 | .subcommand(SubCommand::with_name("format-hook")) | 15 | .subcommand(SubCommand::with_name("format-hook")) |
16 | .subcommand(SubCommand::with_name("fuzz-tests")) | 16 | .subcommand(SubCommand::with_name("fuzz-tests")) |
17 | .get_matches(); | 17 | .get_matches(); |
18 | match matches | 18 | match matches.subcommand_name().expect("Subcommand must be specified") { |
19 | .subcommand_name() | ||
20 | .expect("Subcommand must be specified") | ||
21 | { | ||
22 | "install-code" => install_code_extension()?, | 19 | "install-code" => install_code_extension()?, |
23 | "gen-tests" => gen_tests(Overwrite)?, | 20 | "gen-tests" => gen_tests(Overwrite)?, |
24 | "gen-syntax" => generate(Overwrite)?, | 21 | "gen-syntax" => generate(Overwrite)?, |
@@ -45,10 +42,7 @@ fn install_code_extension() -> Result<()> { | |||
45 | "./editors/code", | 42 | "./editors/code", |
46 | )?; | 43 | )?; |
47 | } else { | 44 | } else { |
48 | run( | 45 | run(r"code --install-extension ./ra-lsp-0.0.1.vsix --force", "./editors/code")?; |
49 | r"code --install-extension ./ra-lsp-0.0.1.vsix --force", | ||
50 | "./editors/code", | ||
51 | )?; | ||
52 | } | 46 | } |
53 | Ok(()) | 47 | Ok(()) |
54 | } | 48 | } |
diff --git a/crates/tools/tests/cli.rs b/crates/tools/tests/cli.rs index 2ee4b5223..aab52a4aa 100644 --- a/crates/tools/tests/cli.rs +++ b/crates/tools/tests/cli.rs | |||
@@ -10,19 +10,13 @@ fn generated_grammar_is_fresh() { | |||
10 | #[test] | 10 | #[test] |
11 | fn generated_tests_are_fresh() { | 11 | fn generated_tests_are_fresh() { |
12 | if let Err(error) = gen_tests(Verify) { | 12 | if let Err(error) = gen_tests(Verify) { |
13 | panic!( | 13 | panic!("{}. Please update tests by running `cargo gen-tests`", error); |
14 | "{}. Please update tests by running `cargo gen-tests`", | ||
15 | error | ||
16 | ); | ||
17 | } | 14 | } |
18 | } | 15 | } |
19 | 16 | ||
20 | #[test] | 17 | #[test] |
21 | fn check_code_formatting() { | 18 | fn check_code_formatting() { |
22 | if let Err(error) = run_rustfmt(Verify) { | 19 | if let Err(error) = run_rustfmt(Verify) { |
23 | panic!( | 20 | panic!("{}. Please format the code by running `cargo format`", error); |
24 | "{}. Please format the code by running `cargo format`", | ||
25 | error | ||
26 | ); | ||
27 | } | 21 | } |
28 | } | 22 | } |