aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/nameres/tests/mod_resolution.rs21
-rw-r--r--crates/hir_def/src/path/lower/lower_use.rs2
-rw-r--r--crates/ide/src/hover.rs119
-rw-r--r--crates/syntax/src/ast/token_ext.rs77
-rw-r--r--crates/vfs/src/file_set.rs51
-rw-r--r--crates/vfs/src/file_set/tests.rs42
-rw-r--r--crates/vfs/src/vfs_path.rs33
-rw-r--r--crates/vfs/src/vfs_path/tests.rs30
8 files changed, 225 insertions, 150 deletions
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs
index ba295fd9e..ef6f85e15 100644
--- a/crates/hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs
@@ -798,3 +798,24 @@ mod foo;
798"#, 798"#,
799 ); 799 );
800} 800}
801
802#[test]
803fn abs_path_ignores_local() {
804 check(
805 r#"
806//- /main.rs crate:main deps:core
807pub use ::core::hash::Hash;
808pub mod core {}
809
810//- /lib.rs crate:core
811pub mod hash { pub trait Hash {} }
812"#,
813 expect![[r#"
814 crate
815 Hash: t
816 core: t
817
818 crate::core
819 "#]],
820 );
821}
diff --git a/crates/hir_def/src/path/lower/lower_use.rs b/crates/hir_def/src/path/lower/lower_use.rs
index 53cecb05f..ba0d1f0e7 100644
--- a/crates/hir_def/src/path/lower/lower_use.rs
+++ b/crates/hir_def/src/path/lower/lower_use.rs
@@ -76,7 +76,7 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) ->
76 Either::Left(name) => { 76 Either::Left(name) => {
77 // no type args in use 77 // no type args in use
78 let mut res = prefix.unwrap_or_else(|| ModPath { 78 let mut res = prefix.unwrap_or_else(|| ModPath {
79 kind: PathKind::Plain, 79 kind: segment.coloncolon_token().map_or(PathKind::Plain, |_| PathKind::Abs),
80 segments: Vec::with_capacity(1), 80 segments: Vec::with_capacity(1),
81 }); 81 });
82 res.segments.push(name); 82 res.segments.push(name);
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 94ad800a0..462f5c2b8 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -295,7 +295,6 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
295 ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)), 295 ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)),
296 _ => None, 296 _ => None,
297 }, 297 },
298 Definition::SelfType(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
299 _ => None, 298 _ => None,
300 } 299 }
301 .map(|name| name.to_string()) 300 .map(|name| name.to_string())
@@ -357,7 +356,14 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
357 ModuleDef::BuiltinType(it) => return Some(it.to_string().into()), 356 ModuleDef::BuiltinType(it) => return Some(it.to_string().into()),
358 }, 357 },
359 Definition::Local(it) => return Some(Markup::fenced_block(&it.ty(db).display(db))), 358 Definition::Local(it) => return Some(Markup::fenced_block(&it.ty(db).display(db))),
360 Definition::TypeParam(_) | Definition::SelfType(_) => { 359 Definition::SelfType(impl_def) => {
360 impl_def.target_ty(db).as_adt().and_then(|adt| match adt {
361 Adt::Struct(it) => from_def_source(db, it, mod_path),
362 Adt::Union(it) => from_def_source(db, it, mod_path),
363 Adt::Enum(it) => from_def_source(db, it, mod_path),
364 })
365 }
366 Definition::TypeParam(_) => {
361 // FIXME: Hover for generic param 367 // FIXME: Hover for generic param
362 None 368 None
363 } 369 }
@@ -1025,52 +1031,75 @@ impl Thing {
1025} 1031}
1026"#, 1032"#,
1027 expect![[r#" 1033 expect![[r#"
1028 *Self { x: 0 }* 1034 *Self*
1035
1029 ```rust 1036 ```rust
1030 Thing 1037 test
1038 ```
1039
1040 ```rust
1041 struct Thing
1031 ``` 1042 ```
1032 "#]], 1043 "#]],
1033 ) 1044 );
1034 } /* FIXME: revive these tests 1045 check(
1035 let (analysis, position) = fixture::position( 1046 r#"
1036 " 1047struct Thing { x: u32 }
1037 struct Thing { x: u32 } 1048impl Thing {
1038 impl Thing { 1049 fn new() -> Self<|> { Self { x: 0 } }
1039 fn new() -> Self<|> { 1050}
1040 Self { x: 0 } 1051"#,
1041 } 1052 expect![[r#"
1042 } 1053 *Self*
1043 ", 1054
1044 ); 1055 ```rust
1045 1056 test
1046 let hover = analysis.hover(position).unwrap().unwrap(); 1057 ```
1047 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); 1058
1048 1059 ```rust
1049 let (analysis, position) = fixture::position( 1060 struct Thing
1050 " 1061 ```
1051 enum Thing { A } 1062 "#]],
1052 impl Thing { 1063 );
1053 pub fn new() -> Self<|> { 1064 check(
1054 Thing::A 1065 r#"
1055 } 1066enum Thing { A }
1056 } 1067impl Thing {
1057 ", 1068 pub fn new() -> Self<|> { Thing::A }
1058 ); 1069}
1059 let hover = analysis.hover(position).unwrap().unwrap(); 1070"#,
1060 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); 1071 expect![[r#"
1061 1072 *Self*
1062 let (analysis, position) = fixture::position( 1073
1063 " 1074 ```rust
1064 enum Thing { A } 1075 test
1065 impl Thing { 1076 ```
1066 pub fn thing(a: Self<|>) { 1077
1067 } 1078 ```rust
1068 } 1079 enum Thing
1069 ", 1080 ```
1070 ); 1081 "#]],
1071 let hover = analysis.hover(position).unwrap().unwrap(); 1082 );
1072 assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); 1083 check(
1073 */ 1084 r#"
1085 enum Thing { A }
1086 impl Thing {
1087 pub fn thing(a: Self<|>) {}
1088 }
1089 "#,
1090 expect![[r#"
1091 *Self*
1092
1093 ```rust
1094 test
1095 ```
1096
1097 ```rust
1098 enum Thing
1099 ```
1100 "#]],
1101 );
1102 }
1074 1103
1075 #[test] 1104 #[test]
1076 fn test_hover_shadowing_pat() { 1105 fn test_hover_shadowing_pat() {
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index b985861f2..fa40e64e8 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -543,11 +543,6 @@ impl HasFormatSpecifier for ast::String {
543} 543}
544 544
545impl ast::IntNumber { 545impl ast::IntNumber {
546 const SUFFIXES: &'static [&'static str] = &[
547 "u8", "u16", "u32", "u64", "u128", "usize", // Unsigned.
548 "i8", "i16", "i32", "i64", "i128", "isize", // Signed.
549 ];
550
551 pub fn radix(&self) -> Radix { 546 pub fn radix(&self) -> Radix {
552 match self.text().get(..2).unwrap_or_default() { 547 match self.text().get(..2).unwrap_or_default() {
553 "0b" => Radix::Binary, 548 "0b" => Radix::Binary,
@@ -580,29 +575,30 @@ impl ast::IntNumber {
580 575
581 pub fn suffix(&self) -> Option<&str> { 576 pub fn suffix(&self) -> Option<&str> {
582 let text = self.text(); 577 let text = self.text();
583 // FIXME: don't check a fixed set of suffixes, `1_0_1_l_o_l` is valid 578 let radix = self.radix();
584 // syntax, suffix is `l_o_l`. 579 let mut indices = text.char_indices();
585 ast::IntNumber::SUFFIXES.iter().chain(ast::FloatNumber::SUFFIXES.iter()).find_map( 580 if radix != Radix::Decimal {
586 |suffix| { 581 indices.next()?;
587 if text.ends_with(suffix) { 582 indices.next()?;
588 return Some(&text[text.len() - suffix.len()..]); 583 }
589 } 584 let is_suffix_start: fn(&(usize, char)) -> bool = match radix {
590 None 585 Radix::Hexadecimal => |(_, c)| matches!(c, 'g'..='z' | 'G'..='Z'),
591 }, 586 _ => |(_, c)| c.is_ascii_alphabetic(),
592 ) 587 };
588 let (suffix_start, _) = indices.find(is_suffix_start)?;
589 Some(&text[suffix_start..])
593 } 590 }
594} 591}
595 592
596impl ast::FloatNumber { 593impl ast::FloatNumber {
597 const SUFFIXES: &'static [&'static str] = &["f32", "f64"];
598 pub fn suffix(&self) -> Option<&str> { 594 pub fn suffix(&self) -> Option<&str> {
599 let text = self.text(); 595 let text = self.text();
600 ast::FloatNumber::SUFFIXES.iter().find_map(|suffix| { 596 let mut indices = text.char_indices();
601 if text.ends_with(suffix) { 597 let (mut suffix_start, c) = indices.by_ref().find(|(_, c)| c.is_ascii_alphabetic())?;
602 return Some(&text[text.len() - suffix.len()..]); 598 if c == 'e' || c == 'E' {
603 } 599 suffix_start = indices.find(|(_, c)| c.is_ascii_alphabetic())?.0;
604 None 600 }
605 }) 601 Some(&text[suffix_start..])
606 } 602 }
607} 603}
608 604
@@ -625,3 +621,40 @@ impl Radix {
625 } 621 }
626 } 622 }
627} 623}
624
625#[cfg(test)]
626mod tests {
627 use crate::ast::{make, FloatNumber, IntNumber};
628
629 fn check_float_suffix<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
630 assert_eq!(FloatNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
631 }
632
633 fn check_int_suffix<'a>(lit: &str, expected: impl Into<Option<&'a str>>) {
634 assert_eq!(IntNumber { syntax: make::tokens::literal(lit) }.suffix(), expected.into());
635 }
636
637 #[test]
638 fn test_float_number_suffix() {
639 check_float_suffix("123.0", None);
640 check_float_suffix("123f32", "f32");
641 check_float_suffix("123.0e", None);
642 check_float_suffix("123.0e4", None);
643 check_float_suffix("123.0ef32", "f32");
644 check_float_suffix("123.0E4f32", "f32");
645 check_float_suffix("1_2_3.0_f32", "f32");
646 }
647
648 #[test]
649 fn test_int_number_suffix() {
650 check_int_suffix("123", None);
651 check_int_suffix("123i32", "i32");
652 check_int_suffix("1_0_1_l_o_l", "l_o_l");
653 check_int_suffix("0b11", None);
654 check_int_suffix("0o11", None);
655 check_int_suffix("0xff", None);
656 check_int_suffix("0b11u32", "u32");
657 check_int_suffix("0o11u32", "u32");
658 check_int_suffix("0xffu32", "u32");
659 }
660}
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index 4aa2d6526..9093fbd97 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -158,53 +158,4 @@ impl fst::Automaton for PrefixOf<'_> {
158} 158}
159 159
160#[cfg(test)] 160#[cfg(test)]
161mod tests { 161mod tests;
162 use super::*;
163
164 #[test]
165 fn path_prefix() {
166 let mut file_set = FileSetConfig::builder();
167 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo".into())]);
168 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo/bar/baz".into())]);
169 let file_set = file_set.build();
170
171 let mut vfs = Vfs::default();
172 vfs.set_file_contents(
173 VfsPath::new_virtual_path("/foo/src/lib.rs".into()),
174 Some(Vec::new()),
175 );
176 vfs.set_file_contents(
177 VfsPath::new_virtual_path("/foo/src/bar/baz/lib.rs".into()),
178 Some(Vec::new()),
179 );
180 vfs.set_file_contents(
181 VfsPath::new_virtual_path("/foo/bar/baz/lib.rs".into()),
182 Some(Vec::new()),
183 );
184 vfs.set_file_contents(VfsPath::new_virtual_path("/quux/lib.rs".into()), Some(Vec::new()));
185
186 let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
187 assert_eq!(partition, vec![2, 1, 1]);
188 }
189
190 #[test]
191 fn name_prefix() {
192 let mut file_set = FileSetConfig::builder();
193 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo".into())]);
194 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo-things".into())]);
195 let file_set = file_set.build();
196
197 let mut vfs = Vfs::default();
198 vfs.set_file_contents(
199 VfsPath::new_virtual_path("/foo/src/lib.rs".into()),
200 Some(Vec::new()),
201 );
202 vfs.set_file_contents(
203 VfsPath::new_virtual_path("/foo-things/src/lib.rs".into()),
204 Some(Vec::new()),
205 );
206
207 let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
208 assert_eq!(partition, vec![1, 1, 0]);
209 }
210}
diff --git a/crates/vfs/src/file_set/tests.rs b/crates/vfs/src/file_set/tests.rs
new file mode 100644
index 000000000..2146df185
--- /dev/null
+++ b/crates/vfs/src/file_set/tests.rs
@@ -0,0 +1,42 @@
1use super::*;
2
3#[test]
4fn path_prefix() {
5 let mut file_set = FileSetConfig::builder();
6 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo".into())]);
7 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo/bar/baz".into())]);
8 let file_set = file_set.build();
9
10 let mut vfs = Vfs::default();
11 vfs.set_file_contents(VfsPath::new_virtual_path("/foo/src/lib.rs".into()), Some(Vec::new()));
12 vfs.set_file_contents(
13 VfsPath::new_virtual_path("/foo/src/bar/baz/lib.rs".into()),
14 Some(Vec::new()),
15 );
16 vfs.set_file_contents(
17 VfsPath::new_virtual_path("/foo/bar/baz/lib.rs".into()),
18 Some(Vec::new()),
19 );
20 vfs.set_file_contents(VfsPath::new_virtual_path("/quux/lib.rs".into()), Some(Vec::new()));
21
22 let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
23 assert_eq!(partition, vec![2, 1, 1]);
24}
25
26#[test]
27fn name_prefix() {
28 let mut file_set = FileSetConfig::builder();
29 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo".into())]);
30 file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo-things".into())]);
31 let file_set = file_set.build();
32
33 let mut vfs = Vfs::default();
34 vfs.set_file_contents(VfsPath::new_virtual_path("/foo/src/lib.rs".into()), Some(Vec::new()));
35 vfs.set_file_contents(
36 VfsPath::new_virtual_path("/foo-things/src/lib.rs".into()),
37 Some(Vec::new()),
38 );
39
40 let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
41 assert_eq!(partition, vec![1, 1, 0]);
42}
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
index 815697597..bd14911c9 100644
--- a/crates/vfs/src/vfs_path.rs
+++ b/crates/vfs/src/vfs_path.rs
@@ -311,35 +311,4 @@ impl VirtualPath {
311} 311}
312 312
313#[cfg(test)] 313#[cfg(test)]
314mod tests { 314mod tests;
315 use super::*;
316
317 #[test]
318 fn virtual_path_extensions() {
319 assert_eq!(VirtualPath("/".to_string()).name_and_extension(), None);
320 assert_eq!(
321 VirtualPath("/directory".to_string()).name_and_extension(),
322 Some(("directory", None))
323 );
324 assert_eq!(
325 VirtualPath("/directory/".to_string()).name_and_extension(),
326 Some(("directory", None))
327 );
328 assert_eq!(
329 VirtualPath("/directory/file".to_string()).name_and_extension(),
330 Some(("file", None))
331 );
332 assert_eq!(
333 VirtualPath("/directory/.file".to_string()).name_and_extension(),
334 Some((".file", None))
335 );
336 assert_eq!(
337 VirtualPath("/directory/.file.rs".to_string()).name_and_extension(),
338 Some((".file", Some("rs")))
339 );
340 assert_eq!(
341 VirtualPath("/directory/file.rs".to_string()).name_and_extension(),
342 Some(("file", Some("rs")))
343 );
344 }
345}
diff --git a/crates/vfs/src/vfs_path/tests.rs b/crates/vfs/src/vfs_path/tests.rs
new file mode 100644
index 000000000..510e021e8
--- /dev/null
+++ b/crates/vfs/src/vfs_path/tests.rs
@@ -0,0 +1,30 @@
1use super::*;
2
3#[test]
4fn virtual_path_extensions() {
5 assert_eq!(VirtualPath("/".to_string()).name_and_extension(), None);
6 assert_eq!(
7 VirtualPath("/directory".to_string()).name_and_extension(),
8 Some(("directory", None))
9 );
10 assert_eq!(
11 VirtualPath("/directory/".to_string()).name_and_extension(),
12 Some(("directory", None))
13 );
14 assert_eq!(
15 VirtualPath("/directory/file".to_string()).name_and_extension(),
16 Some(("file", None))
17 );
18 assert_eq!(
19 VirtualPath("/directory/.file".to_string()).name_and_extension(),
20 Some((".file", None))
21 );
22 assert_eq!(
23 VirtualPath("/directory/.file.rs".to_string()).name_and_extension(),
24 Some((".file", Some("rs")))
25 );
26 assert_eq!(
27 VirtualPath("/directory/file.rs".to_string()).name_and_extension(),
28 Some(("file", Some("rs")))
29 );
30}