diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/raw_string.rs | 131 | ||||
-rw-r--r-- | crates/ra_hir_def/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/import_map.rs | 300 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/mod_resolution.rs | 32 | ||||
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 16 |
7 files changed, 241 insertions, 244 deletions
diff --git a/Cargo.lock b/Cargo.lock index 451ba1f42..d341d1054 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -1111,7 +1111,6 @@ dependencies = [ | |||
1111 | "expect", | 1111 | "expect", |
1112 | "fst", | 1112 | "fst", |
1113 | "indexmap", | 1113 | "indexmap", |
1114 | "insta", | ||
1115 | "itertools", | 1114 | "itertools", |
1116 | "log", | 1115 | "log", |
1117 | "once_cell", | 1116 | "once_cell", |
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs index 6d77dff13..ba1dcb610 100644 --- a/crates/ra_assists/src/handlers/raw_string.rs +++ b/crates/ra_assists/src/handlers/raw_string.rs | |||
@@ -4,8 +4,9 @@ use ra_syntax::{ | |||
4 | ast::{self, HasQuotes, HasStringValue}, | 4 | ast::{self, HasQuotes, HasStringValue}, |
5 | AstToken, | 5 | AstToken, |
6 | SyntaxKind::{RAW_STRING, STRING}, | 6 | SyntaxKind::{RAW_STRING, STRING}, |
7 | TextSize, | 7 | TextRange, TextSize, |
8 | }; | 8 | }; |
9 | use test_utils::mark; | ||
9 | 10 | ||
10 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 11 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
11 | 12 | ||
@@ -33,8 +34,7 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
33 | "Rewrite as raw string", | 34 | "Rewrite as raw string", |
34 | target, | 35 | target, |
35 | |edit| { | 36 | |edit| { |
36 | let max_hash_streak = count_hashes(&value); | 37 | let hashes = "#".repeat(required_hashes(&value).max(1)); |
37 | let hashes = "#".repeat(max_hash_streak + 1); | ||
38 | if matches!(value, Cow::Borrowed(_)) { | 38 | if matches!(value, Cow::Borrowed(_)) { |
39 | // Avoid replacing the whole string to better position the cursor. | 39 | // Avoid replacing the whole string to better position the cursor. |
40 | edit.insert(token.syntax().text_range().start(), format!("r{}", hashes)); | 40 | edit.insert(token.syntax().text_range().start(), format!("r{}", hashes)); |
@@ -106,7 +106,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
106 | pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 106 | pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
107 | let token = ctx.find_token_at_offset(RAW_STRING)?; | 107 | let token = ctx.find_token_at_offset(RAW_STRING)?; |
108 | let target = token.text_range(); | 108 | let target = token.text_range(); |
109 | acc.add(AssistId("add_hash", AssistKind::Refactor), "Add # to raw string", target, |edit| { | 109 | acc.add(AssistId("add_hash", AssistKind::Refactor), "Add #", target, |edit| { |
110 | edit.insert(token.text_range().start() + TextSize::of('r'), "#"); | 110 | edit.insert(token.text_range().start() + TextSize::of('r'), "#"); |
111 | edit.insert(token.text_range().end(), "#"); | 111 | edit.insert(token.text_range().end(), "#"); |
112 | }) | 112 | }) |
@@ -128,49 +128,58 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
128 | // } | 128 | // } |
129 | // ``` | 129 | // ``` |
130 | pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 130 | pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
131 | let token = ctx.find_token_at_offset(RAW_STRING)?; | 131 | let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?; |
132 | |||
132 | let text = token.text().as_str(); | 133 | let text = token.text().as_str(); |
133 | if text.starts_with("r\"") { | 134 | if !text.starts_with("r#") && text.ends_with("#") { |
134 | // no hash to remove | ||
135 | return None; | 135 | return None; |
136 | } | 136 | } |
137 | let target = token.text_range(); | 137 | |
138 | acc.add( | 138 | let existing_hashes = text.chars().skip(1).take_while(|&it| it == '#').count(); |
139 | AssistId("remove_hash", AssistKind::RefactorRewrite), | 139 | |
140 | "Remove hash from raw string", | 140 | let text_range = token.syntax().text_range(); |
141 | target, | 141 | let internal_text = &text[token.text_range_between_quotes()? - text_range.start()]; |
142 | |edit| { | 142 | |
143 | let result = &text[2..text.len() - 1]; | 143 | if existing_hashes == required_hashes(internal_text) { |
144 | let result = if result.starts_with('\"') { | 144 | mark::hit!(cant_remove_required_hash); |
145 | // FIXME: this logic is wrong, not only the last has has to handled specially | 145 | return None; |
146 | // no more hash, escape | 146 | } |
147 | let internal_str = &result[1..result.len() - 1]; | 147 | |
148 | format!("\"{}\"", internal_str.escape_default().to_string()) | 148 | acc.add(AssistId("remove_hash", AssistKind::RefactorRewrite), "Remove #", text_range, |edit| { |
149 | } else { | 149 | edit.delete(TextRange::at(text_range.start() + TextSize::of('r'), TextSize::of('#'))); |
150 | result.to_owned() | 150 | edit.delete(TextRange::new(text_range.end() - TextSize::of('#'), text_range.end())); |
151 | }; | 151 | }) |
152 | edit.replace(token.text_range(), format!("r{}", result)); | ||
153 | }, | ||
154 | ) | ||
155 | } | 152 | } |
156 | 153 | ||
157 | fn count_hashes(s: &str) -> usize { | 154 | fn required_hashes(s: &str) -> usize { |
158 | let mut max_hash_streak = 0usize; | 155 | let mut res = 0usize; |
159 | for idx in s.match_indices("\"#").map(|(i, _)| i) { | 156 | for idx in s.match_indices('"').map(|(i, _)| i) { |
160 | let (_, sub) = s.split_at(idx + 1); | 157 | let (_, sub) = s.split_at(idx + 1); |
161 | let nb_hash = sub.chars().take_while(|c| *c == '#').count(); | 158 | let n_hashes = sub.chars().take_while(|c| *c == '#').count(); |
162 | if nb_hash > max_hash_streak { | 159 | res = res.max(n_hashes + 1) |
163 | max_hash_streak = nb_hash; | ||
164 | } | ||
165 | } | 160 | } |
166 | max_hash_streak | 161 | res |
162 | } | ||
163 | |||
164 | #[test] | ||
165 | fn test_required_hashes() { | ||
166 | assert_eq!(0, required_hashes("abc")); | ||
167 | assert_eq!(0, required_hashes("###")); | ||
168 | assert_eq!(1, required_hashes("\"")); | ||
169 | assert_eq!(2, required_hashes("\"#abc")); | ||
170 | assert_eq!(0, required_hashes("#abc")); | ||
171 | assert_eq!(3, required_hashes("#ab\"##c")); | ||
172 | assert_eq!(5, required_hashes("#ab\"##\"####c")); | ||
167 | } | 173 | } |
168 | 174 | ||
169 | #[cfg(test)] | 175 | #[cfg(test)] |
170 | mod test { | 176 | mod test { |
171 | use super::*; | 177 | use test_utils::mark; |
178 | |||
172 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 179 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; |
173 | 180 | ||
181 | use super::*; | ||
182 | |||
174 | #[test] | 183 | #[test] |
175 | fn make_raw_string_target() { | 184 | fn make_raw_string_target() { |
176 | check_assist_target( | 185 | check_assist_target( |
@@ -372,33 +381,21 @@ string"###; | |||
372 | fn remove_hash_works() { | 381 | fn remove_hash_works() { |
373 | check_assist( | 382 | check_assist( |
374 | remove_hash, | 383 | remove_hash, |
375 | r##" | 384 | r##"fn f() { let s = <|>r#"random string"#; }"##, |
376 | fn f() { | 385 | r#"fn f() { let s = r"random string"; }"#, |
377 | let s = <|>r#"random string"#; | ||
378 | } | ||
379 | "##, | ||
380 | r#" | ||
381 | fn f() { | ||
382 | let s = r"random string"; | ||
383 | } | ||
384 | "#, | ||
385 | ) | 386 | ) |
386 | } | 387 | } |
387 | 388 | ||
388 | #[test] | 389 | #[test] |
389 | fn remove_hash_with_quote_works() { | 390 | fn cant_remove_required_hash() { |
390 | check_assist( | 391 | mark::check!(cant_remove_required_hash); |
392 | check_assist_not_applicable( | ||
391 | remove_hash, | 393 | remove_hash, |
392 | r##" | 394 | r##" |
393 | fn f() { | 395 | fn f() { |
394 | let s = <|>r#"random"str"ing"#; | 396 | let s = <|>r#"random"str"ing"#; |
395 | } | 397 | } |
396 | "##, | 398 | "##, |
397 | r#" | ||
398 | fn f() { | ||
399 | let s = r"random\"str\"ing"; | ||
400 | } | ||
401 | "#, | ||
402 | ) | 399 | ) |
403 | } | 400 | } |
404 | 401 | ||
@@ -420,27 +417,13 @@ string"###; | |||
420 | } | 417 | } |
421 | 418 | ||
422 | #[test] | 419 | #[test] |
423 | fn remove_hash_not_works() { | 420 | fn remove_hash_doesnt_work() { |
424 | check_assist_not_applicable( | 421 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>"random string"; }"#); |
425 | remove_hash, | ||
426 | r#" | ||
427 | fn f() { | ||
428 | let s = <|>"random string"; | ||
429 | } | ||
430 | "#, | ||
431 | ); | ||
432 | } | 422 | } |
433 | 423 | ||
434 | #[test] | 424 | #[test] |
435 | fn remove_hash_no_hash_not_works() { | 425 | fn remove_hash_no_hash_doesnt_work() { |
436 | check_assist_not_applicable( | 426 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>r"random string"; }"#); |
437 | remove_hash, | ||
438 | r#" | ||
439 | fn f() { | ||
440 | let s = <|>r"random string"; | ||
441 | } | ||
442 | "#, | ||
443 | ); | ||
444 | } | 427 | } |
445 | 428 | ||
446 | #[test] | 429 | #[test] |
@@ -518,14 +501,4 @@ string"###; | |||
518 | "#, | 501 | "#, |
519 | ); | 502 | ); |
520 | } | 503 | } |
521 | |||
522 | #[test] | ||
523 | fn count_hashes_test() { | ||
524 | assert_eq!(0, count_hashes("abc")); | ||
525 | assert_eq!(0, count_hashes("###")); | ||
526 | assert_eq!(1, count_hashes("\"#abc")); | ||
527 | assert_eq!(0, count_hashes("#abc")); | ||
528 | assert_eq!(2, count_hashes("#ab\"##c")); | ||
529 | assert_eq!(4, count_hashes("#ab\"##\"####c")); | ||
530 | } | ||
531 | } | 504 | } |
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml index 1ec619b42..d96a86b80 100644 --- a/crates/ra_hir_def/Cargo.toml +++ b/crates/ra_hir_def/Cargo.toml | |||
@@ -33,5 +33,4 @@ ra_cfg = { path = "../ra_cfg" } | |||
33 | tt = { path = "../ra_tt", package = "ra_tt" } | 33 | tt = { path = "../ra_tt", package = "ra_tt" } |
34 | 34 | ||
35 | [dev-dependencies] | 35 | [dev-dependencies] |
36 | insta = "0.16.0" | ||
37 | expect = { path = "../expect" } | 36 | expect = { path = "../expect" } |
diff --git a/crates/ra_hir_def/src/import_map.rs b/crates/ra_hir_def/src/import_map.rs index 869f3ca5a..9e4c30b1a 100644 --- a/crates/ra_hir_def/src/import_map.rs +++ b/crates/ra_hir_def/src/import_map.rs | |||
@@ -327,32 +327,14 @@ pub fn search_dependencies<'a>( | |||
327 | 327 | ||
328 | #[cfg(test)] | 328 | #[cfg(test)] |
329 | mod tests { | 329 | mod tests { |
330 | use super::*; | 330 | use expect::{expect, Expect}; |
331 | use crate::{test_db::TestDB, AssocContainerId, Lookup}; | 331 | use ra_db::{fixture::WithFixture, SourceDatabase, Upcast}; |
332 | use insta::assert_snapshot; | ||
333 | use itertools::Itertools; | ||
334 | use ra_db::fixture::WithFixture; | ||
335 | use ra_db::{SourceDatabase, Upcast}; | ||
336 | 332 | ||
337 | fn import_map(ra_fixture: &str) -> String { | 333 | use crate::{test_db::TestDB, AssocContainerId, Lookup}; |
338 | let db = TestDB::with_files(ra_fixture); | ||
339 | let crate_graph = db.crate_graph(); | ||
340 | |||
341 | let s = crate_graph | ||
342 | .iter() | ||
343 | .filter_map(|krate| { | ||
344 | let cdata = &crate_graph[krate]; | ||
345 | let name = cdata.display_name.as_ref()?; | ||
346 | |||
347 | let map = db.import_map(krate); | ||
348 | 334 | ||
349 | Some(format!("{}:\n{:?}", name, map)) | 335 | use super::*; |
350 | }) | ||
351 | .join("\n"); | ||
352 | s | ||
353 | } | ||
354 | 336 | ||
355 | fn search_dependencies_of(ra_fixture: &str, krate_name: &str, query: Query) -> String { | 337 | fn check_search(ra_fixture: &str, krate_name: &str, query: Query, expect: Expect) { |
356 | let db = TestDB::with_files(ra_fixture); | 338 | let db = TestDB::with_files(ra_fixture); |
357 | let crate_graph = db.crate_graph(); | 339 | let crate_graph = db.crate_graph(); |
358 | let krate = crate_graph | 340 | let krate = crate_graph |
@@ -363,7 +345,7 @@ mod tests { | |||
363 | }) | 345 | }) |
364 | .unwrap(); | 346 | .unwrap(); |
365 | 347 | ||
366 | search_dependencies(db.upcast(), krate, query) | 348 | let actual = search_dependencies(db.upcast(), krate, query) |
367 | .into_iter() | 349 | .into_iter() |
368 | .filter_map(|item| { | 350 | .filter_map(|item| { |
369 | let mark = match item { | 351 | let mark = match item { |
@@ -376,14 +358,15 @@ mod tests { | |||
376 | let map = db.import_map(krate); | 358 | let map = db.import_map(krate); |
377 | let path = map.path_of(item).unwrap(); | 359 | let path = map.path_of(item).unwrap(); |
378 | format!( | 360 | format!( |
379 | "{}::{} ({})", | 361 | "{}::{} ({})\n", |
380 | crate_graph[krate].display_name.as_ref().unwrap(), | 362 | crate_graph[krate].display_name.as_ref().unwrap(), |
381 | path, | 363 | path, |
382 | mark | 364 | mark |
383 | ) | 365 | ) |
384 | }) | 366 | }) |
385 | }) | 367 | }) |
386 | .join("\n") | 368 | .collect::<String>(); |
369 | expect.assert_eq(&actual) | ||
387 | } | 370 | } |
388 | 371 | ||
389 | fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs { | 372 | fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs { |
@@ -409,9 +392,28 @@ mod tests { | |||
409 | } | 392 | } |
410 | } | 393 | } |
411 | 394 | ||
395 | fn check(ra_fixture: &str, expect: Expect) { | ||
396 | let db = TestDB::with_files(ra_fixture); | ||
397 | let crate_graph = db.crate_graph(); | ||
398 | |||
399 | let actual = crate_graph | ||
400 | .iter() | ||
401 | .filter_map(|krate| { | ||
402 | let cdata = &crate_graph[krate]; | ||
403 | let name = cdata.display_name.as_ref()?; | ||
404 | |||
405 | let map = db.import_map(krate); | ||
406 | |||
407 | Some(format!("{}:\n{:?}\n", name, map)) | ||
408 | }) | ||
409 | .collect::<String>(); | ||
410 | |||
411 | expect.assert_eq(&actual) | ||
412 | } | ||
413 | |||
412 | #[test] | 414 | #[test] |
413 | fn smoke() { | 415 | fn smoke() { |
414 | let map = import_map( | 416 | check( |
415 | r" | 417 | r" |
416 | //- /main.rs crate:main deps:lib | 418 | //- /main.rs crate:main deps:lib |
417 | 419 | ||
@@ -436,24 +438,23 @@ mod tests { | |||
436 | pub struct Pub2; // t + v | 438 | pub struct Pub2; // t + v |
437 | struct Priv; | 439 | struct Priv; |
438 | ", | 440 | ", |
441 | expect![[r#" | ||
442 | main: | ||
443 | - publ1 (t) | ||
444 | - real_pu2 (t) | ||
445 | - real_pub (t) | ||
446 | - real_pub::Pub (t) | ||
447 | lib: | ||
448 | - Pub (t) | ||
449 | - Pub2 (t) | ||
450 | - Pub2 (v) | ||
451 | "#]], | ||
439 | ); | 452 | ); |
440 | |||
441 | assert_snapshot!(map, @r###" | ||
442 | main: | ||
443 | - publ1 (t) | ||
444 | - real_pu2 (t) | ||
445 | - real_pub (t) | ||
446 | - real_pub::Pub (t) | ||
447 | lib: | ||
448 | - Pub (t) | ||
449 | - Pub2 (t) | ||
450 | - Pub2 (v) | ||
451 | "###); | ||
452 | } | 453 | } |
453 | 454 | ||
454 | #[test] | 455 | #[test] |
455 | fn prefers_shortest_path() { | 456 | fn prefers_shortest_path() { |
456 | let map = import_map( | 457 | check( |
457 | r" | 458 | r" |
458 | //- /main.rs crate:main | 459 | //- /main.rs crate:main |
459 | 460 | ||
@@ -465,21 +466,20 @@ mod tests { | |||
465 | pub use super::sub::subsub::Def; | 466 | pub use super::sub::subsub::Def; |
466 | } | 467 | } |
467 | ", | 468 | ", |
469 | expect![[r#" | ||
470 | main: | ||
471 | - sub (t) | ||
472 | - sub::Def (t) | ||
473 | - sub::subsub (t) | ||
474 | "#]], | ||
468 | ); | 475 | ); |
469 | |||
470 | assert_snapshot!(map, @r###" | ||
471 | main: | ||
472 | - sub (t) | ||
473 | - sub::Def (t) | ||
474 | - sub::subsub (t) | ||
475 | "###); | ||
476 | } | 476 | } |
477 | 477 | ||
478 | #[test] | 478 | #[test] |
479 | fn type_reexport_cross_crate() { | 479 | fn type_reexport_cross_crate() { |
480 | // Reexports need to be visible from a crate, even if the original crate exports the item | 480 | // Reexports need to be visible from a crate, even if the original crate exports the item |
481 | // at a shorter path. | 481 | // at a shorter path. |
482 | let map = import_map( | 482 | check( |
483 | r" | 483 | r" |
484 | //- /main.rs crate:main deps:lib | 484 | //- /main.rs crate:main deps:lib |
485 | pub mod m { | 485 | pub mod m { |
@@ -488,22 +488,21 @@ mod tests { | |||
488 | //- /lib.rs crate:lib | 488 | //- /lib.rs crate:lib |
489 | pub struct S; | 489 | pub struct S; |
490 | ", | 490 | ", |
491 | expect![[r#" | ||
492 | main: | ||
493 | - m (t) | ||
494 | - m::S (t) | ||
495 | - m::S (v) | ||
496 | lib: | ||
497 | - S (t) | ||
498 | - S (v) | ||
499 | "#]], | ||
491 | ); | 500 | ); |
492 | |||
493 | assert_snapshot!(map, @r###" | ||
494 | main: | ||
495 | - m (t) | ||
496 | - m::S (t) | ||
497 | - m::S (v) | ||
498 | lib: | ||
499 | - S (t) | ||
500 | - S (v) | ||
501 | "###); | ||
502 | } | 501 | } |
503 | 502 | ||
504 | #[test] | 503 | #[test] |
505 | fn macro_reexport() { | 504 | fn macro_reexport() { |
506 | let map = import_map( | 505 | check( |
507 | r" | 506 | r" |
508 | //- /main.rs crate:main deps:lib | 507 | //- /main.rs crate:main deps:lib |
509 | pub mod m { | 508 | pub mod m { |
@@ -515,21 +514,20 @@ mod tests { | |||
515 | () => {}; | 514 | () => {}; |
516 | } | 515 | } |
517 | ", | 516 | ", |
517 | expect![[r#" | ||
518 | main: | ||
519 | - m (t) | ||
520 | - m::pub_macro (m) | ||
521 | lib: | ||
522 | - pub_macro (m) | ||
523 | "#]], | ||
518 | ); | 524 | ); |
519 | |||
520 | assert_snapshot!(map, @r###" | ||
521 | main: | ||
522 | - m (t) | ||
523 | - m::pub_macro (m) | ||
524 | lib: | ||
525 | - pub_macro (m) | ||
526 | "###); | ||
527 | } | 525 | } |
528 | 526 | ||
529 | #[test] | 527 | #[test] |
530 | fn module_reexport() { | 528 | fn module_reexport() { |
531 | // Reexporting modules from a dependency adds all contents to the import map. | 529 | // Reexporting modules from a dependency adds all contents to the import map. |
532 | let map = import_map( | 530 | check( |
533 | r" | 531 | r" |
534 | //- /main.rs crate:main deps:lib | 532 | //- /main.rs crate:main deps:lib |
535 | pub use lib::module as reexported_module; | 533 | pub use lib::module as reexported_module; |
@@ -538,24 +536,23 @@ mod tests { | |||
538 | pub struct S; | 536 | pub struct S; |
539 | } | 537 | } |
540 | ", | 538 | ", |
539 | expect![[r#" | ||
540 | main: | ||
541 | - reexported_module (t) | ||
542 | - reexported_module::S (t) | ||
543 | - reexported_module::S (v) | ||
544 | lib: | ||
545 | - module (t) | ||
546 | - module::S (t) | ||
547 | - module::S (v) | ||
548 | "#]], | ||
541 | ); | 549 | ); |
542 | |||
543 | assert_snapshot!(map, @r###" | ||
544 | main: | ||
545 | - reexported_module (t) | ||
546 | - reexported_module::S (t) | ||
547 | - reexported_module::S (v) | ||
548 | lib: | ||
549 | - module (t) | ||
550 | - module::S (t) | ||
551 | - module::S (v) | ||
552 | "###); | ||
553 | } | 550 | } |
554 | 551 | ||
555 | #[test] | 552 | #[test] |
556 | fn cyclic_module_reexport() { | 553 | fn cyclic_module_reexport() { |
557 | // A cyclic reexport does not hang. | 554 | // A cyclic reexport does not hang. |
558 | let map = import_map( | 555 | check( |
559 | r" | 556 | r" |
560 | //- /lib.rs crate:lib | 557 | //- /lib.rs crate:lib |
561 | pub mod module { | 558 | pub mod module { |
@@ -567,36 +564,35 @@ mod tests { | |||
567 | pub use super::module; | 564 | pub use super::module; |
568 | } | 565 | } |
569 | ", | 566 | ", |
567 | expect![[r#" | ||
568 | lib: | ||
569 | - module (t) | ||
570 | - module::S (t) | ||
571 | - module::S (v) | ||
572 | - sub (t) | ||
573 | "#]], | ||
570 | ); | 574 | ); |
571 | |||
572 | assert_snapshot!(map, @r###" | ||
573 | lib: | ||
574 | - module (t) | ||
575 | - module::S (t) | ||
576 | - module::S (v) | ||
577 | - sub (t) | ||
578 | "###); | ||
579 | } | 575 | } |
580 | 576 | ||
581 | #[test] | 577 | #[test] |
582 | fn private_macro() { | 578 | fn private_macro() { |
583 | let map = import_map( | 579 | check( |
584 | r" | 580 | r" |
585 | //- /lib.rs crate:lib | 581 | //- /lib.rs crate:lib |
586 | macro_rules! private_macro { | 582 | macro_rules! private_macro { |
587 | () => {}; | 583 | () => {}; |
588 | } | 584 | } |
589 | ", | 585 | ", |
590 | ); | 586 | expect![[r#" |
587 | lib: | ||
591 | 588 | ||
592 | assert_snapshot!(map, @r###" | 589 | "#]], |
593 | lib: | 590 | ); |
594 | "###); | ||
595 | } | 591 | } |
596 | 592 | ||
597 | #[test] | 593 | #[test] |
598 | fn namespacing() { | 594 | fn namespacing() { |
599 | let map = import_map( | 595 | check( |
600 | r" | 596 | r" |
601 | //- /lib.rs crate:lib | 597 | //- /lib.rs crate:lib |
602 | pub struct Thing; // t + v | 598 | pub struct Thing; // t + v |
@@ -605,16 +601,15 @@ mod tests { | |||
605 | () => {}; | 601 | () => {}; |
606 | } | 602 | } |
607 | ", | 603 | ", |
604 | expect![[r#" | ||
605 | lib: | ||
606 | - Thing (m) | ||
607 | - Thing (t) | ||
608 | - Thing (v) | ||
609 | "#]], | ||
608 | ); | 610 | ); |
609 | 611 | ||
610 | assert_snapshot!(map, @r###" | 612 | check( |
611 | lib: | ||
612 | - Thing (m) | ||
613 | - Thing (t) | ||
614 | - Thing (v) | ||
615 | "###); | ||
616 | |||
617 | let map = import_map( | ||
618 | r" | 613 | r" |
619 | //- /lib.rs crate:lib | 614 | //- /lib.rs crate:lib |
620 | pub mod Thing {} // t | 615 | pub mod Thing {} // t |
@@ -623,13 +618,12 @@ mod tests { | |||
623 | () => {}; | 618 | () => {}; |
624 | } | 619 | } |
625 | ", | 620 | ", |
621 | expect![[r#" | ||
622 | lib: | ||
623 | - Thing (m) | ||
624 | - Thing (t) | ||
625 | "#]], | ||
626 | ); | 626 | ); |
627 | |||
628 | assert_snapshot!(map, @r###" | ||
629 | lib: | ||
630 | - Thing (m) | ||
631 | - Thing (t) | ||
632 | "###); | ||
633 | } | 627 | } |
634 | 628 | ||
635 | #[test] | 629 | #[test] |
@@ -658,25 +652,33 @@ mod tests { | |||
658 | } | 652 | } |
659 | "#; | 653 | "#; |
660 | 654 | ||
661 | let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt")); | 655 | check_search( |
662 | assert_snapshot!(res, @r###" | 656 | ra_fixture, |
663 | dep::fmt (t) | 657 | "main", |
664 | dep::Fmt (t) | 658 | Query::new("fmt"), |
665 | dep::Fmt (v) | 659 | expect![[r#" |
666 | dep::Fmt (m) | 660 | dep::fmt (t) |
667 | dep::fmt::Display (t) | 661 | dep::Fmt (t) |
668 | dep::format (v) | 662 | dep::Fmt (v) |
669 | dep::fmt::Display (t) | 663 | dep::Fmt (m) |
670 | "###); | 664 | dep::fmt::Display (t) |
671 | 665 | dep::format (v) | |
672 | let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt").anchor_end()); | 666 | dep::fmt::Display (t) |
673 | assert_snapshot!(res, @r###" | 667 | "#]], |
674 | dep::fmt (t) | 668 | ); |
675 | dep::Fmt (t) | 669 | |
676 | dep::Fmt (v) | 670 | check_search( |
677 | dep::Fmt (m) | 671 | ra_fixture, |
678 | dep::fmt::Display (t) | 672 | "main", |
679 | "###); | 673 | Query::new("fmt").anchor_end(), |
674 | expect![[r#" | ||
675 | dep::fmt (t) | ||
676 | dep::Fmt (t) | ||
677 | dep::Fmt (v) | ||
678 | dep::Fmt (m) | ||
679 | dep::fmt::Display (t) | ||
680 | "#]], | ||
681 | ); | ||
680 | } | 682 | } |
681 | 683 | ||
682 | #[test] | 684 | #[test] |
@@ -689,26 +691,32 @@ mod tests { | |||
689 | pub struct FMT; | 691 | pub struct FMT; |
690 | "#; | 692 | "#; |
691 | 693 | ||
692 | let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT")); | 694 | check_search( |
693 | 695 | ra_fixture, | |
694 | assert_snapshot!(res, @r###" | 696 | "main", |
695 | dep::fmt (t) | 697 | Query::new("FMT"), |
696 | dep::fmt (v) | 698 | expect![[r#" |
697 | dep::FMT (t) | 699 | dep::fmt (t) |
698 | dep::FMT (v) | 700 | dep::fmt (v) |
699 | "###); | 701 | dep::FMT (t) |
700 | 702 | dep::FMT (v) | |
701 | let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT").case_sensitive()); | 703 | "#]], |
704 | ); | ||
702 | 705 | ||
703 | assert_snapshot!(res, @r###" | 706 | check_search( |
704 | dep::FMT (t) | 707 | ra_fixture, |
705 | dep::FMT (v) | 708 | "main", |
706 | "###); | 709 | Query::new("FMT").case_sensitive(), |
710 | expect![[r#" | ||
711 | dep::FMT (t) | ||
712 | dep::FMT (v) | ||
713 | "#]], | ||
714 | ); | ||
707 | } | 715 | } |
708 | 716 | ||
709 | #[test] | 717 | #[test] |
710 | fn search_limit() { | 718 | fn search_limit() { |
711 | let res = search_dependencies_of( | 719 | check_search( |
712 | r#" | 720 | r#" |
713 | //- /main.rs crate:main deps:dep | 721 | //- /main.rs crate:main deps:dep |
714 | //- /dep.rs crate:dep | 722 | //- /dep.rs crate:dep |
@@ -728,10 +736,10 @@ mod tests { | |||
728 | "#, | 736 | "#, |
729 | "main", | 737 | "main", |
730 | Query::new("").limit(2), | 738 | Query::new("").limit(2), |
739 | expect![[r#" | ||
740 | dep::fmt (t) | ||
741 | dep::Fmt (t) | ||
742 | "#]], | ||
731 | ); | 743 | ); |
732 | assert_snapshot!(res, @r###" | ||
733 | dep::fmt (t) | ||
734 | dep::Fmt (t) | ||
735 | "###); | ||
736 | } | 744 | } |
737 | } | 745 | } |
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index 3da16fbe3..ae58948c4 100644 --- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs | |||
@@ -686,27 +686,25 @@ fn unresolved_module_diagnostics() { | |||
686 | 686 | ||
687 | let crate_def_map = db.crate_def_map(krate); | 687 | let crate_def_map = db.crate_def_map(krate); |
688 | 688 | ||
689 | insta::assert_debug_snapshot!( | 689 | expect![[r#" |
690 | crate_def_map.diagnostics, | 690 | [ |
691 | @r###" | 691 | UnresolvedModule { |
692 | [ | 692 | module: Idx::<ModuleData>(0), |
693 | UnresolvedModule { | 693 | declaration: InFile { |
694 | module: Idx::<ModuleData>(0), | 694 | file_id: HirFileId( |
695 | declaration: InFile { | ||
696 | file_id: HirFileId( | ||
697 | FileId( | ||
698 | FileId( | 695 | FileId( |
699 | 0, | 696 | FileId( |
697 | 0, | ||
698 | ), | ||
700 | ), | 699 | ), |
701 | ), | 700 | ), |
702 | ), | 701 | value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1), |
703 | value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1), | 702 | }, |
703 | candidate: "bar.rs", | ||
704 | }, | 704 | }, |
705 | candidate: "bar.rs", | 705 | ] |
706 | }, | 706 | "#]] |
707 | ] | 707 | .assert_debug_eq(&crate_def_map.diagnostics); |
708 | "### | ||
709 | ); | ||
710 | } | 708 | } |
711 | 709 | ||
712 | #[test] | 710 | #[test] |
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index 14980afdd..ff602202f 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -161,6 +161,10 @@ impl ActiveParameter { | |||
161 | 161 | ||
162 | let idx = active_parameter?; | 162 | let idx = active_parameter?; |
163 | let mut params = signature.params(sema.db); | 163 | let mut params = signature.params(sema.db); |
164 | if !(idx < params.len()) { | ||
165 | mark::hit!(too_many_arguments); | ||
166 | return None; | ||
167 | } | ||
164 | let (pat, ty) = params.swap_remove(idx); | 168 | let (pat, ty) = params.swap_remove(idx); |
165 | let name = pat?.to_string(); | 169 | let name = pat?.to_string(); |
166 | Some(ActiveParameter { ty, name }) | 170 | Some(ActiveParameter { ty, name }) |
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index c7b74e635..9a94ff476 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -1160,6 +1160,22 @@ fn go(world: &WorldSnapshot) { go(w<|>) } | |||
1160 | } | 1160 | } |
1161 | 1161 | ||
1162 | #[test] | 1162 | #[test] |
1163 | fn too_many_arguments() { | ||
1164 | mark::check!(too_many_arguments); | ||
1165 | check_scores( | ||
1166 | r#" | ||
1167 | struct Foo; | ||
1168 | fn f(foo: &Foo) { f(foo, w<|>) } | ||
1169 | "#, | ||
1170 | expect![[r#" | ||
1171 | st Foo [] | ||
1172 | fn f(…) [] | ||
1173 | bn foo [] | ||
1174 | "#]], | ||
1175 | ); | ||
1176 | } | ||
1177 | |||
1178 | #[test] | ||
1163 | fn guesses_macro_braces() { | 1179 | fn guesses_macro_braces() { |
1164 | check_edit( | 1180 | check_edit( |
1165 | "vec!", | 1181 | "vec!", |