//! See [`CompletionContext`] structure.

mod analysis;
#[cfg(test)]
mod tests;

use std::{iter, ops::ControlFlow};

use base_db::RootQueryDb as _;
use hir::{
    DisplayTarget, HasAttrs, InFile, Local, ModuleDef, ModuleSource, Name, PathResolution,
    ScopeDef, Semantics, SemanticsScope, Symbol, Type, TypeInfo,
};
use ide_db::{
    FilePosition, FxHashMap, FxHashSet, RootDatabase, famous_defs::FamousDefs,
    helpers::is_editable_crate,
};
use itertools::Either;
use syntax::{
    AstNode, Edition, SmolStr,
    SyntaxKind::{self, *},
    SyntaxToken, T, TextRange, TextSize,
    ast::{self, AttrKind, NameOrNameRef},
    match_ast,
};

use crate::{
    CompletionConfig,
    config::AutoImportExclusionType,
    context::analysis::{AnalysisResult, expand_and_analyze},
};

const COMPLETION_MARKER: &str = "raCompletionMarker";

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum PatternRefutability {
    Refutable,
    Irrefutable,
}

#[derive(Debug)]
pub(crate) enum Visible {
    Yes,
    Editable,
    No,
}

/// Existing qualifiers for the thing we are currently completing.
#[derive(Debug, Default)]
pub(crate) struct QualifierCtx {
    // TODO: Add try_tok and default_tok
    pub(crate) async_tok: Option<SyntaxToken>,
    pub(crate) unsafe_tok: Option<SyntaxToken>,
    pub(crate) safe_tok: Option<SyntaxToken>,
    pub(crate) vis_node: Option<ast::Visibility>,
}

impl QualifierCtx {
    pub(crate) fn none(&self) -> bool {
        self.async_tok.is_none()
            && self.unsafe_tok.is_none()
            && self.safe_tok.is_none()
            && self.vis_node.is_none()
    }
}

/// The state of the path we are currently completing.
#[derive(Debug)]
pub(crate) struct PathCompletionCtx<'db> {
    /// If this is a call with () already there (or {} in case of record patterns)
    pub(crate) has_call_parens: bool,
    /// If this has a macro call bang !
    pub(crate) has_macro_bang: bool,
    /// The qualifier of the current path.
    pub(crate) qualified: Qualified<'db>,
    /// The parent of the path we are completing.
    pub(crate) parent: Option<ast::Path>,
    #[allow(dead_code)]
    /// The path of which we are completing the segment
    pub(crate) path: ast::Path,
    /// The path of which we are completing the segment in the original file
    pub(crate) original_path: Option<ast::Path>,
    pub(crate) kind: PathKind<'db>,
    /// Whether the path segment has type args or not.
    pub(crate) has_type_args: bool,
    /// Whether the qualifier comes from a use tree parent or not
    pub(crate) use_tree_parent: bool,
}

impl PathCompletionCtx<'_> {
    pub(crate) fn is_trivial_path(&self) -> bool {
        matches!(
            self,
            PathCompletionCtx {
                has_call_parens: false,
                has_macro_bang: false,
                qualified: Qualified::No,
                parent: None,
                has_type_args: false,
                ..
            }
        )
    }
}

/// The kind of path we are completing right now.
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum PathKind<'db> {
    Expr {
        expr_ctx: PathExprCtx<'db>,
    },
    Type {
        location: TypeLocation,
    },
    Attr {
        attr_ctx: AttrCtx,
    },
    Derive {
        existing_derives: ExistingDerives,
    },
    /// Path in item position, that is inside an (Assoc)ItemList
    Item {
        kind: ItemListKind,
    },
    Pat {
        pat_ctx: PatternContext,
    },
    Vis {
        has_in_token: bool,
    },
    Use,
}

pub(crate) type ExistingDerives = FxHashSet<hir::Macro>;

