//! `NameDefinition` keeps information about the element we want to search references for.
//! The element is represented by `NameKind`. It's located inside some `container` and
//! has a `visibility`, which defines a search scope.
//! Note that the reference search is possible for not all of the classified items.

// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).

use crate::RootDatabase;
use crate::documentation::{DocsRangeMap, Documentation, HasDocs};
use crate::famous_defs::FamousDefs;
use arrayvec::ArrayVec;
use either::Either;
use hir::{
    Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType,
    Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExternAssocItem,
    ExternCrateDecl, Field, Function, GenericDef, GenericParam, GenericSubstitution, HasContainer,
    HasVisibility, HirDisplay, Impl, InlineAsmOperand, ItemContainer, Label, Local, Macro, Module,
    ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, Struct, ToolModule, Trait,
    TupleField, TypeAlias, Variant, VariantDef, Visibility,
};
use span::Edition;
use stdx::{format_to, impl_from};
use syntax::{
    SyntaxKind, SyntaxNode, SyntaxToken, TextSize,
    ast::{self, AstNode},
    match_ast,
};

// FIXME: a more precise name would probably be `Symbol`?
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub enum Definition {
    Macro(Macro),
    Field(Field),
    TupleField(TupleField),
    Module(Module),
    Crate(Crate),
    Function(Function),
    Adt(Adt),
    Variant(Variant),
    Const(Const),
    Static(Static),
    Trait(Trait),
    TypeAlias(TypeAlias),
    SelfType(Impl),
    GenericParam(GenericParam),
    Local(Local),
    Label(Label),
    DeriveHelper(DeriveHelper),
    BuiltinType(BuiltinType),
    BuiltinLifetime(StaticLifetime),
    BuiltinAttr(BuiltinAttr),
    ToolModule(ToolModule),
    ExternCrateDecl(ExternCrateDecl),
    InlineAsmRegOrRegClass(()),
    InlineAsmOperand(InlineAsmOperand),
}

impl Definition {
    pub fn canonical_module_path(&self, db: &RootDatabase) -> Option<impl Iterator<Item = Module>> {
        self.module(db).map(|it| it.path_to_root(db).into_iter().rev())
    }

    pub fn krate(&self, db: &RootDatabase) -> Option<Crate> {
        Some(match self {
            Definition::Module(m) => m.krate(),
            &Definition::Crate(it) => it,
            _ => self.module(db)?.krate(),
        })
    }

    /// Returns the module this definition resides in.
    ///
    /// As such, for modules themselves this will return the parent module.
    pub fn module(&self, db: &RootDatabase) -> Option<Module> {
        let module = match self {
            Definition::Macro(it) => it.module(db),
            Definition::Module(it) => it.parent(db)?,
            Definition::Crate(_) => return None,
            Definition::Field(it) => it.parent_def(db).module(db),
            Definition::Function(it) => it.module(db),
            Definition::Adt(it) => it.module(db),
            Definition::Const(it) => it.module(db),
            Definition::Static(it) => it.module(db),
            Definition::Trait(it) => it.module(db),
            Definition::TypeAlias(it) => it.module(db),
            Definition::Variant(it) => it.module(db),
            Definition::SelfType(it) => it.module(db),
            Definition::Local(it) => it.module(db),
            Definition::GenericParam(it) => it.module(db),
            Definition::Label(it) => it.module(db),
            Definition::ExternCrateDecl(it) => it.module(db),
            Definition::DeriveHelper(it) => it.derive().module(db),
            Definition::InlineAsmOperand(it) => it.parent(db).module(db),
            Definition::ToolModule(t) => t.krate().root_module(),
            Definition::BuiltinAttr(_)
            | Definition::BuiltinType(_)
            | Definition::BuiltinLifetime(_)
            | Definition::TupleField(_)
            | Definition::InlineAsmRegOrRegClass(_) => return None,
        };
        Some(module)
    }

    pub fn enclosing_definition(&self, db: &RootDatabase) -> Option<Definition> {
        fn container_to_definition(container: ItemContainer) -> Option<Definition> {
            match container {
                ItemContainer::Trait(it) => Some(it.into()),
                ItemContainer::Impl(it) => Some(it.into()),
                ItemContainer::Module(it) => Some(it.into()),
                ItemContainer::ExternBlock(_) | ItemContainer::Crate(_) => None,
            }
        }
        match self {
            Definition::Macro(it) => Some(it.module(db).into()),
            Definition::Module(it) => it.parent(db).map(Definition::Module),
            Definition::Crate(_) => None,
            Definition::Field(it) => Some(it.parent_def(db).into()),
            Definition::Function(it) => container_to_definition(it.container(db)),
            Definition::Adt(it) => Some(it.module(db).into()),
            Definition::Const(it) => container_to_definition(it.container(db)),
            Definition::Static(it) => container_to_definition(it.container(db)),
            Definition::Trait(it) => container_to_definition(it.container(db)),
            Definition::TypeAlias(it) => container_to_definition(it.container(db)),
            Definition::Variant(it) => Some(Adt::Enum(it.parent_enum(db)).into()),
            Definition::SelfType(it) => Some(it.module(db).into()),
            Definition::Local(it) => it.parent(db).try_into().ok(),
            Definition::GenericParam(it) => Some(it.parent().into()),
            Definition::Label(it) => it.parent(db).try_into().ok(),
            Definition::ExternCrateDecl(it) => container_to_definition(it.container(db)),
            Definition::DeriveHelper(it) => Some(it.derive().module(db).into()),
            Definition::InlineAsmOperand(it) => it.parent(db).try_into().ok(),
            Definition::BuiltinAttr(_)
            | Definition::BuiltinType(_)
            | Definition::BuiltinLifetime(_)
            | Definition::TupleField(_)
            | Definition::ToolModule(_)
            | Definition::InlineAsmRegOrRegClass(_) => None,
        }
    }

    pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
        let vis = match self {
            Definition::Field(sf) => sf.visibility(db),
            Definition::Module(it) => it.visibility(db),
            Definition::Crate(_) => return None,
            Definition::Function(it) => it.visibility(db),
            Definition::Adt(it) => it.visibility(db),
            Definition::Const(it) => it.visibility(db),
            Definition::Static(it) => it.visibility(db),
            Definition::Trait(it) => it.visibility(db),
            Definition::TypeAlias(it) => it.visibility(db),
            Definition::Variant(it) => it.visibility(db),
            Definition::ExternCrateDecl(it) => it.visibility(db),
            Definition::Macro(it) => it.visibility(db),
            Definition::BuiltinType(_) | Definition::TupleField(_) => Visibility::Public,
            Definition::BuiltinAttr(_)
            | Definition::BuiltinLifetime(_)
            | Definition::ToolModule(_)
            | Definition::SelfType(_)
            | Definition::Local(_)
            | Definition::GenericParam(_)
            | Definition::Label(_)
            | Definition::DeriveHelper(_)
            | Definition::InlineAsmRegOrRegClass(_)
            | Definition::InlineAsmOperand(_) => return None,
        };
        Some(vis)
    }

    pub fn name(&self, db: &RootDatabase) -> Option<Name> {
        let name = match self {
            Definition::Macro(it) => it.name(db),
            Definition::Field(it) => it.name(db),
            Definition::Module(it) => it.name(db)?,
            Definition::Crate(it) => {
                Name::new_symbol_root(it.display_name(db)?.crate_name().symbol().clone())
            }
            Definition::Function(it) => it.name(db),
            Definition::Adt(it) => it.name(db),
            Definition::Variant(it) => it.name(db),
            Definition::Const(it) => it.name(db)?,
            Definition::Static(it) => it.name(db),
            Definition::Trait(it) => it.name(db),
            Definition::TypeAlias(it) => it.name(db),
            Definition::BuiltinType(it) => it.name(),
            Definition::TupleField(it) => it.name(),
            Definition::SelfType(_) => return None,
            Definition::Local(it) => it.name(db),
            Definition::GenericParam(it) => it.name(db),
            Definition::Label(it) => it.name(db),
            Definition::BuiltinLifetime(it) => it.name(),
            Definition::BuiltinAttr(_) => return None, // FIXME
            Definition::ToolModule(_) => return None,  // FIXME
            Definition::DeriveHelper(it) => it.name(db),
            Definition::ExternCrateDecl(it) => return it.alias_or_name(db),
            Definition::InlineAsmRegOrRegClass(_) => return None,
            Definition::InlineAsmOperand(op) => return op.name(db),
        };
        Some(name)
    }

    pub fn docs(
        &self,
        db: &RootDatabase,
        famous_defs: Option<&FamousDefs<'_, '_>>,
        display_target: DisplayTarget,
    ) -> Option<Documentation> {
        self.docs_with_rangemap(db, famous_defs, display_target).map(|(docs, _)| docs)
    }

    pub fn docs_with_rangemap(
        &self,
        db: &RootDatabase,
        famous_defs: Option<&FamousDefs<'_, '_>>,
        display_target: DisplayTarget,
    ) -> Option<(Documentation, Option<DocsRangeMap>)> {
        let docs = match self {
            Definition::Macro(it) => it.docs_with_rangemap(db),
            Definition::Field(it) => it.docs_with_rangemap(db),
            Definition::Module(it) => it.docs_with_rangemap(db),
            Definition::Crate(it) => it.docs_with_rangemap(db),
            Definition::Function(it) => it.docs_with_rangemap(db),
            Definition::Adt(it) => it.docs_with_rangemap(db),
            Definition::Variant(it) => it.docs_with_rangemap(db),
            Definition::Const(it) => it.docs_with_rangemap(db),
            Definition::Static(it) => it.docs_with_rangemap(db),
            Definition::Trait(it) => it.docs_with_rangemap(db),
            Definition::TypeAlias(it) => {
                it.docs_with_rangemap(db).or_else(|| {
                    // docs are missing, try to fall back to the docs of the aliased item.
                    let adt = it.ty(db).as_adt()?;
                    let (docs, range_map) = adt.docs_with_rangemap(db)?;
                    let header_docs = format!(
                        "*This is the documentation for* `{}`\n\n",
                        adt.display(db, display_target)
                    );
                    let offset = TextSize::new(header_docs.len() as u32);
                    let range_map = range_map.shift_docstring_line_range(offset);
                    let docs = header_docs + docs.as_str();
                    Some((Documentation::new(docs), range_map))
                })
            }
            Definition::BuiltinType(it) => {
                famous_defs.and_then(|fd| {
                    // std exposes prim_{} modules with docstrings on the root to document the builtins
                    let primitive_mod =
                        format!("prim_{}", it.name().display(fd.0.db, display_target.edition));
                    let doc_owner = find_std_module(fd, &primitive_mod, display_target.edition)?;
                    doc_owner.docs_with_rangemap(fd.0.db)
                })
            }
            Definition::BuiltinLifetime(StaticLifetime) => None,
            Definition::Local(_) => None,
            Definition::SelfType(impl_def) => {
                impl_def.self_ty(db).as_adt().map(|adt| adt.docs_with_rangemap(db))?
            }
            Definition::GenericParam(_) => None,
            Definition::Label(_) => None,
            Definition::ExternCrateDecl(it) => it.docs_with_rangemap(db),

            Definition::BuiltinAttr(it) => {
                let name = it.name(db);
                let AttributeTemplate { word, list, name_value_str } = it.template(db)?;
                let mut docs = "Valid forms are:".to_owned();
                if word {
                    format_to!(docs, "\n - #\\[{}]", name.display(db, display_target.edition));
                }
                if let Some(list) = list {
                    format_to!(
                        docs,
                        "\n - #\\[{}({})]",
                        name.display(db, display_target.edition),
                        list
                    );
                }
                if let Some(name_value_str) = name_value_str {
                    format_to!(
                        docs,
                        "\n - #\\[{} = {}]",
                        name.display(db, display_target.edition),
                        name_value_str
                    );
                }

                return Some((Documentation::new(docs.replace('*', "\\*")), None));
            }
            Definition::ToolModule(_) => None,
            Definition::DeriveHelper(_) => None,
            Definition::TupleField(_) => None,
            Definition::InlineAsmRegOrRegClass(_) | Definition::InlineAsmOperand(_) => None,
        };

        docs.or_else(|| {
            // docs are missing, for assoc items of trait impls try to fall back to the docs of the
            // original item of the trait
            let assoc = self.as_assoc_item(db)?;
            let trait_ = assoc.implemented_trait(db)?;
            let name = Some(assoc.name(db)?);
            let item = trait_.items(db).into_iter().find(|it| it.name(db) == name)?;
            item.docs_with_rangemap(db)
        })
        .map(|(docs, range_map)| (docs, Some(range_map)))
    }

    pub fn label(&self, db: &RootDatabase, display_target: DisplayTarget) -> String {
        match *self {
            Definition::Macro(it) => it.display(db, display_target).to_string(),
            Definition::Field(it) => it.display(db, display_target).to_string(),
            Definition::TupleField(it) => it.display(db, display_target).to_string(),
            Definition::Module(it) => it.display(db, display_target).to_string(),
            Definition::Crate(it) => it.display(db, display_target).to_string(),
            Definition::Function(it) => it.display(db, display_target).to_string(),
            Definition::Adt(it) => it.display(db, display_target).to_string(),
            Definition::Variant(it) => it.display(db, display_target).to_string(),
            Definition::Const(it) => it.display(db, display_target).to_string(),
            Definition::Static(it) => it.display(db, display_target).to_string(),
            Definition::Trait(it) => it.display(db, display_target).to_string(),
            Definition::TypeAlias(it) => it.display(db, display_target).to_string(),
            Definition::BuiltinType(it) => {
                it.name().display(db, display_target.edition).to_string()
            }
            Definition::BuiltinLifetime(it) => {
                it.name().display(db, display_target.edition).to_string()
            }
            Definition::Local(it) => {
                let ty = it.ty(db);
                let ty_display = ty.display_truncated(db, None, display_target);
                let is_mut = if it.is_mut(db) { "mut " } else { "" };
                if it.is_self(db) {
                    format!("{is_mut}self: {ty_display}")
                } else {
                    let name = it.name(db);
                    let let_kw = if it.is_param(db) { "" } else { "let " };
                    format!(
                        "{let_kw}{is_mut}{}: {ty_display}",
                        name.display(db, display_target.edition)
                    )
                }
            }
            Definition::SelfType(impl_def) => {
                let self_ty = &impl_def.self_ty(db);
                match self_ty.as_adt() {
                    Some(it) => it.display(db, display_target).to_string(),
                    None => self_ty.display(db, display_target).to_string(),
                }
            }
            Definition::GenericParam(it) => it.display(db, display_target).to_string(),
            Definition::Label(it) => it.name(db).display(db, display_target.edition).to_string(),
            Definition::ExternCrateDecl(it) => it.display(db, display_target).to_string(),
            Definition::BuiltinAttr(it) => {
                format!("#[{}]", it.name(db).display(db, display_target.edition))
            }
            Definition::ToolModule(it) => {
                it.name(db).display(db, display_target.edition).to_string()
            }
            Definition::DeriveHelper(it) => {
                format!("derive_helper {}", it.name(db).display(db, display_target.edition))
            }
            // FIXME
            Definition::InlineAsmRegOrRegClass(_) => "inline_asm_reg_or_reg_class".to_owned(),
            Definition::InlineAsmOperand(_) => "inline_asm_reg_operand".to_owned(),
        }
    }
}

