mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
resolve range patterns to the their struct types
This commit is contained in:
parent
2f6923b844
commit
271f64f94d
4 changed files with 141 additions and 8 deletions
|
@ -203,6 +203,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast))
|
self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<Struct> {
|
||||||
|
self.imp.resolve_range_pat(range_pat).map(Struct::from)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<Struct> {
|
pub fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<Struct> {
|
||||||
self.imp.resolve_range_expr(range_expr).map(Struct::from)
|
self.imp.resolve_range_expr(range_expr).map(Struct::from)
|
||||||
}
|
}
|
||||||
|
@ -1361,6 +1365,10 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
self.analyze(call.syntax())?.resolve_method_call_fallback(self.db, call)
|
self.analyze(call.syntax())?.resolve_method_call_fallback(self.db, call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option<StructId> {
|
||||||
|
self.analyze(range_pat.syntax())?.resolve_range_pat(self.db, range_pat)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<StructId> {
|
fn resolve_range_expr(&self, range_expr: &ast::RangeExpr) -> Option<StructId> {
|
||||||
self.analyze(range_expr.syntax())?.resolve_range_expr(self.db, range_expr)
|
self.analyze(range_expr.syntax())?.resolve_range_expr(self.db, range_expr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,26 @@ impl SourceAnalyzer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resolve_range_pat(
|
||||||
|
&self,
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
range_pat: &ast::RangePat,
|
||||||
|
) -> Option<StructId> {
|
||||||
|
let path: ModPath = match (range_pat.op_kind()?, range_pat.start(), range_pat.end()) {
|
||||||
|
(RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
|
||||||
|
(RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
|
||||||
|
(RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
|
||||||
|
(RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
|
||||||
|
(RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
|
||||||
|
|
||||||
|
(RangeOp::Exclusive, None, None) => return None,
|
||||||
|
(RangeOp::Inclusive, None, None) => return None,
|
||||||
|
(RangeOp::Inclusive, Some(_), None) => return None,
|
||||||
|
};
|
||||||
|
let s = self.resolver.resolve_known_struct(db.upcast(), &path);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_range_expr(
|
pub(crate) fn resolve_range_expr(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
|
|
|
@ -318,7 +318,8 @@ impl IdentClass {
|
||||||
.map(IdentClass::NameClass)
|
.map(IdentClass::NameClass)
|
||||||
.or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
|
.or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
|
||||||
},
|
},
|
||||||
ast::RangeExpr(range_expr) => OperatorClass::classify_range(sema, &range_expr).map(IdentClass::Operator),
|
ast::RangePat(range_pat) => OperatorClass::classify_range_pat(sema, &range_pat).map(IdentClass::Operator),
|
||||||
|
ast::RangeExpr(range_expr) => OperatorClass::classify_range_expr(sema, &range_expr).map(IdentClass::Operator),
|
||||||
ast::AwaitExpr(await_expr) => OperatorClass::classify_await(sema, &await_expr).map(IdentClass::Operator),
|
ast::AwaitExpr(await_expr) => OperatorClass::classify_await(sema, &await_expr).map(IdentClass::Operator),
|
||||||
ast::BinExpr(bin_expr) => OperatorClass::classify_bin(sema, &bin_expr).map(IdentClass::Operator),
|
ast::BinExpr(bin_expr) => OperatorClass::classify_bin(sema, &bin_expr).map(IdentClass::Operator),
|
||||||
ast::IndexExpr(index_expr) => OperatorClass::classify_index(sema, &index_expr).map(IdentClass::Operator),
|
ast::IndexExpr(index_expr) => OperatorClass::classify_index(sema, &index_expr).map(IdentClass::Operator),
|
||||||
|
@ -558,7 +559,14 @@ pub enum OperatorClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OperatorClass {
|
impl OperatorClass {
|
||||||
pub fn classify_range(
|
pub fn classify_range_pat(
|
||||||
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
|
range_pat: &ast::RangePat,
|
||||||
|
) -> Option<OperatorClass> {
|
||||||
|
sema.resolve_range_pat(range_pat).map(OperatorClass::Range)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn classify_range_expr(
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
range_expr: &ast::RangeExpr,
|
range_expr: &ast::RangeExpr,
|
||||||
) -> Option<OperatorClass> {
|
) -> Option<OperatorClass> {
|
||||||
|
|
|
@ -98,6 +98,7 @@ pub(crate) fn goto_definition(
|
||||||
return Some(vec![x]);
|
return Some(vec![x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
IdentClass::classify_node(sema, &parent)?
|
IdentClass::classify_node(sema, &parent)?
|
||||||
.definitions()
|
.definitions()
|
||||||
|
@ -460,7 +461,103 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range() {
|
fn goto_def_pat_range_to_inclusive() {
|
||||||
|
check_name(
|
||||||
|
"RangeToInclusive",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
..$0='z' => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_pat_range_to() {
|
||||||
|
check_name(
|
||||||
|
"RangeTo",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
.$0.'z' => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_pat_range() {
|
||||||
|
check_name(
|
||||||
|
"Range",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
'a'.$0.'z' => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_pat_range_inclusive() {
|
||||||
|
check_name(
|
||||||
|
"RangeInclusive",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
'a'..$0='z' => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_pat_range_from() {
|
||||||
|
check_name(
|
||||||
|
"RangeFrom",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
'a'..$0 => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_range_pat_inclusive() {
|
||||||
|
check_name(
|
||||||
|
"RangeInclusive",
|
||||||
|
r#"
|
||||||
|
//- minicore: range
|
||||||
|
fn f(ch: char) -> bool {
|
||||||
|
match ch {
|
||||||
|
'a'..$0='z' => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_expr_range() {
|
||||||
check_name(
|
check_name(
|
||||||
"Range",
|
"Range",
|
||||||
r#"
|
r#"
|
||||||
|
@ -471,7 +568,7 @@ let x = 0.$0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range_from() {
|
fn goto_def_expr_range_from() {
|
||||||
check_name(
|
check_name(
|
||||||
"RangeFrom",
|
"RangeFrom",
|
||||||
r#"
|
r#"
|
||||||
|
@ -484,7 +581,7 @@ fn f(arr: &[i32]) -> &[i32] {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range_inclusive() {
|
fn goto_def_expr_range_inclusive() {
|
||||||
check_name(
|
check_name(
|
||||||
"RangeInclusive",
|
"RangeInclusive",
|
||||||
r#"
|
r#"
|
||||||
|
@ -495,7 +592,7 @@ let x = 0.$0.=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range_full() {
|
fn goto_def_expr_range_full() {
|
||||||
check_name(
|
check_name(
|
||||||
"RangeFull",
|
"RangeFull",
|
||||||
r#"
|
r#"
|
||||||
|
@ -508,7 +605,7 @@ fn f(arr: &[i32]) -> &[i32] {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range_to() {
|
fn goto_def_expr_range_to() {
|
||||||
check_name(
|
check_name(
|
||||||
"RangeTo",
|
"RangeTo",
|
||||||
r#"
|
r#"
|
||||||
|
@ -521,7 +618,7 @@ fn f(arr: &[i32]) -> &[i32] {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn goto_def_range_to_inclusive() {
|
fn goto_def_expr_range_to_inclusive() {
|
||||||
check_name(
|
check_name(
|
||||||
"RangeToInclusive",
|
"RangeToInclusive",
|
||||||
r#"
|
r#"
|
||||||
|
|
Loading…
Reference in a new issue