#[derive(Debug, PartialEq, Eq)]
pub(crate) struct AttrCtx {
    pub(crate) kind: AttrKind,
    pub(crate) annotated_item_kind: Option<SyntaxKind>,
    pub(crate) derive_helpers: Vec<(Symbol, Symbol)>,
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) struct PathExprCtx<'db> {
    pub(crate) in_block_expr: bool,
    pub(crate) in_breakable: Option<BreakableKind>,
    pub(crate) after_if_expr: bool,
    pub(crate) before_else_kw: bool,
    /// Whether this expression is the direct condition of an if or while expression
    pub(crate) in_condition: bool,
    pub(crate) incomplete_let: bool,
    pub(crate) after_incomplete_let: bool,
    pub(crate) in_value: bool,
    pub(crate) ref_expr_parent: Option<ast::RefExpr>,
    pub(crate) after_amp: bool,
    /// The surrounding RecordExpression we are completing a functional update
    pub(crate) is_func_update: Option<ast::RecordExpr>,
    pub(crate) self_param: Option<hir::SelfParam>,
    pub(crate) innermost_ret_ty: Option<hir::Type<'db>>,
    pub(crate) innermost_breakable_ty: Option<hir::Type<'db>>,
    pub(crate) impl_: Option<ast::Impl>,
    /// Whether this expression occurs in match arm guard position: before the
    /// fat arrow token
    pub(crate) in_match_guard: bool,
}

/// Original file ast nodes
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum TypeLocation {
    TupleField,
    TypeAscription(TypeAscriptionTarget),
    /// Generic argument position e.g. `Foo<$0>`
    GenericArg {
        /// The generic argument list containing the generic arg
        args: Option<ast::GenericArgList>,
        /// `Some(trait_)` if `trait_` is being instantiated with `args`
        of_trait: Option<hir::Trait>,
        /// The generic parameter being filled in by the generic arg
        corresponding_param: Option<ast::GenericParam>,
    },
    /// Associated type equality constraint e.g. `Foo<Bar = $0>`
    AssocTypeEq,
    /// Associated constant equality constraint e.g. `Foo<X = $0>`
    AssocConstEq,
    TypeBound,
    ImplTarget,
    ImplTrait,
    Other,
}

impl TypeLocation {
    pub(crate) fn complete_lifetimes(&self) -> bool {
        matches!(
            self,
            TypeLocation::GenericArg {
                corresponding_param: Some(ast::GenericParam::LifetimeParam(_)),
                ..
            }
        )
    }

    pub(crate) fn complete_consts(&self) -> bool {
        matches!(
            self,
            TypeLocation::GenericArg {
                corresponding_param: Some(ast::GenericParam::ConstParam(_)),
                ..
            } | TypeLocation::AssocConstEq
        )
    }

    pub(crate) fn complete_types(&self) -> bool {
        match self {
            TypeLocation::GenericArg { corresponding_param: Some(param), .. } => {
                matches!(param, ast::GenericParam::TypeParam(_))
            }
            TypeLocation::AssocConstEq => false,
            TypeLocation::AssocTypeEq => true,
            TypeLocation::ImplTrait => false,
            _ => true,
        }
    }