fn find_std_module(
    famous_defs: &FamousDefs<'_, '_>,
    name: &str,
    edition: Edition,
) -> Option<hir::Module> {
    let db = famous_defs.0.db;
    let std_crate = famous_defs.std()?;
    let std_root_module = std_crate.root_module();
    std_root_module.children(db).find(|module| {
        module.name(db).is_some_and(|module| module.display(db, edition).to_string() == name)
    })
}

// FIXME: IdentClass as a name no longer fits
#[derive(Debug)]
pub enum IdentClass<'db> {
    NameClass(NameClass<'db>),
    NameRefClass(NameRefClass<'db>),
    Operator(OperatorClass),
}

impl<'db> IdentClass<'db> {
    pub fn classify_node(
        sema: &Semantics<'db, RootDatabase>,
        node: &SyntaxNode,
    ) -> Option<IdentClass<'db>> {
        match_ast! {
            match node {
                ast::Name(name) => NameClass::classify(sema, &name).map(IdentClass::NameClass),
                ast::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref).map(IdentClass::NameRefClass),
                ast::Lifetime(lifetime) => {
                    NameClass::classify_lifetime(sema, &lifetime)
                        .map(IdentClass::NameClass)
                        .or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
                },
                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::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::PrefixExpr(prefix_expr) => OperatorClass::classify_prefix(sema, &prefix_expr).map(IdentClass::Operator),
                ast::TryExpr(try_expr) => OperatorClass::classify_try(sema, &try_expr).map(IdentClass::Operator),
                _ => None,
            }
        }
    }

    pub fn classify_token(
        sema: &Semantics<'db, RootDatabase>,
        token: &SyntaxToken,
    ) -> Option<IdentClass<'db>> {
        let parent = token.parent()?;
        Self::classify_node(sema, &parent)
    }

    pub fn classify_lifetime(
        sema: &Semantics<'db, RootDatabase>,
        lifetime: &ast::Lifetime,
    ) -> Option<IdentClass<'db>> {
        NameRefClass::classify_lifetime(sema, lifetime)
            .map(IdentClass::NameRefClass)
            .or_else(|| NameClass::classify_lifetime(sema, lifetime).map(IdentClass::NameClass))
    }

    pub fn definitions(self) -> ArrayVec<(Definition, Option<GenericSubstitution<'db>>), 2> {
        let mut res = ArrayVec::new();
        match self {
            IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => {
                res.push((it, None))
            }
            IdentClass::NameClass(NameClass::PatFieldShorthand {
                local_def,
                field_ref,
                adt_subst,
            }) => {
                res.push((Definition::Local(local_def), None));
                res.push((Definition::Field(field_ref), Some(adt_subst)));
            }
            IdentClass::NameRefClass(NameRefClass::Definition(it, subst)) => res.push((it, subst)),
            IdentClass::NameRefClass(NameRefClass::FieldShorthand {
                local_ref,
                field_ref,
                adt_subst,
            }) => {
                res.push((Definition::Local(local_ref), None));
                res.push((Definition::Field(field_ref), Some(adt_subst)));
            }
            IdentClass::NameRefClass(NameRefClass::ExternCrateShorthand { decl, krate }) => {
                res.push((Definition::ExternCrateDecl(decl), None));
                res.push((Definition::Crate(krate), None));
            }
            IdentClass::Operator(
                OperatorClass::Await(func)
                | OperatorClass::Prefix(func)
                | OperatorClass::Bin(func)
                | OperatorClass::Index(func)
                | OperatorClass::Try(func),
            ) => res.push((Definition::Function(func), None)),
            IdentClass::Operator(OperatorClass::Range(struct0)) => {
                res.push((Definition::Adt(Adt::Struct(struct0)), None))
            }
        }
        res
    }

    pub fn definitions_no_ops(self) -> ArrayVec<Definition, 2> {
        let mut res = ArrayVec::new();
        match self {
            IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => {
                res.push(it)
            }
            IdentClass::NameClass(NameClass::PatFieldShorthand {
                local_def,
                field_ref,
                adt_subst: _,
            }) => {
                res.push(Definition::Local(local_def));
                res.push(Definition::Field(field_ref));
            }
            IdentClass::NameRefClass(NameRefClass::Definition(it, _)) => res.push(it),
            IdentClass::NameRefClass(NameRefClass::FieldShorthand {
                local_ref,
                field_ref,
                adt_subst: _,
            }) => {
                res.push(Definition::Local(local_ref));
                res.push(Definition::Field(field_ref));
            }
            IdentClass::NameRefClass(NameRefClass::ExternCrateShorthand { decl, krate }) => {
                res.push(Definition::ExternCrateDecl(decl));
                res.push(Definition::Crate(krate));
            }
            IdentClass::Operator(_) => (),
        }
        res
    }
}

