diff options
Diffstat (limited to 'crates/ra_ide/src/goto_implementation.rs')
-rw-r--r-- | crates/ra_ide/src/goto_implementation.rs | 193 |
1 files changed, 105 insertions, 88 deletions
diff --git a/crates/ra_ide/src/goto_implementation.rs b/crates/ra_ide/src/goto_implementation.rs index 0cec0657e..1882789c4 100644 --- a/crates/ra_ide/src/goto_implementation.rs +++ b/crates/ra_ide/src/goto_implementation.rs | |||
@@ -74,135 +74,152 @@ fn impls_for_trait( | |||
74 | 74 | ||
75 | #[cfg(test)] | 75 | #[cfg(test)] |
76 | mod tests { | 76 | mod tests { |
77 | use crate::mock_analysis::analysis_and_position; | 77 | use ra_db::FileRange; |
78 | 78 | ||
79 | fn check_goto(fixture: &str, expected: &[&str]) { | 79 | use crate::mock_analysis::{analysis_and_position, MockAnalysis}; |
80 | let (analysis, pos) = analysis_and_position(fixture); | ||
81 | 80 | ||
82 | let mut navs = analysis.goto_implementation(pos).unwrap().unwrap().info; | 81 | fn check(ra_fixture: &str) { |
83 | assert_eq!(navs.len(), expected.len()); | 82 | let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture); |
84 | navs.sort_by_key(|nav| (nav.file_id(), nav.full_range().start())); | 83 | let annotations = mock.annotations(); |
85 | navs.into_iter().enumerate().for_each(|(i, nav)| nav.assert_match(expected[i])); | 84 | let analysis = mock.analysis(); |
85 | |||
86 | let navs = analysis.goto_implementation(position).unwrap().unwrap().info; | ||
87 | |||
88 | let key = |frange: &FileRange| (frange.file_id, frange.range.start()); | ||
89 | |||
90 | let mut expected = annotations | ||
91 | .into_iter() | ||
92 | .map(|(range, data)| { | ||
93 | assert!(data.is_empty()); | ||
94 | range | ||
95 | }) | ||
96 | .collect::<Vec<_>>(); | ||
97 | expected.sort_by_key(key); | ||
98 | |||
99 | let mut actual = navs | ||
100 | .into_iter() | ||
101 | .map(|nav| FileRange { file_id: nav.file_id(), range: nav.range() }) | ||
102 | .collect::<Vec<_>>(); | ||
103 | actual.sort_by_key(key); | ||
104 | |||
105 | assert_eq!(expected, actual); | ||
86 | } | 106 | } |
87 | 107 | ||
88 | #[test] | 108 | #[test] |
89 | fn goto_implementation_works() { | 109 | fn goto_implementation_works() { |
90 | check_goto( | 110 | check( |
91 | " | 111 | r#" |
92 | //- /lib.rs | 112 | struct Foo<|>; |
93 | struct Foo<|>; | 113 | impl Foo {} |
94 | impl Foo {} | 114 | //^^^ |
95 | ", | 115 | "#, |
96 | &["impl IMPL_DEF FileId(1) 12..23"], | ||
97 | ); | 116 | ); |
98 | } | 117 | } |
99 | 118 | ||
100 | #[test] | 119 | #[test] |
101 | fn goto_implementation_works_multiple_blocks() { | 120 | fn goto_implementation_works_multiple_blocks() { |
102 | check_goto( | 121 | check( |
103 | " | 122 | r#" |
104 | //- /lib.rs | 123 | struct Foo<|>; |
105 | struct Foo<|>; | 124 | impl Foo {} |
106 | impl Foo {} | 125 | //^^^ |
107 | impl Foo {} | 126 | impl Foo {} |
108 | ", | 127 | //^^^ |
109 | &["impl IMPL_DEF FileId(1) 12..23", "impl IMPL_DEF FileId(1) 24..35"], | 128 | "#, |
110 | ); | 129 | ); |
111 | } | 130 | } |
112 | 131 | ||
113 | #[test] | 132 | #[test] |
114 | fn goto_implementation_works_multiple_mods() { | 133 | fn goto_implementation_works_multiple_mods() { |
115 | check_goto( | 134 | check( |
116 | " | 135 | r#" |
117 | //- /lib.rs | 136 | struct Foo<|>; |
118 | struct Foo<|>; | 137 | mod a { |
119 | mod a { | 138 | impl super::Foo {} |
120 | impl super::Foo {} | 139 | //^^^^^^^^^^ |
121 | } | 140 | } |
122 | mod b { | 141 | mod b { |
123 | impl super::Foo {} | 142 | impl super::Foo {} |
124 | } | 143 | //^^^^^^^^^^ |
125 | ", | 144 | } |
126 | &["impl IMPL_DEF FileId(1) 24..42", "impl IMPL_DEF FileId(1) 57..75"], | 145 | "#, |
127 | ); | 146 | ); |
128 | } | 147 | } |
129 | 148 | ||
130 | #[test] | 149 | #[test] |
131 | fn goto_implementation_works_multiple_files() { | 150 | fn goto_implementation_works_multiple_files() { |
132 | check_goto( | 151 | check( |
133 | " | 152 | r#" |
134 | //- /lib.rs | 153 | //- /lib.rs |
135 | struct Foo<|>; | 154 | struct Foo<|>; |
136 | mod a; | 155 | mod a; |
137 | mod b; | 156 | mod b; |
138 | //- /a.rs | 157 | //- /a.rs |
139 | impl crate::Foo {} | 158 | impl crate::Foo {} |
140 | //- /b.rs | 159 | //^^^^^^^^^^ |
141 | impl crate::Foo {} | 160 | //- /b.rs |
142 | ", | 161 | impl crate::Foo {} |
143 | &["impl IMPL_DEF FileId(2) 0..18", "impl IMPL_DEF FileId(3) 0..18"], | 162 | //^^^^^^^^^^ |
163 | "#, | ||
144 | ); | 164 | ); |
145 | } | 165 | } |
146 | 166 | ||
147 | #[test] | 167 | #[test] |
148 | fn goto_implementation_for_trait() { | 168 | fn goto_implementation_for_trait() { |
149 | check_goto( | 169 | check( |
150 | " | 170 | r#" |
151 | //- /lib.rs | 171 | trait T<|> {} |
152 | trait T<|> {} | 172 | struct Foo; |
153 | struct Foo; | 173 | impl T for Foo {} |
154 | impl T for Foo {} | 174 | //^^^ |
155 | ", | 175 | "#, |
156 | &["impl IMPL_DEF FileId(1) 23..40"], | ||
157 | ); | 176 | ); |
158 | } | 177 | } |
159 | 178 | ||
160 | #[test] | 179 | #[test] |
161 | fn goto_implementation_for_trait_multiple_files() { | 180 | fn goto_implementation_for_trait_multiple_files() { |
162 | check_goto( | 181 | check( |
163 | " | 182 | r#" |
164 | //- /lib.rs | 183 | //- /lib.rs |
165 | trait T<|> {}; | 184 | trait T<|> {}; |
166 | struct Foo; | 185 | struct Foo; |
167 | mod a; | 186 | mod a; |
168 | mod b; | 187 | mod b; |
169 | //- /a.rs | 188 | //- /a.rs |
170 | impl crate::T for crate::Foo {} | 189 | impl crate::T for crate::Foo {} |
171 | //- /b.rs | 190 | //^^^^^^^^^^ |
172 | impl crate::T for crate::Foo {} | 191 | //- /b.rs |
173 | ", | 192 | impl crate::T for crate::Foo {} |
174 | &["impl IMPL_DEF FileId(2) 0..31", "impl IMPL_DEF FileId(3) 0..31"], | 193 | //^^^^^^^^^^ |
194 | "#, | ||
175 | ); | 195 | ); |
176 | } | 196 | } |
177 | 197 | ||
178 | #[test] | 198 | #[test] |
179 | fn goto_implementation_all_impls() { | 199 | fn goto_implementation_all_impls() { |
180 | check_goto( | 200 | check( |
181 | " | 201 | r#" |
182 | //- /lib.rs | 202 | //- /lib.rs |
183 | trait T {} | 203 | trait T {} |
184 | struct Foo<|>; | 204 | struct Foo<|>; |
185 | impl Foo {} | 205 | impl Foo {} |
186 | impl T for Foo {} | 206 | //^^^ |
187 | impl T for &Foo {} | 207 | impl T for Foo {} |
188 | ", | 208 | //^^^ |
189 | &[ | 209 | impl T for &Foo {} |
190 | "impl IMPL_DEF FileId(1) 23..34", | 210 | //^^^^ |
191 | "impl IMPL_DEF FileId(1) 35..52", | 211 | "#, |
192 | "impl IMPL_DEF FileId(1) 53..71", | ||
193 | ], | ||
194 | ); | 212 | ); |
195 | } | 213 | } |
196 | 214 | ||
197 | #[test] | 215 | #[test] |
198 | fn goto_implementation_to_builtin_derive() { | 216 | fn goto_implementation_to_builtin_derive() { |
199 | check_goto( | 217 | check( |
200 | " | 218 | r#" |
201 | //- /lib.rs | 219 | #[derive(Copy)] |
202 | #[derive(Copy)] | 220 | //^^^^^^^^^^^^^^^ |
203 | struct Foo<|>; | 221 | struct Foo<|>; |
204 | ", | 222 | "#, |
205 | &["impl IMPL_DEF FileId(1) 0..15"], | ||
206 | ); | 223 | ); |
207 | } | 224 | } |
208 | } | 225 | } |