    pub(crate) fn complete_self_type(&self) -> bool {
        self.complete_types() && !matches!(self, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum TypeAscriptionTarget {
    Let(Option<ast::Pat>),
    FnParam(Option<ast::Pat>),
    RetType(Option<ast::Expr>),
    Const(Option<ast::Expr>),
}

/// The kind of item list a [`PathKind::Item`] belongs to.
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum ItemListKind {
    SourceFile,
    Module,
    Impl,
    TraitImpl(Option<ast::Impl>),
    Trait,
    ExternBlock { is_unsafe: bool },
}

#[derive(Debug)]
pub(crate) enum Qualified<'db> {
    No,
    With {
        path: ast::Path,
        resolution: Option<PathResolution>,
        /// How many `super` segments are present in the path
        ///
        /// This would be None, if path is not solely made of
        /// `super` segments, e.g.
        ///
        /// ```ignore
        /// use super::foo;
        /// ```
        ///
        /// Otherwise it should be Some(count of `super`)
        super_chain_len: Option<usize>,
    },
    /// <_>::
    TypeAnchor {
        ty: Option<hir::Type<'db>>,
        trait_: Option<hir::Trait>,
    },
    /// Whether the path is an absolute path
    Absolute,
}

/// The state of the pattern we are completing.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct PatternContext {
    pub(crate) refutability: PatternRefutability,
    pub(crate) param_ctx: Option<ParamContext>,
    pub(crate) has_type_ascription: bool,
    pub(crate) should_suggest_name: bool,
    pub(crate) after_if_expr: bool,
    pub(crate) parent_pat: Option<ast::Pat>,
    pub(crate) ref_token: Option<SyntaxToken>,
    pub(crate) mut_token: Option<SyntaxToken>,
    /// The record pattern this name or ref is a field of
    pub(crate) record_pat: Option<ast::RecordPat>,
    pub(crate) impl_or_trait: Option<Either<ast::Impl, ast::Trait>>,
    /// List of missing variants in a match expr
    pub(crate) missing_variants: Vec<hir::Variant>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct ParamContext {
    pub(crate) param_list: ast::ParamList,
    pub(crate) param: ast::Param,
    pub(crate) kind: ParamKind,
}

/// The state of the lifetime we are completing.
#[derive(Debug)]
pub(crate) struct LifetimeContext {
    pub(crate) kind: LifetimeKind,
}

/// The kind of lifetime we are completing.
#[derive(Debug)]
pub(crate) enum LifetimeKind {
    LifetimeParam,
    Lifetime { in_lifetime_param_bound: bool, def: Option<hir::GenericDef> },
    LabelRef,
    LabelDef,
}

/// The state of the name we are completing.
#[derive(Debug)]
pub(crate) struct NameContext {
    #[allow(dead_code)]
    pub(crate) name: Option<ast::Name>,
    pub(crate) kind: NameKind,
}

/// The kind of the name we are completing.
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) enum NameKind {
    Const,
    ConstParam,
    Enum,
    Function,
    IdentPat(PatternContext),
    MacroDef,
    MacroRules,
    /// Fake node
    Module(ast::Module),
    RecordField,
    Rename,
    SelfParam,
    Static,
    Struct,
    Trait,
    TypeAlias,
    TypeParam,
    Union,
    Variant,
}

/// The state of the NameRef we are completing.
#[derive(Debug)]
pub(crate) struct NameRefContext<'db> {
    /// NameRef syntax in the original file
    pub(crate) nameref: Option<ast::NameRef>,
    pub(crate) kind: NameRefKind<'db>,
}