/// On a first blush, a single `ast::Name` defines a single definition at some
/// scope. That is, that, by just looking at the syntactical category, we can
/// unambiguously define the semantic category.
///
/// Sadly, that's not 100% true, there are special cases. To make sure that
/// callers handle all the special cases correctly via exhaustive matching, we
/// add a [`NameClass`] enum which lists all of them!
///
/// A model special case is `None` constant in pattern.
#[derive(Debug)]
pub enum NameClass<'db> {
    Definition(Definition),
    /// `None` in `if let None = Some(82) {}`.
    /// Syntactically, it is a name, but semantically it is a reference.
    ConstReference(Definition),
    /// `field` in `if let Foo { field } = foo`. Here, `ast::Name` both introduces
    /// a definition into a local scope, and refers to an existing definition.
    PatFieldShorthand {
        local_def: Local,
        field_ref: Field,
        adt_subst: GenericSubstitution<'db>,
    },
}

impl<'db> NameClass<'db> {
    /// `Definition` defined by this name.
    pub fn defined(self) -> Option<Definition> {
        let res = match self {
            NameClass::Definition(it) => it,
            NameClass::ConstReference(_) => return None,
            NameClass::PatFieldShorthand { local_def, field_ref: _, adt_subst: _ } => {
                Definition::Local(local_def)
            }
        };
        Some(res)
    }

