Skip to content

Commit

Permalink
Add FieldShorthand variant to NameClass
Browse files Browse the repository at this point in the history
  • Loading branch information
unexge committed Jun 8, 2020
1 parent 73684a4 commit c5d5d21
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 27 deletions.
2 changes: 1 addition & 1 deletion crates/ra_ide/src/goto_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(crate) fn goto_definition(
reference_definition(&sema, &name_ref).to_vec()
},
ast::Name(name) => {
let def = classify_name(&sema, &name)?.definition();
let def = classify_name(&sema, &name)?.into_definition()?;
let nav = def.try_to_nav(sema.db)?;
vec![nav]
},
Expand Down
1 change: 1 addition & 0 deletions crates/ra_ide/src/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ fn highlight_element(
highlight_name(db, def) | HighlightModifier::Definition
}
Some(NameClass::ConstReference(def)) => highlight_name(db, def),
Some(NameClass::FieldShorthand { .. }) => HighlightTag::Field.into(),
None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
}
}
Expand Down
56 changes: 30 additions & 26 deletions crates/ra_ide_db/src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,38 +82,40 @@ pub enum NameClass {
Definition(Definition),
/// `None` in `if let None = Some(82) {}`
ConstReference(Definition),
FieldShorthand {
local: Local,
field: Definition,
},
}

impl NameClass {
pub fn into_definition(self) -> Option<Definition> {
match self {
NameClass::Definition(it) => Some(it),
NameClass::ConstReference(_) => None,
NameClass::FieldShorthand { local: _, field } => Some(field),
}
}

pub fn definition(self) -> Definition {
match self {
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
NameClass::FieldShorthand { local, field: _ } => Definition::Local(local),
}
}
}

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

if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
let parent = name.syntax().parent()?;

if let Some(bind_pat) = ast::BindPat::cast(parent.clone()) {
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
}
}

classify_name_inner(sema, name).map(NameClass::Definition)
}

fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Definition> {
let parent = name.syntax().parent()?;

match_ast! {
match parent {
ast::Alias(it) => {
Expand All @@ -123,69 +125,71 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
let name_ref = path_segment.name_ref()?;
let name_ref_class = classify_name_ref(sema, &name_ref)?;

Some(name_ref_class.definition())
Some(NameClass::Definition(name_ref_class.definition()))
},
ast::BindPat(it) => {
let local = sema.to_def(&it)?;

if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordFieldPat::cast) {
return Some(Definition::Field(
sema.resolve_record_field_pat(&record_field_pat)?
));
if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
let field = Definition::Field(field);
return Some(NameClass::FieldShorthand { local, field });
}
}

let local = sema.to_def(&it)?;
Some(Definition::Local(local))
Some(NameClass::Definition(Definition::Local(local)))
},
ast::RecordFieldDef(it) => {
let field: hir::Field = sema.to_def(&it)?;
Some(Definition::Field(field))
Some(NameClass::Definition(Definition::Field(field)))
},
ast::Module(it) => {
let def = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::StructDef(it) => {
let def: hir::Struct = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::UnionDef(it) => {
let def: hir::Union = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::EnumDef(it) => {
let def: hir::Enum = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::TraitDef(it) => {
let def: hir::Trait = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::StaticDef(it) => {
let def: hir::Static = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::EnumVariant(it) => {
let def: hir::EnumVariant = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::FnDef(it) => {
let def: hir::Function = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::ConstDef(it) => {
let def: hir::Const = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::TypeAliasDef(it) => {
let def: hir::TypeAlias = sema.to_def(&it)?;
Some(Definition::ModuleDef(def.into()))
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
},
ast::MacroCall(it) => {
let def = sema.to_def(&it)?;
Some(Definition::Macro(def))
Some(NameClass::Definition(Definition::Macro(def)))
},
ast::TypeParam(it) => {
let def = sema.to_def(&it)?;
Some(Definition::TypeParam(def))
Some(NameClass::Definition(Definition::TypeParam(def)))
},
_ => None,
}
Expand Down

0 comments on commit c5d5d21

Please sign in to comment.