/// The kind of the NameRef we are completing.
#[derive(Debug)]
pub(crate) enum NameRefKind<'db> {
    Path(PathCompletionCtx<'db>),
    DotAccess(DotAccess<'db>),
    /// Position where we are only interested in keyword completions
    Keyword(ast::Item),
    /// The record expression this nameref is a field of and whether a dot precedes the completion identifier.
    RecordExpr {
        dot_prefix: bool,
        expr: ast::RecordExpr,
    },
    Pattern(PatternContext),
    ExternCrate,
}

/// The identifier we are currently completing.
#[derive(Debug)]
pub(crate) enum CompletionAnalysis<'db> {
    Name(NameContext),
    NameRef(NameRefContext<'db>),
    Lifetime(LifetimeContext),
    /// The string the cursor is currently inside
    String {
        /// original token
        original: ast::String,
        /// fake token
        expanded: Option<ast::String>,
    },
    /// Set if we are currently completing in an unexpanded attribute, this usually implies a builtin attribute like `allow($0)`
    UnexpandedAttrTT {
        colon_prefix: bool,
        fake_attribute_under_caret: Option<ast::Attr>,
        extern_crate: Option<ast::ExternCrate>,
    },
}

/// Information about the field or method access we are completing.
#[derive(Debug)]
pub(crate) struct DotAccess<'db> {
    pub(crate) receiver: Option<ast::Expr>,
    pub(crate) receiver_ty: Option<TypeInfo<'db>>,
    pub(crate) kind: DotAccessKind,
    pub(crate) ctx: DotAccessExprCtx,
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum DotAccessKind {
    Field {
        /// True if the receiver is an integer and there is no ident in the original file after it yet
        /// like `0.$0`
        receiver_is_ambiguous_float_literal: bool,
    },
    Method,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct DotAccessExprCtx {
    pub(crate) in_block_expr: bool,
    pub(crate) in_breakable: Option<BreakableKind>,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum BreakableKind {
    Loop,
    For,
    While,
    Block,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) enum ParamKind {
    Function(ast::Fn),
    Closure(ast::ClosureExpr),
}

/// `CompletionContext` is created early during completion to figure out, where
/// exactly is the cursor, syntax-wise.
#[derive(Debug)]
pub(crate) struct CompletionContext<'a> {
    pub(crate) sema: Semantics<'a, RootDatabase>,
    pub(crate) scope: SemanticsScope<'a>,
    pub(crate) db: &'a RootDatabase,
    pub(crate) config: &'a CompletionConfig<'a>,
    pub(crate) position: FilePosition,

    pub(crate) trigger_character: Option<char>,
    /// The token before the cursor, in the original file.
    pub(crate) original_token: SyntaxToken,
    /// The token before the cursor, in the macro-expanded file.
    pub(crate) token: SyntaxToken,
    /// The crate of the current file.
    pub(crate) krate: hir::Crate,
    pub(crate) display_target: DisplayTarget,
    /// The module of the `scope`.
    pub(crate) module: hir::Module,
    /// The function where we're completing, if inside a function.
    pub(crate) containing_function: Option<hir::Function>,
    /// Whether nightly toolchain is used. Cached since this is looked up a lot.
    pub(crate) is_nightly: bool,
    /// The edition of the current crate
    // FIXME: This should probably be the crate of the current token?
    pub(crate) edition: Edition,

    /// The expected name of what we are completing.
    /// This is usually the parameter name of the function argument we are completing.
    pub(crate) expected_name: Option<NameOrNameRef>,
    /// The expected type of what we are completing.
    pub(crate) expected_type: Option<Type<'a>>,

    pub(crate) qualifier_ctx: QualifierCtx,

    pub(crate) locals: FxHashMap<Name, Local>,

    /// The module depth of the current module of the cursor position.
    /// - crate-root
    ///  - mod foo
    ///   - mod bar
    ///
    /// Here depth will be 2
    pub(crate) depth_from_crate_root: usize,

    /// Traits whose methods will be excluded from flyimport. Flyimport should not suggest
    /// importing those traits.
    ///
    /// Note the trait *themselves* are not excluded, only their methods are.
    pub(crate) exclude_flyimport: FxHashMap<ModuleDef, AutoImportExclusionType>,
    /// Traits whose methods should always be excluded, even when in scope (compare `exclude_flyimport_traits`).
    /// They will *not* be excluded, however, if they are available as a generic bound.
    ///
    /// Note the trait *themselves* are not excluded, only their methods are.
    pub(crate) exclude_traits: FxHashSet<hir::Trait>,

    /// Whether and how to complete semicolon for unit-returning functions.
    pub(crate) complete_semicolon: CompleteSemicolon,
}

#[derive(Debug)]
pub(crate) enum CompleteSemicolon {
    DoNotComplete,
    CompleteSemi,
    CompleteComma,
}

impl CompletionContext<'_> {
    /// The range of the identifier that is being completed.
    pub(crate) fn source_range(&self) -> TextRange {
        let kind = self.original_token.kind();
        match kind {
            CHAR => {
                // assume we are completing a lifetime but the user has only typed the '
                cov_mark::hit!(completes_if_lifetime_without_idents);
                TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
            }
            LIFETIME_IDENT | UNDERSCORE | INT_NUMBER => self.original_token.text_range(),
            // We want to consider all keywords in all editions.
            _ if kind.is_any_identifier() => self.original_token.text_range(),
            _ => TextRange::empty(self.position.offset),
        }
    }

    pub(crate) fn famous_defs(&self) -> FamousDefs<'_, '_> {
        FamousDefs(&self.sema, self.krate)
    }

    /// Checks if an item is visible and not `doc(hidden)` at the completion site.
    pub(crate) fn def_is_visible(&self, item: &ScopeDef) -> Visible {
        match item {
            ScopeDef::ModuleDef(def) => match def {
                hir::ModuleDef::Module(it) => self.is_visible(it),
                hir::ModuleDef::Function(it) => self.is_visible(it),
                hir::ModuleDef::Adt(it) => self.is_visible(it),
                hir::ModuleDef::Variant(it) => self.is_visible(it),
                hir::ModuleDef::Const(it) => self.is_visible(it),
                hir::ModuleDef::Static(it) => self.is_visible(it),
                hir::ModuleDef::Trait(it) => self.is_visible(it),
                hir::ModuleDef::TypeAlias(it) => self.is_visible(it),
                hir::ModuleDef::Macro(it) => self.is_visible(it),
                hir::ModuleDef::BuiltinType(_) => Visible::Yes,
            },
            ScopeDef::GenericParam(_)
            | ScopeDef::ImplSelfType(_)
            | ScopeDef::AdtSelfType(_)
            | ScopeDef::Local(_)
            | ScopeDef::Label(_)
            | ScopeDef::Unknown => Visible::Yes,
        }
    }

    /// Checks if an item is visible, not `doc(hidden)` and stable at the completion site.
    pub(crate) fn is_visible<I>(&self, item: &I) -> Visible
    where
        I: hir::HasVisibility + hir::HasAttrs + hir::HasCrate + Copy,
    {
        let vis = item.visibility(self.db);
        let attrs = item.attrs(self.db);
        self.is_visible_impl(&vis, &attrs, item.krate(self.db))
    }

    pub(crate) fn doc_aliases<I>(&self, item: &I) -> Vec<SmolStr>
    where
        I: hir::HasAttrs + Copy,
    {
        let attrs = item.attrs(self.db);
        attrs.doc_aliases().map(|it| it.as_str().into()).collect()
    }

    /// Check if an item is `#[doc(hidden)]`.
    pub(crate) fn is_item_hidden(&self, item: &hir::ItemInNs) -> bool {
        let attrs = item.attrs(self.db);
        let krate = item.krate(self.db);
        match (attrs, krate) {
            (Some(attrs), Some(krate)) => self.is_doc_hidden(&attrs, krate),
            _ => false,
        }
    }

    /// Checks whether this item should be listed in regards to stability. Returns `true` if we should.
    pub(crate) fn check_stability(&self, attrs: Option<&hir::Attrs>) -> bool {
        let Some(attrs) = attrs else {
            return true;
        };
        !attrs.is_unstable() || self.is_nightly
    }

    pub(crate) fn check_stability_and_hidden<I>(&self, item: I) -> bool
    where
        I: hir::HasAttrs + hir::HasCrate,
    {
        let defining_crate = item.krate(self.db);
        let attrs = item.attrs(self.db);
        self.check_stability(Some(&attrs)) && !self.is_doc_hidden(&attrs, defining_crate)
    }

    /// Whether the given trait is an operator trait or not.
    pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool {
        match trait_.attrs(self.db).lang() {
            Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang.as_str()),
            None => false,
        }
    }

    /// Whether the given trait has `#[doc(notable_trait)]`
    pub(crate) fn is_doc_notable_trait(&self, trait_: hir::Trait) -> bool {
        trait_.attrs(self.db).has_doc_notable_trait()
    }

    /// Returns the traits in scope, with the [`Drop`] trait removed.
    pub(crate) fn traits_in_scope(&self) -> hir::VisibleTraits {
        let mut traits_in_scope = self.scope.visible_traits();
        if let Some(drop) = self.famous_defs().core_ops_Drop() {
            traits_in_scope.0.remove(&drop.into());
        }
        traits_in_scope
    }

    pub(crate) fn iterate_path_candidates(
        &self,
        ty: &hir::Type<'_>,
        mut cb: impl FnMut(hir::AssocItem),
    ) {
        let mut seen = FxHashSet::default();
        ty.iterate_path_candidates(
            self.db,
            &self.scope,
            &self.traits_in_scope(),
            Some(self.module),
            None,
            |item| {
                // We might iterate candidates of a trait multiple times here, so deduplicate
                // them.
                if seen.insert(item) {
                    cb(item)
                }
                None::<()>
            },
        );
    }

    /// A version of [`SemanticsScope::process_all_names`] that filters out `#[doc(hidden)]` items and
    /// passes all doc-aliases along, to funnel it into [`Completions::add_path_resolution`].
    pub(crate) fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef, Vec<SmolStr>)) {
        let _p = tracing::info_span!("CompletionContext::process_all_names").entered();
        self.scope.process_all_names(&mut |name, def| {
            if self.is_scope_def_hidden(def) {
                return;
            }
            let doc_aliases = self.doc_aliases_in_scope(def);
            f(name, def, doc_aliases);
        });
    }

    pub(crate) fn process_all_names_raw(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
        let _p = tracing::info_span!("CompletionContext::process_all_names_raw").entered();
        self.scope.process_all_names(f);
    }

    fn is_scope_def_hidden(&self, scope_def: ScopeDef) -> bool {
        if let (Some(attrs), Some(krate)) = (scope_def.attrs(self.db), scope_def.krate(self.db)) {
            return self.is_doc_hidden(&attrs, krate);
        }

        false
    }

    fn is_visible_impl(
        &self,
        vis: &hir::Visibility,
        attrs: &hir::Attrs,
        defining_crate: hir::Crate,
    ) -> Visible {
        if !self.check_stability(Some(attrs)) {
            return Visible::No;
        }

        if !vis.is_visible_from(self.db, self.module.into()) {
            if !self.config.enable_private_editable {
                return Visible::No;
            }
            // If the definition location is editable, also show private items
            return if is_editable_crate(defining_crate, self.db) {
                Visible::Editable
            } else {
                Visible::No
            };
        }

        if self.is_doc_hidden(attrs, defining_crate) { Visible::No } else { Visible::Yes }
    }

    pub(crate) fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool {
        // `doc(hidden)` items are only completed within the defining crate.
        self.krate != defining_crate && attrs.has_doc_hidden()
    }

    pub(crate) fn doc_aliases_in_scope(&self, scope_def: ScopeDef) -> Vec<SmolStr> {
        if let Some(attrs) = scope_def.attrs(self.db) {
            attrs.doc_aliases().map(|it| it.as_str().into()).collect()
        } else {
            vec![]
        }
    }
}