    pub fn classify(
        sema: &Semantics<'db, RootDatabase>,
        name: &ast::Name,
    ) -> Option<NameClass<'db>> {
        let _p = tracing::info_span!("NameClass::classify").entered();

        let parent = name.syntax().parent()?;
        let definition = match_ast! {
            match parent {
                ast::Item(it) => classify_item(sema, it)?,
                ast::IdentPat(it) => return classify_ident_pat(sema, it),
                ast::Rename(it) => classify_rename(sema, it)?,
                ast::SelfParam(it) => Definition::Local(sema.to_def(&it)?),
                ast::RecordField(it) => Definition::Field(sema.to_def(&it)?),
                ast::Variant(it) => Definition::Variant(sema.to_def(&it)?),
                ast::TypeParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()),
                ast::ConstParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()),
                ast::AsmOperandNamed(it) => Definition::InlineAsmOperand(sema.to_def(&it)?),
                _ => return None,
            }
        };
        return Some(NameClass::Definition(definition));

        fn classify_item(
            sema: &Semantics<'_, RootDatabase>,
            item: ast::Item,
        ) -> Option<Definition> {
            let definition = match item {
                ast::Item::MacroRules(it) => {
                    Definition::Macro(sema.to_def(&ast::Macro::MacroRules(it))?)
                }
                ast::Item::MacroDef(it) => {
                    Definition::Macro(sema.to_def(&ast::Macro::MacroDef(it))?)
                }
                ast::Item::Const(it) => Definition::Const(sema.to_def(&it)?),
                ast::Item::Fn(it) => {
                    let def = sema.to_def(&it)?;
                    def.as_proc_macro(sema.db)
                        .map(Definition::Macro)
                        .unwrap_or(Definition::Function(def))
                }
                ast::Item::Module(it) => Definition::Module(sema.to_def(&it)?),
                ast::Item::Static(it) => Definition::Static(sema.to_def(&it)?),
                ast::Item::Trait(it) => Definition::Trait(sema.to_def(&it)?),
                ast::Item::TypeAlias(it) => Definition::TypeAlias(sema.to_def(&it)?),
                ast::Item::Enum(it) => Definition::Adt(hir::Adt::Enum(sema.to_def(&it)?)),
                ast::Item::Struct(it) => Definition::Adt(hir::Adt::Struct(sema.to_def(&it)?)),
                ast::Item::Union(it) => Definition::Adt(hir::Adt::Union(sema.to_def(&it)?)),
                ast::Item::ExternCrate(it) => Definition::ExternCrateDecl(sema.to_def(&it)?),
                _ => return None,
            };
            Some(definition)
        }

        fn classify_ident_pat<'db>(
            sema: &Semantics<'db, RootDatabase>,
            ident_pat: ast::IdentPat,
        ) -> Option<NameClass<'db>> {
            if let Some(def) = sema.resolve_bind_pat_to_const(&ident_pat) {
                return Some(NameClass::ConstReference(Definition::from(def)));
            }

            let local = sema.to_def(&ident_pat)?;
            let pat_parent = ident_pat.syntax().parent();
            if let Some(record_pat_field) = pat_parent.and_then(ast::RecordPatField::cast)
                && record_pat_field.name_ref().is_none()
                && let Some((field, _, adt_subst)) =
                    sema.resolve_record_pat_field_with_subst(&record_pat_field)
            {
                return Some(NameClass::PatFieldShorthand {
                    local_def: local,
                    field_ref: field,
                    adt_subst,
                });
            }
            Some(NameClass::Definition(Definition::Local(local)))
        }

        fn classify_rename(
            sema: &Semantics<'_, RootDatabase>,
            rename: ast::Rename,
        ) -> Option<Definition> {
            if let Some(use_tree) = rename.syntax().parent().and_then(ast::UseTree::cast) {
                let path = use_tree.path()?;
                sema.resolve_path(&path).map(Definition::from)
            } else {
                sema.to_def(&rename.syntax().parent().and_then(ast::ExternCrate::cast)?)
                    .map(Definition::ExternCrateDecl)
            }
        }
    }

    pub fn classify_lifetime(
        sema: &Semantics<'db, RootDatabase>,
        lifetime: &ast::Lifetime,
    ) -> Option<NameClass<'db>> {
        let _p = tracing::info_span!("NameClass::classify_lifetime", ?lifetime).entered();
        let parent = lifetime.syntax().parent()?;

        if let Some(it) = ast::LifetimeParam::cast(parent.clone()) {
            sema.to_def(&it).map(Into::into).map(Definition::GenericParam)
        } else if let Some(it) = ast::Label::cast(parent) {
            sema.to_def(&it).map(Definition::Label)
        } else {
            None
        }
        .map(NameClass::Definition)
    }
}

