pub fn classify_name_ref(
    sema: &Semantics<RootDatabase>,
    name_ref: &ast::NameRef,
) -> Option<NameRefClass> {
    let _p = profile("classify_name_ref");

    let parent = name_ref.syntax().parent()?;

    if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
        if let Some(func) = sema.resolve_method_call(&method_call) {
            return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
        }
    }

    if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
        if let Some(field) = sema.resolve_field(&field_expr) {
            return Some(NameRefClass::Definition(Definition::Field(field)));
        }
    }

    if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
        if let Some((field, local)) = sema.resolve_record_field(&record_field) {
            let field = Definition::Field(field);
            let res = match local {
                None => NameRefClass::Definition(field),
                Some(local) => NameRefClass::FieldShorthand { field, local },
            };
            return Some(res);
        }
    }

    if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
        if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
            let field = Definition::Field(field);
            return Some(NameRefClass::Definition(field));
        }
    }

    if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
        if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
            return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
        }
    }

    let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
    let resolved = sema.resolve_path(&path)?;
    let res = match resolved {
        PathResolution::Def(def) => Definition::ModuleDef(def),
        PathResolution::AssocItem(item) => {
            let def = match item {
                hir::AssocItem::Function(it) => it.into(),
                hir::AssocItem::Const(it) => it.into(),
                hir::AssocItem::TypeAlias(it) => it.into(),
            };
            Definition::ModuleDef(def)
        }
        PathResolution::Local(local) => Definition::Local(local),
        PathResolution::TypeParam(par) => Definition::TypeParam(par),
        PathResolution::Macro(def) => Definition::Macro(def),
        PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
    };
    Some(NameRefClass::Definition(res))
}
// Note: we don't have unit-tests for this rather important function.
// It is primarily exercised via goto definition tests in `ra_ide`.
we don't have unit-tests for this rather important function.
It is primarily exercised via goto definition tests in `ra_ide`.
we don ' t have unit - tests for this rather important function . It is primarily exercised via goto definition tests in ` ra_ide ` .
pub fn classify_name_ref(
    sema: &Semantics<RootDatabase>,
    name_ref: &ast::NameRef,
) -> Option<NameRefClass> {
    let _p = profile("classify_name_ref");
    let parent = name_ref.syntax().parent()?;
    if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
        if let Some(func) = sema.resolve_method_call(&method_call) {
            return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
        }
    }
    if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
        if let Some(field) = sema.resolve_field(&field_expr) {
            return Some(NameRefClass::Definition(Definition::Field(field)));
        }
    }
    if let Some(record_field) = ast::RecordField::for_field_name(name_ref) {
        if let Some((field, local)) = sema.resolve_record_field(&record_field) {
            let field = Definition::Field(field);
            let res = match local {
                None => NameRefClass::Definition(field),
                Some(local) => NameRefClass::FieldShorthand { field, local },
            };
            return Some(res);
        }
    }
    if let Some(record_field_pat) = ast::RecordFieldPat::cast(parent.clone()) {
        if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) {
            let field = Definition::Field(field);
            return Some(NameRefClass::Definition(field));
        }
    }
    if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
        if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
            return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
        }
    }
    let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
    let resolved = sema.resolve_path(&path)?;
    let res = match resolved {
        PathResolution::Def(def) => Definition::ModuleDef(def),
        PathResolution::AssocItem(item) => {
            let def = match item {
                hir::AssocItem::Function(it) => it.into(),
                hir::AssocItem::Const(it) => it.into(),
                hir::AssocItem::TypeAlias(it) => it.into(),
            };
            Definition::ModuleDef(def)
        }
        PathResolution::Local(local) => Definition::Local(local),
        PathResolution::TypeParam(par) => Definition::TypeParam(par),
        PathResolution::Macro(def) => Definition::Macro(def),
        PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
    };
    Some(NameRefClass::Definition(res))
}
pub fn classify_name_ref ( sema : & Semantics < RootDatabase > , name_ref : & ast :: NameRef , ) -> Option < NameRefClass > { let _p = profile ( " " ) ; let parent = name_ref . syntax ( ) . parent ( ) ? ; if let Some ( method_call ) = ast :: MethodCallExpr :: cast ( parent . clone ( ) ) { if let Some ( func ) = sema . resolve_method_call ( & method_call ) { return Some ( NameRefClass :: Definition ( Definition :: ModuleDef ( func . into ( ) ) ) ) ; } } if let Some ( field_expr ) = ast :: FieldExpr :: cast ( parent . clone ( ) ) { if let Some ( field ) = sema . resolve_field ( & field_expr ) { return Some ( NameRefClass :: Definition ( Definition :: Field ( field ) ) ) ; } } if let Some ( record_field ) = ast :: RecordField :: for_field_name ( name_ref ) { if let Some ( ( field , local ) ) = sema . resolve_record_field ( & record_field ) { let field = Definition :: Field ( field ) ; let res = match local { None => NameRefClass :: Definition ( field ) , Some ( local ) => NameRefClass :: FieldShorthand { field , local } , } ; return Some ( res ) ; } } if let Some ( record_field_pat ) = ast :: RecordFieldPat :: cast ( parent . clone ( ) ) { if let Some ( field ) = sema . resolve_record_field_pat ( & record_field_pat ) { let field = Definition :: Field ( field ) ; return Some ( NameRefClass :: Definition ( field ) ) ; } } if let Some ( macro_call ) = parent . ancestors ( ) . find_map ( ast :: MacroCall :: cast ) { if let Some ( macro_def ) = sema . resolve_macro_call ( & macro_call ) { return Some ( NameRefClass :: Definition ( Definition :: Macro ( macro_def ) ) ) ; } } let path = name_ref . syntax ( ) . ancestors ( ) . find_map ( ast :: Path :: cast ) ? ; let resolved = sema . resolve_path ( & path ) ? ; let res = match resolved { PathResolution :: Def ( def ) => Definition :: ModuleDef ( def ) , PathResolution :: AssocItem ( item ) => { let def = match item { hir :: AssocItem :: Function ( it ) => it . into ( ) , hir :: AssocItem :: Const ( it ) => it . into ( ) , hir :: AssocItem :: TypeAlias ( it ) => it . into ( ) , } ; Definition :: ModuleDef ( def ) } PathResolution :: Local ( local ) => Definition :: Local ( local ) , PathResolution :: TypeParam ( par ) => Definition :: TypeParam ( par ) , PathResolution :: Macro ( def ) => Definition :: Macro ( def ) , PathResolution :: SelfType ( impl_def ) => Definition :: SelfType ( impl_def ) , } ; Some ( NameRefClass :: Definition ( res ) ) }
Note: we don't have unit-tests for this rather important function.
Note : we don ' t have unit - tests for this rather important function .
sema
&Semantics<RootDatabase>
name_ref
&ast::NameRef
sema
&Semantics<RootDatabase>
name_ref
&ast::NameRef