// CompletionContext construction
impl<'db> CompletionContext<'db> {
    pub(crate) fn new(
        db: &'db RootDatabase,
        position @ FilePosition { file_id, offset }: FilePosition,
        config: &'db CompletionConfig<'db>,
        trigger_character: Option<char>,
    ) -> Option<(CompletionContext<'db>, CompletionAnalysis<'db>)> {
        let _p = tracing::info_span!("CompletionContext::new").entered();
        let sema = Semantics::new(db);

        let editioned_file_id = sema.attach_first_edition(file_id)?;
        let original_file = sema.parse(editioned_file_id);

        // Insert a fake ident to get a valid parse tree. We will use this file
        // to determine context, though the original_file will be used for
        // actual completion.
        let file_with_fake_ident = {
            let (_, edition) = editioned_file_id.unpack(db);
            let parse = db.parse(editioned_file_id);
            parse.reparse(TextRange::empty(offset), COMPLETION_MARKER, edition).tree()
        };

        // always pick the token to the immediate left of the cursor, as that is what we are actually
        // completing on
        let original_token = original_file.syntax().token_at_offset(offset).left_biased()?;

        // try to skip completions on path with invalid colons
        // this approach works in normal path and inside token tree
        if original_token.kind() == T![:] {
            // return if no prev token before colon
            let prev_token = original_token.prev_token()?;

            // only has a single colon
            if prev_token.kind() != T![:] {
                return None;
            }

            // has 3 colon or 2 coloncolon in a row
            // special casing this as per discussion in https://github.com/rust-lang/rust-analyzer/pull/13611#discussion_r1031845205
            // and https://github.com/rust-lang/rust-analyzer/pull/13611#discussion_r1032812751
            if prev_token
                .prev_token()
                .map(|t| t.kind() == T![:] || t.kind() == T![::])
                .unwrap_or(false)
            {
                return None;
            }
        }

        let AnalysisResult {
            analysis,
            expected: (expected_type, expected_name),
            qualifier_ctx,
            token,
            original_offset,
        } = expand_and_analyze(
            &sema,
            InFile::new(editioned_file_id.into(), original_file.syntax().clone()),
            file_with_fake_ident.syntax().clone(),
            offset,
            &original_token,
        )?;

        // adjust for macro input, this still fails if there is no token written yet
        let scope = sema.scope_at_offset(&token.parent()?, original_offset)?;

        let krate = scope.krate();
        let module = scope.module();
        let containing_function = scope.containing_function();
        let edition = krate.edition(db);

        let toolchain = db.toolchain_channel(krate.into());
        // `toolchain == None` means we're in some detached files. Since we have no information on
        // the toolchain being used, let's just allow unstable items to be listed.
        let is_nightly = matches!(toolchain, Some(base_db::ReleaseChannel::Nightly) | None);

        let mut locals = FxHashMap::default();
        scope.process_all_names(&mut |name, scope| {
            if let ScopeDef::Local(local) = scope {
                // synthetic names currently leak out as we lack synthetic hygiene, so filter them
                // out here
                if name.as_str().starts_with('<') {
                    return;
                }
                locals.insert(name, local);
            }
        });

        let depth_from_crate_root = iter::successors(Some(module), |m| m.parent(db))
            // `BlockExpr` modules do not count towards module depth
            .filter(|m| !matches!(m.definition_source(db).value, ModuleSource::BlockExpr(_)))
            .count()
            // exclude `m` itself
            .saturating_sub(1);

        let exclude_traits: FxHashSet<_> = config
            .exclude_traits
            .iter()
            .filter_map(|path| {
                hir::resolve_absolute_path(db, path.split("::").map(Symbol::intern)).find_map(
                    |it| match it {
                        hir::ItemInNs::Types(ModuleDef::Trait(t)) => Some(t),
                        _ => None,
                    },
                )
            })
            .collect();

        let mut exclude_flyimport: FxHashMap<_, _> = config
            .exclude_flyimport
            .iter()
            .flat_map(|(path, kind)| {
                hir::resolve_absolute_path(db, path.split("::").map(Symbol::intern))
                    .map(|it| (it.into_module_def(), *kind))
            })
            .collect();
        exclude_flyimport
            .extend(exclude_traits.iter().map(|&t| (t.into(), AutoImportExclusionType::Always)));

        // FIXME: This should be part of `CompletionAnalysis` / `expand_and_analyze`
        let complete_semicolon = if config.add_semicolon_to_unit {
            let inside_closure_ret = token.parent_ancestors().try_for_each(|ancestor| {
                match_ast! {
                    match ancestor {
                        ast::BlockExpr(_) => ControlFlow::Break(false),
                        ast::ClosureExpr(_) => ControlFlow::Break(true),
                        _ => ControlFlow::Continue(())
                    }
                }
            });

            if inside_closure_ret == ControlFlow::Break(true) {
                CompleteSemicolon::DoNotComplete
            } else {
                let next_non_trivia_token =
                    std::iter::successors(token.next_token(), |it| it.next_token())
                        .find(|it| !it.kind().is_trivia());
                let in_match_arm = token.parent_ancestors().try_for_each(|ancestor| {
                    if ast::MatchArm::can_cast(ancestor.kind()) {
                        ControlFlow::Break(true)
                    } else if matches!(
                        ancestor.kind(),
                        SyntaxKind::EXPR_STMT | SyntaxKind::BLOCK_EXPR
                    ) {
                        ControlFlow::Break(false)
                    } else {
                        ControlFlow::Continue(())
                    }
                });
                // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node.
                let in_match_arm = match in_match_arm {
                    ControlFlow::Continue(()) => false,
                    ControlFlow::Break(it) => it,
                };
                let complete_token = if in_match_arm { T![,] } else { T![;] };
                if next_non_trivia_token.map(|it| it.kind()) == Some(complete_token) {
                    CompleteSemicolon::DoNotComplete
                } else if in_match_arm {
                    CompleteSemicolon::CompleteComma
                } else {
                    CompleteSemicolon::CompleteSemi
                }
            }
        } else {
            CompleteSemicolon::DoNotComplete
        };

        let display_target = krate.to_display_target(db);
        let ctx = CompletionContext {
            sema,
            scope,
            db,
            config,
            position,
            trigger_character,
            original_token,
            token,
            krate,
            module,
            containing_function,
            is_nightly,
            edition,
            expected_name,
            expected_type,
            qualifier_ctx,
            locals,
            depth_from_crate_root,
            exclude_flyimport,
            exclude_traits,
            complete_semicolon,
            display_target,
        };
        Some((ctx, analysis))
    }
}

const OP_TRAIT_LANG_NAMES: &[&str] = &[
    "add_assign",
    "add",
    "bitand_assign",
    "bitand",
    "bitor_assign",
    "bitor",
    "bitxor_assign",
    "bitxor",
    "deref_mut",
    "deref",
    "div_assign",
    "div",
    "eq",
    "fn_mut",
    "fn_once",
    "fn",
    "index_mut",
    "index",
    "mul_assign",
    "mul",
    "neg",
    "not",
    "partial_ord",
    "rem_assign",
    "rem",
    "shl_assign",
    "shl",
    "shr_assign",
    "shr",
    "sub",
];