#[derive(Debug)]
pub enum OperatorClass {
    Range(Struct),
    Await(Function),
    Prefix(Function),
    Index(Function),
    Try(Function),
    Bin(Function),
}

impl OperatorClass {
    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>,
        range_expr: &ast::RangeExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_range_expr(range_expr).map(OperatorClass::Range)
    }

    pub fn classify_await(
        sema: &Semantics<'_, RootDatabase>,
        await_expr: &ast::AwaitExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_await_to_poll(await_expr).map(OperatorClass::Await)
    }

    pub fn classify_prefix(
        sema: &Semantics<'_, RootDatabase>,
        prefix_expr: &ast::PrefixExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_prefix_expr(prefix_expr).map(OperatorClass::Prefix)
    }

    pub fn classify_try(
        sema: &Semantics<'_, RootDatabase>,
        try_expr: &ast::TryExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_try_expr(try_expr).map(OperatorClass::Try)
    }

    pub fn classify_index(
        sema: &Semantics<'_, RootDatabase>,
        index_expr: &ast::IndexExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_index_expr(index_expr).map(OperatorClass::Index)
    }

    pub fn classify_bin(
        sema: &Semantics<'_, RootDatabase>,
        bin_expr: &ast::BinExpr,
    ) -> Option<OperatorClass> {
        sema.resolve_bin_expr(bin_expr).map(OperatorClass::Bin)
    }
}

/// This is similar to [`NameClass`], but works for [`ast::NameRef`] rather than
/// for [`ast::Name`]. Similarly, what looks like a reference in syntax is a
/// reference most of the time, but there are a couple of annoying exceptions.
///
/// A model special case is field shorthand syntax, which uses a single
/// reference to point to two different defs.
#[derive(Debug)]
pub enum NameRefClass<'db> {
    Definition(Definition, Option<GenericSubstitution<'db>>),
    FieldShorthand {
        local_ref: Local,
        field_ref: Field,
        adt_subst: GenericSubstitution<'db>,
    },
    /// The specific situation where we have an extern crate decl without a rename
    /// Here we have both a declaration and a reference.
    /// ```rs
    /// extern crate foo;
    /// ```
    ExternCrateShorthand {
        decl: ExternCrateDecl,
        krate: Crate,
    },
}

impl<'db> NameRefClass<'db> {
    // Note: we don't have unit-tests for this rather important function.
    // It is primarily exercised via goto definition tests in `ide`.
    pub fn classify(
        sema: &Semantics<'db, RootDatabase>,
        name_ref: &ast::NameRef,
    ) -> Option<NameRefClass<'db>> {
        let _p = tracing::info_span!("NameRefClass::classify", ?name_ref).entered();

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

