Skip to content

Commit 83fd0fb

Browse files
bors[bot]unexge
andauthored
Merge #4775
4775: Add goto def for enum variant field r=matklad a=unexge Closes #4764. I'm not familiar with ra codebase, there might be better ways to do that 😄 Co-authored-by: unexge <unexge@gmail.com>
2 parents db36a25 + 48b6dd0 commit 83fd0fb

File tree

3 files changed

+57
-24
lines changed

3 files changed

+57
-24
lines changed

crates/ra_ide/src/goto_definition.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use hir::Semantics;
22
use ra_ide_db::{
3-
defs::{classify_name, classify_name_ref},
3+
defs::{classify_name, classify_name_ref, NameClass},
44
symbol_index, RootDatabase,
55
};
66
use ra_syntax::{
@@ -39,7 +39,10 @@ pub(crate) fn goto_definition(
3939
reference_definition(&sema, &name_ref).to_vec()
4040
},
4141
ast::Name(name) => {
42-
let def = classify_name(&sema, &name)?.definition();
42+
let def = match classify_name(&sema, &name)? {
43+
NameClass::Definition(def) | NameClass::ConstReference(def) => def,
44+
NameClass::FieldShorthand { local: _, field } => field,
45+
};
4346
let nav = def.try_to_nav(sema.db)?;
4447
vec![nav]
4548
},
@@ -886,4 +889,23 @@ mod tests {
886889
"x",
887890
)
888891
}
892+
893+
#[test]
894+
fn goto_def_for_enum_variant_field() {
895+
check_goto(
896+
"
897+
//- /lib.rs
898+
enum Foo {
899+
Bar { x: i32 }
900+
}
901+
fn baz(foo: Foo) {
902+
match foo {
903+
Foo::Bar { x<|> } => x
904+
};
905+
}
906+
",
907+
"x RECORD_FIELD_DEF FileId(1) 21..27 21..22",
908+
"x: i32|x",
909+
);
910+
}
889911
}

crates/ra_ide/src/syntax_highlighting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ fn highlight_element(
436436
highlight_name(db, def) | HighlightModifier::Definition
437437
}
438438
Some(NameClass::ConstReference(def)) => highlight_name(db, def),
439+
Some(NameClass::FieldShorthand { .. }) => HighlightTag::Field.into(),
439440
None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
440441
}
441442
}

crates/ra_ide_db/src/defs.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,38 +82,40 @@ pub enum NameClass {
8282
Definition(Definition),
8383
/// `None` in `if let None = Some(82) {}`
8484
ConstReference(Definition),
85+
FieldShorthand {
86+
local: Local,
87+
field: Definition,
88+
},
8589
}
8690

8791
impl NameClass {
8892
pub fn into_definition(self) -> Option<Definition> {
8993
match self {
9094
NameClass::Definition(it) => Some(it),
9195
NameClass::ConstReference(_) => None,
96+
NameClass::FieldShorthand { local, field: _ } => Some(Definition::Local(local)),
9297
}
9398
}
9499

95100
pub fn definition(self) -> Definition {
96101
match self {
97102
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
103+
NameClass::FieldShorthand { local: _, field } => field,
98104
}
99105
}
100106
}
101107

102108
pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
103109
let _p = profile("classify_name");
104110

105-
if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
111+
let parent = name.syntax().parent()?;
112+
113+
if let Some(bind_pat) = ast::BindPat::cast(parent.clone()) {
106114
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
107115
return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
108116
}
109117
}
110118

111-
classify_name_inner(sema, name).map(NameClass::Definition)
112-
}
113-
114-
fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
115-
let parent = name.syntax().parent()?;
116-
117119
match_ast! {
118120
match parent {
119121
ast::Alias(it) => {
@@ -123,63 +125,71 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
123125
let name_ref = path_segment.name_ref()?;
124126
let name_ref_class = classify_name_ref(sema, &name_ref)?;
125127

126-
Some(name_ref_class.definition())
128+
Some(NameClass::Definition(name_ref_class.definition()))
127129
},
128130
ast::BindPat(it) => {
129131
let local = sema.to_def(&it)?;
130-
Some(Definition::Local(local))
132+
133+
if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) {
134+
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
135+
let field = Definition::Field(field);
136+
return Some(NameClass::FieldShorthand { local, field });
137+
}
138+
}
139+
140+
Some(NameClass::Definition(Definition::Local(local)))
131141
},
132142
ast::RecordFieldDef(it) => {
133143
let field: hir::Field = sema.to_def(&it)?;
134-
Some(Definition::Field(field))
144+
Some(NameClass::Definition(Definition::Field(field)))
135145
},
136146
ast::Module(it) => {
137147
let def = sema.to_def(&it)?;
138-
Some(Definition::ModuleDef(def.into()))
148+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
139149
},
140150
ast::StructDef(it) => {
141151
let def: hir::Struct = sema.to_def(&it)?;
142-
Some(Definition::ModuleDef(def.into()))
152+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
143153
},
144154
ast::UnionDef(it) => {
145155
let def: hir::Union = sema.to_def(&it)?;
146-
Some(Definition::ModuleDef(def.into()))
156+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
147157
},
148158
ast::EnumDef(it) => {
149159
let def: hir::Enum = sema.to_def(&it)?;
150-
Some(Definition::ModuleDef(def.into()))
160+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
151161
},
152162
ast::TraitDef(it) => {
153163
let def: hir::Trait = sema.to_def(&it)?;
154-
Some(Definition::ModuleDef(def.into()))
164+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
155165
},
156166
ast::StaticDef(it) => {
157167
let def: hir::Static = sema.to_def(&it)?;
158-
Some(Definition::ModuleDef(def.into()))
168+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
159169
},
160170
ast::EnumVariant(it) => {
161171
let def: hir::EnumVariant = sema.to_def(&it)?;
162-
Some(Definition::ModuleDef(def.into()))
172+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
163173
},
164174
ast::FnDef(it) => {
165175
let def: hir::Function = sema.to_def(&it)?;
166-
Some(Definition::ModuleDef(def.into()))
176+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
167177
},
168178
ast::ConstDef(it) => {
169179
let def: hir::Const = sema.to_def(&it)?;
170-
Some(Definition::ModuleDef(def.into()))
180+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
171181
},
172182
ast::TypeAliasDef(it) => {
173183
let def: hir::TypeAlias = sema.to_def(&it)?;
174-
Some(Definition::ModuleDef(def.into()))
184+
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
175185
},
176186
ast::MacroCall(it) => {
177187
let def = sema.to_def(&it)?;
178-
Some(Definition::Macro(def))
188+
Some(NameClass::Definition(Definition::Macro(def)))
179189
},
180190
ast::TypeParam(it) => {
181191
let def = sema.to_def(&it)?;
182-
Some(Definition::TypeParam(def))
192+
Some(NameClass::Definition(Definition::TypeParam(def)))
183193
},
184194
_ => None,
185195
}

0 commit comments

Comments
 (0)