⬆️ rust-analyzer

This commit is contained in:
Laurențiu Nicola 2022-09-20 17:39:17 +03:00
parent 459bbb4222
commit f5fde4df43
76 changed files with 1613 additions and 654 deletions

View file

@ -41,6 +41,12 @@ pub struct AnnotationConfig {
pub annotate_references: bool,
pub annotate_method_references: bool,
pub annotate_enum_variant_references: bool,
pub location: AnnotationLocation,
}
pub enum AnnotationLocation {
AboveName,
AboveWholeItem,
}
pub(crate) fn annotations(
@ -65,10 +71,10 @@ pub(crate) fn annotations(
visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
let range = match def {
Definition::Const(konst) if config.annotate_references => {
konst.source(db).and_then(|node| name_range(db, node, file_id))
konst.source(db).and_then(|node| name_range(db, config, node, file_id))
}
Definition::Trait(trait_) if config.annotate_references || config.annotate_impls => {
trait_.source(db).and_then(|node| name_range(db, node, file_id))
trait_.source(db).and_then(|node| name_range(db, config, node, file_id))
}
Definition::Adt(adt) => match adt {
hir::Adt::Enum(enum_) => {
@ -77,7 +83,9 @@ pub(crate) fn annotations(
.variants(db)
.into_iter()
.map(|variant| {
variant.source(db).and_then(|node| name_range(db, node, file_id))
variant
.source(db)
.and_then(|node| name_range(db, config, node, file_id))
})
.flatten()
.for_each(|range| {
@ -88,14 +96,14 @@ pub(crate) fn annotations(
})
}
if config.annotate_references || config.annotate_impls {
enum_.source(db).and_then(|node| name_range(db, node, file_id))
enum_.source(db).and_then(|node| name_range(db, config, node, file_id))
} else {
None
}
}
_ => {
if config.annotate_references || config.annotate_impls {
adt.source(db).and_then(|node| name_range(db, node, file_id))
adt.source(db).and_then(|node| name_range(db, config, node, file_id))
} else {
None
}
@ -113,6 +121,7 @@ pub(crate) fn annotations(
annotations
.push(Annotation { range, kind: AnnotationKind::HasImpls { file_id, data: None } });
}
if config.annotate_references {
annotations.push(Annotation {
range,
@ -122,12 +131,18 @@ pub(crate) fn annotations(
fn name_range<T: HasName>(
db: &RootDatabase,
config: &AnnotationConfig,
node: InFile<T>,
source_file_id: FileId,
) -> Option<TextRange> {
if let Some(InFile { file_id, value }) = node.original_ast_node(db) {
if file_id == source_file_id.into() {
return value.name().map(|it| it.syntax().text_range());
return match config.location {
AnnotationLocation::AboveName => {
value.name().map(|name| name.syntax().text_range())
}
AnnotationLocation::AboveWholeItem => Some(value.syntax().text_range()),
};
}
}
None
@ -188,21 +203,23 @@ mod tests {
use crate::{fixture, Annotation, AnnotationConfig};
fn check(ra_fixture: &str, expect: Expect) {
use super::AnnotationLocation;
const DEFAULT_CONFIG: AnnotationConfig = AnnotationConfig {
binary_target: true,
annotate_runnables: true,
annotate_impls: true,
annotate_references: true,
annotate_method_references: true,
annotate_enum_variant_references: true,
location: AnnotationLocation::AboveName,
};
fn check_with_config(ra_fixture: &str, expect: Expect, config: &AnnotationConfig) {
let (analysis, file_id) = fixture::file(ra_fixture);
let annotations: Vec<Annotation> = analysis
.annotations(
&AnnotationConfig {
binary_target: true,
annotate_runnables: true,
annotate_impls: true,
annotate_references: true,
annotate_method_references: true,
annotate_enum_variant_references: true,
},
file_id,
)
.annotations(config, file_id)
.unwrap()
.into_iter()
.map(|annotation| analysis.resolve_annotation(annotation).unwrap())
@ -211,6 +228,10 @@ mod tests {
expect.assert_debug_eq(&annotations);
}
fn check(ra_fixture: &str, expect: Expect) {
check_with_config(ra_fixture, expect, &DEFAULT_CONFIG);
}
#[test]
fn const_annotations() {
check(
@ -786,4 +807,40 @@ m!();
"#]],
);
}
#[test]
fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
check_with_config(
r#"
/// This is a struct named Foo, obviously.
#[derive(Clone)]
struct Foo;
"#,
expect![[r#"
[
Annotation {
range: 0..71,
kind: HasImpls {
file_id: FileId(
0,
),
data: Some(
[],
),
},
},
Annotation {
range: 0..71,
kind: HasReferences {
file_id: FileId(
0,
),
data: None,
},
},
]
"#]],
&AnnotationConfig { location: AnnotationLocation::AboveWholeItem, ..DEFAULT_CONFIG },
);
}
}

View file

@ -377,6 +377,7 @@ mod tests {
match it {
ReferenceCategory::Read => "read",
ReferenceCategory::Write => "write",
ReferenceCategory::Import => "import",
}
.to_string()
}),
@ -423,12 +424,12 @@ struct Foo;
check(
r#"
use crate$0;
//^^^^^
//^^^^^ import
use self;
//^^^^
//^^^^ import
mod __ {
use super;
//^^^^^
//^^^^^ import
}
"#,
);
@ -436,7 +437,7 @@ mod __ {
r#"
//- /main.rs crate:main deps:lib
use lib$0;
//^^^
//^^^ import
//- /lib.rs crate:lib
"#,
);
@ -450,7 +451,7 @@ use lib$0;
mod foo;
//- /foo.rs
use self$0;
// ^^^^
// ^^^^ import
"#,
);
}

View file

@ -1687,6 +1687,74 @@ fn main() {
);
}
#[test]
fn iterator_hint_regression_issue_12674() {
// Ensure we don't crash while solving the projection type of iterators.
check_expect(
InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
r#"
//- minicore: iterators
struct S<T>(T);
impl<T> S<T> {
fn iter(&self) -> Iter<'_, T> { loop {} }
}
struct Iter<'a, T: 'a>(&'a T);
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { loop {} }
}
struct Container<'a> {
elements: S<&'a str>,
}
struct SliceIter<'a, T>(&'a T);
impl<'a, T> Iterator for SliceIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { loop {} }
}
fn main(a: SliceIter<'_, Container>) {
a
.filter_map(|c| Some(c.elements.iter().filter_map(|v| Some(v))))
.map(|e| e);
}
"#,
expect![[r#"
[
InlayHint {
range: 484..554,
kind: ChainingHint,
label: [
"impl Iterator<Item = impl Iterator<Item = &&str>>",
],
tooltip: Some(
HoverRanged(
FileId(
0,
),
484..554,
),
),
},
InlayHint {
range: 484..485,
kind: ChainingHint,
label: [
"SliceIter<Container>",
],
tooltip: Some(
HoverRanged(
FileId(
0,
),
484..485,
),
),
},
]
"#]],
);
}
#[test]
fn infer_call_method_return_associated_types_with_generic() {
check_types(

View file

@ -74,7 +74,7 @@ use syntax::SourceFile;
use crate::navigation_target::{ToNav, TryToNav};
pub use crate::{
annotations::{Annotation, AnnotationConfig, AnnotationKind},
annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
call_hierarchy::CallItem,
expand_macro::ExpandedMacro,
file_structure::{StructureNode, StructureNodeKind},

View file

@ -742,7 +742,7 @@ pub struct Foo {
expect![[r#"
foo Module FileId(0) 0..8 4..7
FileId(0) 14..17
FileId(0) 14..17 Import
"#]],
);
}
@ -760,7 +760,7 @@ use self$0;
expect![[r#"
foo Module FileId(0) 0..8 4..7
FileId(1) 4..8
FileId(1) 4..8 Import
"#]],
);
}
@ -775,7 +775,7 @@ use self$0;
expect![[r#"
Module FileId(0) 0..10
FileId(0) 4..8
FileId(0) 4..8 Import
"#]],
);
}
@ -803,7 +803,7 @@ pub(super) struct Foo$0 {
expect![[r#"
Foo Struct FileId(2) 0..41 18..21
FileId(1) 20..23
FileId(1) 20..23 Import
FileId(1) 47..50
"#]],
);
@ -966,7 +966,7 @@ fn g() { f(); }
expect![[r#"
f Function FileId(0) 22..31 25..26
FileId(1) 11..12
FileId(1) 11..12 Import
FileId(1) 24..25
"#]],
);
@ -1424,9 +1424,9 @@ pub use level1::Foo;
expect![[r#"
Foo Struct FileId(0) 0..15 11..14
FileId(1) 16..19
FileId(2) 16..19
FileId(3) 16..19
FileId(1) 16..19 Import
FileId(2) 16..19 Import
FileId(3) 16..19 Import
"#]],
);
}
@ -1454,7 +1454,7 @@ lib::foo!();
expect![[r#"
foo Macro FileId(1) 0..61 29..32
FileId(0) 46..49
FileId(0) 46..49 Import
FileId(2) 0..3
FileId(3) 5..8
"#]],
@ -1617,7 +1617,7 @@ struct Foo;
expect![[r#"
derive_identity Derive FileId(2) 1..107 45..60
FileId(0) 17..31
FileId(0) 17..31 Import
FileId(0) 56..70
"#]],
);