        if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref)
            && let Some((field, local, _, adt_subst)) =
                sema.resolve_record_field_with_substitution(&record_field)
        {
            let res = match local {
                None => NameRefClass::Definition(Definition::Field(field), Some(adt_subst)),
                Some(local) => {
                    NameRefClass::FieldShorthand { field_ref: field, local_ref: local, adt_subst }
                }
            };
            return Some(res);
        }

        if let Some(path) = ast::PathSegment::cast(parent.clone()).map(|it| it.parent_path()) {
            if path.parent_path().is_none()
                && let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast)
            {
                // Only use this to resolve to macro calls for last segments as qualifiers resolve
                // to modules below.
                if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
                    return Some(NameRefClass::Definition(Definition::Macro(macro_def), None));
                }
            }
            return sema
                .resolve_path_with_subst(&path)
                .map(|(res, subst)| NameRefClass::Definition(res.into(), subst));
        }

        match_ast! {
            match parent {
                ast::MethodCallExpr(method_call) => {
                    sema.resolve_method_call_fallback(&method_call)
                        .map(|(def, subst)| {
                            match def {
                                Either::Left(def) => NameRefClass::Definition(def.into(), subst),
                                Either::Right(def) => NameRefClass::Definition(def.into(), subst),
                            }
                        })
                },
                ast::FieldExpr(field_expr) => {
                    sema.resolve_field_fallback(&field_expr)
                        .map(|(def, subst)| {
                            match def {
                                Either::Left(Either::Left(def)) => NameRefClass::Definition(def.into(), subst),
                                Either::Left(Either::Right(def)) => NameRefClass::Definition(Definition::TupleField(def), subst),
                                Either::Right(def) => NameRefClass::Definition(def.into(), subst),
                            }
                        })
                },
                ast::RecordPatField(record_pat_field) => {
                    sema.resolve_record_pat_field_with_subst(&record_pat_field)
                        .map(|(field, _, subst)| NameRefClass::Definition(Definition::Field(field), Some(subst)))
                },
                ast::RecordExprField(record_expr_field) => {
                    sema.resolve_record_field_with_substitution(&record_expr_field)
                        .map(|(field, _, _, subst)| NameRefClass::Definition(Definition::Field(field), Some(subst)))
                },
                ast::AssocTypeArg(_) => {
                    // `Trait<Assoc = Ty>`
                    //        ^^^^^
                    let containing_path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
                    let resolved = sema.resolve_path(&containing_path)?;
                    if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved
                        && let Some(ty) = tr
                            .items_with_supertraits(sema.db)
                            .iter()
                            .filter_map(|&assoc| match assoc {
                                hir::AssocItem::TypeAlias(it) => Some(it),
                                _ => None,
                            })
                            .find(|alias| alias.name(sema.db).as_str() == name_ref.text().trim_start_matches("r#"))
                        {
                            // No substitution, this can only occur in type position.
                            return Some(NameRefClass::Definition(Definition::TypeAlias(ty), None));
                        }
                    None
                },
                ast::UseBoundGenericArgs(_) => {
                    // No substitution, this can only occur in type position.
                    sema.resolve_use_type_arg(name_ref)
                        .map(GenericParam::TypeParam)
                        .map(Definition::GenericParam)
                        .map(|it| NameRefClass::Definition(it, None))
                },
                ast::ExternCrate(extern_crate_ast) => {
                    let extern_crate = sema.to_def(&extern_crate_ast)?;
                    let krate = extern_crate.resolved_crate(sema.db)?;
                    Some(if extern_crate_ast.rename().is_some() {
                        NameRefClass::Definition(Definition::Crate(krate), None)
                    } else {
                        NameRefClass::ExternCrateShorthand { krate, decl: extern_crate }
                    })
                },
                ast::AsmRegSpec(_) => {
                    Some(NameRefClass::Definition(Definition::InlineAsmRegOrRegClass(()), None))
                },
                ast::OffsetOfExpr(_) => {
                    let (def, subst) = sema.resolve_offset_of_field(name_ref)?;
                    let def = match def {
                        Either::Left(variant) => Definition::Variant(variant),
                        Either::Right(field) => Definition::Field(field),
                    };
                    Some(NameRefClass::Definition(def, Some(subst)))
                },
                _ => None
            }
        }
    }

    pub fn classify_lifetime(
        sema: &Semantics<'db, RootDatabase>,
        lifetime: &ast::Lifetime,
    ) -> Option<NameRefClass<'db>> {
        let _p = tracing::info_span!("NameRefClass::classify_lifetime", ?lifetime).entered();
        if lifetime.text() == "'static" {
            return Some(NameRefClass::Definition(
                Definition::BuiltinLifetime(StaticLifetime),
                None,
            ));
        }
        let parent = lifetime.syntax().parent()?;
        match parent.kind() {
            SyntaxKind::BREAK_EXPR | SyntaxKind::CONTINUE_EXPR => sema
                .resolve_label(lifetime)
                .map(Definition::Label)
                .map(|it| NameRefClass::Definition(it, None)),
            SyntaxKind::LIFETIME_ARG
            | SyntaxKind::USE_BOUND_GENERIC_ARGS
            | SyntaxKind::SELF_PARAM
            | SyntaxKind::TYPE_BOUND
            | SyntaxKind::WHERE_PRED
            | SyntaxKind::REF_TYPE => sema
                .resolve_lifetime_param(lifetime)
                .map(GenericParam::LifetimeParam)
                .map(Definition::GenericParam)
                .map(|it| NameRefClass::Definition(it, None)),
            _ => None,
        }
    }
}

impl_from!(
    Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
    GenericParam, Label, Macro, ExternCrateDecl
    for Definition
);

impl From<Impl> for Definition {
    fn from(impl_: Impl) -> Self {
        Definition::SelfType(impl_)
    }
}

impl From<InlineAsmOperand> for Definition {
    fn from(value: InlineAsmOperand) -> Self {
        Definition::InlineAsmOperand(value)
    }
}

impl From<Either<PathResolution, InlineAsmOperand>> for Definition {
    fn from(value: Either<PathResolution, InlineAsmOperand>) -> Self {
        value.either(Definition::from, Definition::from)
    }
}

impl AsAssocItem for Definition {
    fn as_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option<AssocItem> {
        match self {
            Definition::Function(it) => it.as_assoc_item(db),
            Definition::Const(it) => it.as_assoc_item(db),
            Definition::TypeAlias(it) => it.as_assoc_item(db),
            _ => None,
        }
    }
}

impl AsExternAssocItem for Definition {
    fn as_extern_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option<ExternAssocItem> {
        match self {
            Definition::Function(it) => it.as_extern_assoc_item(db),
            Definition::Static(it) => it.as_extern_assoc_item(db),
            Definition::TypeAlias(it) => it.as_extern_assoc_item(db),
            _ => None,
        }
    }
}

impl From<AssocItem> for Definition {
    fn from(assoc_item: AssocItem) -> Self {
        match assoc_item {
            AssocItem::Function(it) => Definition::Function(it),
            AssocItem::Const(it) => Definition::Const(it),
            AssocItem::TypeAlias(it) => Definition::TypeAlias(it),
        }
    }
}

impl From<PathResolution> for Definition {
    fn from(path_resolution: PathResolution) -> Self {
        match path_resolution {
            PathResolution::Def(def) => def.into(),
            PathResolution::Local(local) => Definition::Local(local),
            PathResolution::TypeParam(par) => Definition::GenericParam(par.into()),
            PathResolution::ConstParam(par) => Definition::GenericParam(par.into()),
            PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
            PathResolution::BuiltinAttr(attr) => Definition::BuiltinAttr(attr),
            PathResolution::ToolModule(tool) => Definition::ToolModule(tool),
            PathResolution::DeriveHelper(helper) => Definition::DeriveHelper(helper),
        }
    }
}

impl From<ModuleDef> for Definition {
    fn from(def: ModuleDef) -> Self {
        match def {
            ModuleDef::Module(it) => Definition::Module(it),
            ModuleDef::Function(it) => Definition::Function(it),
            ModuleDef::Adt(it) => Definition::Adt(it),
            ModuleDef::Variant(it) => Definition::Variant(it),
            ModuleDef::Const(it) => Definition::Const(it),
            ModuleDef::Static(it) => Definition::Static(it),
            ModuleDef::Trait(it) => Definition::Trait(it),
            ModuleDef::TypeAlias(it) => Definition::TypeAlias(it),
            ModuleDef::Macro(it) => Definition::Macro(it),
            ModuleDef::BuiltinType(it) => Definition::BuiltinType(it),
        }
    }
}

impl From<DocLinkDef> for Definition {
    fn from(def: DocLinkDef) -> Self {
        match def {
            DocLinkDef::ModuleDef(it) => it.into(),
            DocLinkDef::Field(it) => it.into(),
            DocLinkDef::SelfType(it) => it.into(),
        }
    }
}

impl From<VariantDef> for Definition {
    fn from(def: VariantDef) -> Self {
        ModuleDef::from(def).into()
    }
}

impl TryFrom<DefWithBody> for Definition {
    type Error = ();
    fn try_from(def: DefWithBody) -> Result<Self, Self::Error> {
        match def {
            DefWithBody::Function(it) => Ok(it.into()),
            DefWithBody::Static(it) => Ok(it.into()),
            DefWithBody::Const(it) => Ok(it.into()),
            DefWithBody::Variant(it) => Ok(it.into()),
        }
    }
}

impl From<GenericDef> for Definition {
    fn from(def: GenericDef) -> Self {
        match def {
            GenericDef::Function(it) => it.into(),
            GenericDef::Adt(it) => it.into(),
            GenericDef::Trait(it) => it.into(),
            GenericDef::TypeAlias(it) => it.into(),
            GenericDef::Impl(it) => it.into(),
            GenericDef::Const(it) => it.into(),
            GenericDef::Static(it) => it.into(),
        }
    }
}

impl TryFrom<Definition> for GenericDef {
    type Error = ();
    fn try_from(def: Definition) -> Result<Self, Self::Error> {
        match def {
            Definition::Function(it) => Ok(it.into()),
            Definition::Adt(it) => Ok(it.into()),
            Definition::Trait(it) => Ok(it.into()),
            Definition::TypeAlias(it) => Ok(it.into()),
            Definition::SelfType(it) => Ok(it.into()),
            Definition::Const(it) => Ok(it.into()),
            _ => Err(()),
        }
    }
}
