//! ide crate provides "ide-centric" APIs for the rust-analyzer. That is,
//! it generally operates with files and text ranges, and returns results as
//! Strings, suitable for displaying to the human.
//!
//! What powers this API are the `RootDatabase` struct, which defines a `salsa`
//! database, and the `hir` crate, where majority of the analysis happens.
//! However, IDE specific bits of the analysis (most notably completion) happen
//! in this crate.

// For proving that RootDatabase is RefUnwindSafe.

#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
#![recursion_limit = "128"]

#[cfg(test)]
mod fixture;

mod markup;
mod navigation_target;

mod annotations;
mod call_hierarchy;
mod child_modules;
mod doc_links;
mod expand_macro;
mod extend_selection;
mod fetch_crates;
mod file_structure;
mod folding_ranges;
mod goto_declaration;
mod goto_definition;
mod goto_implementation;
mod goto_type_definition;
mod highlight_related;
mod hover;
mod inlay_hints;
mod interpret;
mod join_lines;
mod markdown_remove;
mod matching_brace;
mod moniker;
mod move_item;
mod parent_module;
mod references;
mod rename;
mod runnables;
mod signature_help;
mod ssr;
mod static_index;
mod status;
mod syntax_highlighting;
mod test_explorer;
mod typing;
mod view_crate_graph;
mod view_hir;
mod view_item_tree;
mod view_memory_layout;
mod view_mir;
mod view_syntax_tree;

use std::panic::{AssertUnwindSafe, UnwindSafe};

use cfg::CfgOptions;
use fetch_crates::CrateInfo;
use hir::{ChangeWithProcMacros, EditionedFileId, crate_def_map, sym};
use ide_db::{
    FxHashMap, FxIndexSet, LineIndexDatabase,
    base_db::{
        CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, VfsPath,
        salsa::Cancelled,
    },
    prime_caches, symbol_index,
};
use ide_db::{MiniCore, ra_fixture::RaFixtureAnalysis};
use macros::UpmapFromRaFixture;
use syntax::{SourceFile, ast};
use triomphe::Arc;
use view_memory_layout::{RecursiveMemoryLayout, view_memory_layout};

use crate::navigation_target::ToNav;

pub use crate::{
    annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
    call_hierarchy::{CallHierarchyConfig, CallItem},
    expand_macro::ExpandedMacro,
    file_structure::{FileStructureConfig, StructureNode, StructureNodeKind},
    folding_ranges::{Fold, FoldKind},
    goto_definition::GotoDefinitionConfig,
    goto_implementation::GotoImplementationConfig,
    highlight_related::{HighlightRelatedConfig, HighlightedRange},
    hover::{
        HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult,
        MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, SubstTyLen,
    },
    inlay_hints::{
        AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
        GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
        InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LazyProperty,
        LifetimeElisionHints,
    },
    join_lines::JoinLinesConfig,
    markup::Markup,
    moniker::{
        Moniker, MonikerDescriptorKind, MonikerIdentifier, MonikerKind, MonikerResult,
        PackageInformation, SymbolInformationKind,
    },
    move_item::Direction,
    navigation_target::{NavigationTarget, TryToNav, UpmappingResult},
    references::{FindAllRefsConfig, ReferenceSearchResult},
    rename::{RenameConfig, RenameError},
    runnables::{Runnable, RunnableKind, TestId, UpdateTest},
    signature_help::SignatureHelp,
    static_index::{
        StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig,
    },
    syntax_highlighting::{
        HighlightConfig, HlRange,
        tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
    },
    test_explorer::{TestItem, TestItemKind},
};
pub use hir::Semantics;
pub use ide_assists::{
    Assist, AssistConfig, AssistId, AssistKind, AssistResolveStrategy, SingleResolve,
};
pub use ide_completion::{
    CallableSnippets, CompletionConfig, CompletionFieldsToResolve, CompletionItem,
    CompletionItemKind, CompletionItemRefMode, CompletionRelevance, Snippet, SnippetScope,
};
pub use ide_db::{
    FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind,
    assists::ExprFillDefaultMode,
    base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId},
    documentation::Documentation,
    label::Label,
    line_index::{LineCol, LineIndex},
    prime_caches::ParallelPrimeCachesProgress,
    search::{ReferenceCategory, SearchScope},
    source_change::{FileSystemEdit, SnippetEdit, SourceChange},
    symbol_index::Query,
    text_edit::{Indel, TextEdit},
};
pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig};
pub use ide_ssr::SsrError;
pub use span::Edition;
pub use syntax::{TextRange, TextSize};

pub type Cancellable<T> = Result<T, Cancelled>;

/// Info associated with a text range.
#[derive(Debug, UpmapFromRaFixture)]
pub struct RangeInfo<T> {
    pub range: TextRange,
    pub info: T,
}

impl<T> RangeInfo<T> {
    pub fn new(range: TextRange, info: T) -> RangeInfo<T> {
        RangeInfo { range, info }
    }
}

/// `AnalysisHost` stores the current state of the world.
#[derive(Debug)]
pub struct AnalysisHost {
    db: RootDatabase,
}

impl AnalysisHost {
    pub fn new(lru_capacity: Option<u16>) -> AnalysisHost {
        AnalysisHost { db: RootDatabase::new(lru_capacity) }
    }

    pub fn with_database(db: RootDatabase) -> AnalysisHost {
        AnalysisHost { db }
    }

    pub fn update_lru_capacity(&mut self, lru_capacity: Option<u16>) {
        self.db.update_base_query_lru_capacities(lru_capacity);
    }

    pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, u16>) {
        self.db.update_lru_capacities(lru_capacities);
    }

    /// Returns a snapshot of the current state, which you can query for
    /// semantic information.
    pub fn analysis(&self) -> Analysis {
        Analysis { db: self.db.clone() }
    }

    /// Applies changes to the current state of the world. If there are
    /// outstanding snapshots, they will be canceled.
    pub fn apply_change(&mut self, change: ChangeWithProcMacros) {
        self.db.apply_change(change);
    }

    /// NB: this clears the database
    pub fn per_query_memory_usage(&mut self) -> Vec<(String, profile::Bytes, usize)> {
        self.db.per_query_memory_usage()
    }
    pub fn request_cancellation(&mut self) {
        self.db.request_cancellation();
    }
    pub fn raw_database(&self) -> &RootDatabase {
        &self.db
    }
    pub fn raw_database_mut(&mut self) -> &mut RootDatabase {
        &mut self.db
    }
}

impl Default for AnalysisHost {
    fn default() -> AnalysisHost {
        AnalysisHost::new(None)
    }
}

/// Analysis is a snapshot of a world state at a moment in time. It is the main
/// entry point for asking semantic information about the world. When the world
/// state is advanced using `AnalysisHost::apply_change` method, all existing
/// `Analysis` are canceled (most method return `Err(Canceled)`).
#[derive(Debug)]
pub struct Analysis {
    db: RootDatabase,
}

// As a general design guideline, `Analysis` API are intended to be independent
// from the language server protocol. That is, when exposing some functionality
// we should think in terms of "what API makes most sense" and not in terms of
// "what types LSP uses". Although currently LSP is the only consumer of the
// API, the API should in theory be usable as a library, or via a different
// protocol.
impl Analysis {
    // Creates an analysis instance for a single file, without any external
    // dependencies, stdlib support or ability to apply changes. See
    // `AnalysisHost` for creating a fully-featured analysis.
    pub fn from_single_file(text: String) -> (Analysis, FileId) {
        let mut host = AnalysisHost::default();
        let file_id = FileId::from_raw(0);
        let mut file_set = FileSet::default();
        file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_owned()));
        let source_root = SourceRoot::new_local(file_set);

        let mut change = ChangeWithProcMacros::default();
        change.set_roots(vec![source_root]);
        let mut crate_graph = CrateGraphBuilder::default();
        // FIXME: cfg options
        // Default to enable test for single file.
        let mut cfg_options = CfgOptions::default();

        // FIXME: This is less than ideal
        let proc_macro_cwd = Arc::new(
            TryFrom::try_from(&*std::env::current_dir().unwrap().as_path().to_string_lossy())
                .unwrap(),
        );
        cfg_options.insert_atom(sym::test);
        crate_graph.add_crate_root(
            file_id,
            Edition::CURRENT,
            None,
            None,
            cfg_options,
            None,
            Env::default(),
            CrateOrigin::Local { repo: None, name: None },
            false,
            proc_macro_cwd,
            Arc::new(CrateWorkspaceData {
                target: Err("fixture has no layout".into()),
                toolchain: None,
            }),
        );
        change.change_file(file_id, Some(text));
        change.set_crate_graph(crate_graph);

        host.apply_change(change);
        (host.analysis(), file_id)
    }

    pub(crate) fn from_ra_fixture(
        sema: &Semantics<'_, RootDatabase>,
        literal: ast::String,
        expanded: &ast::String,
        minicore: MiniCore<'_>,
    ) -> Option<(Analysis, RaFixtureAnalysis)> {
        Self::from_ra_fixture_with_on_cursor(sema, literal, expanded, minicore, &mut |_| {})
    }

    /// Like [`Analysis::from_ra_fixture()`], but also calls `on_cursor` with the cursor position.
    pub(crate) fn from_ra_fixture_with_on_cursor(
        sema: &Semantics<'_, RootDatabase>,
        literal: ast::String,
        expanded: &ast::String,
        minicore: MiniCore<'_>,
        on_cursor: &mut dyn FnMut(TextRange),
    ) -> Option<(Analysis, RaFixtureAnalysis)> {
        let analysis =
            RaFixtureAnalysis::analyze_ra_fixture(sema, literal, expanded, minicore, on_cursor)?;
        Some((Analysis { db: analysis.db.clone() }, analysis))
    }

    /// Debug info about the current state of the analysis.
    pub fn status(&self, file_id: Option<FileId>) -> Cancellable<String> {
        self.with_db(|db| status::status(db, file_id))
    }

    pub fn source_root_id(&self, file_id: FileId) -> Cancellable<SourceRootId> {
        self.with_db(|db| db.file_source_root(file_id).source_root_id(db))
    }

    pub fn is_local_source_root(&self, source_root_id: SourceRootId) -> Cancellable<bool> {
        self.with_db(|db| {
            let sr = db.source_root(source_root_id).source_root(db);
            !sr.is_library
        })
    }

    pub fn parallel_prime_caches<F>(&self, num_worker_threads: usize, cb: F) -> Cancellable<()>
    where
        F: Fn(ParallelPrimeCachesProgress) + Sync + std::panic::UnwindSafe,
    {
        self.with_db(move |db| prime_caches::parallel_prime_caches(db, num_worker_threads, &cb))
    }

    /// Gets the text of the source file.
    pub fn file_text(&self, file_id: FileId) -> Cancellable<Arc<str>> {
        self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db).clone())
    }

    /// Gets the syntax tree of the file.
    pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> {
        // FIXME edition
        self.with_db(|db| {
            let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);

            db.parse(editioned_file_id_wrapper).tree()
        })
    }

    /// Returns true if this file belongs to an immutable library.
    pub fn is_library_file(&self, file_id: FileId) -> Cancellable<bool> {
        self.with_db(|db| {
            let source_root = db.file_source_root(file_id).source_root_id(db);
            db.source_root(source_root).source_root(db).is_library
        })
    }

    /// Gets the file's `LineIndex`: data structure to convert between absolute
    /// offsets and line/column representation.
    pub fn file_line_index(&self, file_id: FileId) -> Cancellable<Arc<LineIndex>> {
        self.with_db(|db| db.line_index(file_id))
    }

    /// Selects the next syntactic nodes encompassing the range.
    pub fn extend_selection(&self, frange: FileRange) -> Cancellable<TextRange> {
        self.with_db(|db| extend_selection::extend_selection(db, frange))
    }

    /// Returns position of the matching brace (all types of braces are
    /// supported).
    pub fn matching_brace(&self, position: FilePosition) -> Cancellable<Option<TextSize>> {
        self.with_db(|db| {
            let file_id = EditionedFileId::current_edition(&self.db, position.file_id);
            let parse = db.parse(file_id);
            let file = parse.tree();
            matching_brace::matching_brace(&file, position.offset)
        })
    }

    pub fn view_syntax_tree(&self, file_id: FileId) -> Cancellable<String> {
        self.with_db(|db| view_syntax_tree::view_syntax_tree(db, file_id))
    }

    pub fn view_hir(&self, position: FilePosition) -> Cancellable<String> {
        self.with_db(|db| view_hir::view_hir(db, position))
    }

    pub fn view_mir(&self, position: FilePosition) -> Cancellable<String> {
        self.with_db(|db| view_mir::view_mir(db, position))
    }

    pub fn interpret_function(&self, position: FilePosition) -> Cancellable<String> {
        self.with_db(|db| interpret::interpret(db, position))
    }

    pub fn view_item_tree(&self, file_id: FileId) -> Cancellable<String> {
        self.with_db(|db| view_item_tree::view_item_tree(db, file_id))
    }

    pub fn discover_test_roots(&self) -> Cancellable<Vec<TestItem>> {
        self.with_db(test_explorer::discover_test_roots)
    }

    pub fn discover_tests_in_crate_by_test_id(&self, crate_id: &str) -> Cancellable<Vec<TestItem>> {
        self.with_db(|db| test_explorer::discover_tests_in_crate_by_test_id(db, crate_id))
    }

    pub fn discover_tests_in_crate(&self, crate_id: Crate) -> Cancellable<Vec<TestItem>> {
        self.with_db(|db| test_explorer::discover_tests_in_crate(db, crate_id))
    }

    pub fn discover_tests_in_file(&self, file_id: FileId) -> Cancellable<Vec<TestItem>> {
        self.with_db(|db| test_explorer::discover_tests_in_file(db, file_id))
    }

    /// Renders the crate graph to GraphViz "dot" syntax.
    pub fn view_crate_graph(&self, full: bool) -> Cancellable<Result<String, String>> {
        self.with_db(|db| view_crate_graph::view_crate_graph(db, full))
    }

    pub fn fetch_crates(&self) -> Cancellable<FxIndexSet<CrateInfo>> {
        self.with_db(fetch_crates::fetch_crates)
    }

    pub fn expand_macro(&self, position: FilePosition) -> Cancellable<Option<ExpandedMacro>> {
        self.with_db(|db| expand_macro::expand_macro(db, position))
    }

    /// Returns an edit to remove all newlines in the range, cleaning up minor
    /// stuff like trailing commas.
    pub fn join_lines(&self, config: &JoinLinesConfig, frange: FileRange) -> Cancellable<TextEdit> {
        self.with_db(|db| {
            let editioned_file_id_wrapper =
                EditionedFileId::current_edition(&self.db, frange.file_id);
            let parse = db.parse(editioned_file_id_wrapper);
            join_lines::join_lines(config, &parse.tree(), frange.range)
        })
    }

    /// Returns an edit which should be applied when opening a new line, fixing
    /// up minor stuff like continuing the comment.
    /// The edit will be a snippet (with `$0`).
    pub fn on_enter(&self, position: FilePosition) -> Cancellable<Option<TextEdit>> {
        self.with_db(|db| typing::on_enter(db, position))
    }

    pub const SUPPORTED_TRIGGER_CHARS: &[char] = typing::TRIGGER_CHARS;

    /// Returns an edit which should be applied after a character was typed.
    ///
    /// This is useful for some on-the-fly fixups, like adding `;` to `let =`
    /// automatically.
    pub fn on_char_typed(
        &self,
        position: FilePosition,
        char_typed: char,
    ) -> Cancellable<Option<SourceChange>> {
        // Fast path to not even parse the file.
        if !typing::TRIGGER_CHARS.contains(&char_typed) {
            return Ok(None);
        }

        self.with_db(|db| typing::on_char_typed(db, position, char_typed))
    }

    /// Returns a tree representation of symbols in the file. Useful to draw a
    /// file outline.
    pub fn file_structure(
        &self,
        config: &FileStructureConfig,
        file_id: FileId,
    ) -> Cancellable<Vec<StructureNode>> {
        // FIXME: Edition
        self.with_db(|db| {
            let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
            let source_file = db.parse(editioned_file_id_wrapper).tree();
            file_structure::file_structure(&source_file, config)
        })
    }

    /// Returns a list of the places in the file where type hints can be displayed.
    pub fn inlay_hints(
        &self,
        config: &InlayHintsConfig<'_>,
        file_id: FileId,
        range: Option<TextRange>,
    ) -> Cancellable<Vec<InlayHint>> {
        self.with_db(|db| inlay_hints::inlay_hints(db, file_id, range, config))
    }
    pub fn inlay_hints_resolve(
        &self,
        config: &InlayHintsConfig<'_>,
        file_id: FileId,
        resolve_range: TextRange,
        hash: u64,
        hasher: impl Fn(&InlayHint) -> u64 + Send + UnwindSafe,
    ) -> Cancellable<Option<InlayHint>> {
        self.with_db(|db| {
            inlay_hints::inlay_hints_resolve(db, file_id, resolve_range, hash, config, hasher)
        })
    }

    /// Returns the set of folding ranges.
    pub fn folding_ranges(&self, file_id: FileId) -> Cancellable<Vec<Fold>> {
        self.with_db(|db| {
            let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);

            folding_ranges::folding_ranges(&db.parse(editioned_file_id_wrapper).tree())
        })
    }

    /// Fuzzy searches for a symbol.
    pub fn symbol_search(&self, query: Query, limit: usize) -> Cancellable<Vec<NavigationTarget>> {
        // `world_symbols` currently clones the database to run stuff in parallel, which will make any query panic
        // if we were to attach it here.
        Cancelled::catch(|| {
            let symbols = symbol_index::world_symbols(&self.db, query);
            hir::attach_db(&self.db, || {
                symbols
                    .into_iter()
                    .filter_map(|s| s.try_to_nav(&Semantics::new(&self.db)))
                    .take(limit)
                    .map(UpmappingResult::call_site)
                    .collect::<Vec<_>>()
            })
        })
    }

    /// Returns the definitions from the symbol at `position`.
    pub fn goto_definition(
        &self,
        position: FilePosition,
        config: &GotoDefinitionConfig<'_>,
    ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> {
        self.with_db(|db| goto_definition::goto_definition(db, position, config))
    }

    /// Returns the declaration from the symbol at `position`.
    pub fn goto_declaration(
        &self,
        position: FilePosition,
        config: &GotoDefinitionConfig<'_>,
    ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> {
        self.with_db(|db| goto_declaration::goto_declaration(db, position, config))
    }

    /// Returns the impls from the symbol at `position`.
    pub fn goto_implementation(
        &self,
        config: &GotoImplementationConfig,
        position: FilePosition,
    ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> {
        self.with_db(|db| goto_implementation::goto_implementation(db, config, position))
    }

    /// Returns the type definitions for the symbol at `position`.
    pub fn goto_type_definition(
        &self,
        position: FilePosition,
    ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> {
        self.with_db(|db| goto_type_definition::goto_type_definition(db, position))
    }

    pub fn find_all_refs(
        &self,
        position: FilePosition,
        config: &FindAllRefsConfig<'_>,
    ) -> Cancellable<Option<Vec<ReferenceSearchResult>>> {
        let config = AssertUnwindSafe(config);
        self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, &config))
    }

    /// Returns a short text describing element at position.
    pub fn hover(
        &self,
        config: &HoverConfig<'_>,
        range: FileRange,
    ) -> Cancellable<Option<RangeInfo<HoverResult>>> {
        self.with_db(|db| hover::hover(db, range, config))
    }

    /// Returns moniker of symbol at position.
    pub fn moniker(
        &self,
        position: FilePosition,
    ) -> Cancellable<Option<RangeInfo<Vec<moniker::MonikerResult>>>> {
        self.with_db(|db| moniker::moniker(db, position))
    }

    /// Returns URL(s) for the documentation of the symbol under the cursor.
    /// # Arguments
    /// * `position` - Position in the file.
    /// * `target_dir` - Directory where the build output is stored.
    pub fn external_docs(
        &self,
        position: FilePosition,
        target_dir: Option<&str>,
        sysroot: Option<&str>,
    ) -> Cancellable<doc_links::DocumentationLinks> {
        self.with_db(|db| {
            doc_links::external_docs(db, position, target_dir, sysroot).unwrap_or_default()
        })
    }

    /// Computes parameter information at the given position.
    pub fn signature_help(&self, position: FilePosition) -> Cancellable<Option<SignatureHelp>> {
        self.with_db(|db| signature_help::signature_help(db, position))
    }

    /// Computes call hierarchy candidates for the given file position.
    pub fn call_hierarchy(
        &self,
        position: FilePosition,
        config: &CallHierarchyConfig<'_>,
    ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> {
        self.with_db(|db| call_hierarchy::call_hierarchy(db, position, config))
    }

    /// Computes incoming calls for the given file position.
    pub fn incoming_calls(
        &self,
        config: &CallHierarchyConfig<'_>,
        position: FilePosition,
    ) -> Cancellable<Option<Vec<CallItem>>> {
        self.with_db(|db| call_hierarchy::incoming_calls(db, config, position))
    }

    /// Computes outgoing calls for the given file position.
    pub fn outgoing_calls(
        &self,
        config: &CallHierarchyConfig<'_>,
        position: FilePosition,
    ) -> Cancellable<Option<Vec<CallItem>>> {
        self.with_db(|db| call_hierarchy::outgoing_calls(db, config, position))
    }

    /// Returns a `mod name;` declaration which created the current module.
    pub fn parent_module(&self, position: FilePosition) -> Cancellable<Vec<NavigationTarget>> {
        self.with_db(|db| parent_module::parent_module(db, position))
    }

    /// Returns vec of `mod name;` declaration which are created by the current module.
    pub fn child_modules(&self, position: FilePosition) -> Cancellable<Vec<NavigationTarget>> {
        self.with_db(|db| child_modules::child_modules(db, position))
    }

    /// Returns crates that this file belongs to.
    pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
        self.with_db(|db| parent_module::crates_for(db, file_id))
    }

    /// Returns crates that this file belongs to.
    pub fn transitive_rev_deps(&self, crate_id: Crate) -> Cancellable<Vec<Crate>> {
        self.with_db(|db| Vec::from_iter(crate_id.transitive_rev_deps(db)))
    }

    /// Returns crates that this file *might* belong to.
    pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
        self.with_db(|db| db.relevant_crates(file_id).iter().copied().collect())
    }

    /// Returns the edition of the given crate.
    pub fn crate_edition(&self, crate_id: Crate) -> Cancellable<Edition> {
        self.with_db(|db| crate_id.data(db).edition)
    }

    /// Returns whether the given crate is a proc macro.
    pub fn is_proc_macro_crate(&self, crate_id: Crate) -> Cancellable<bool> {
        self.with_db(|db| crate_id.data(db).is_proc_macro)
    }

    /// Returns true if this crate has `no_std` or `no_core` specified.
    pub fn is_crate_no_std(&self, crate_id: Crate) -> Cancellable<bool> {
        self.with_db(|db| crate_def_map(db, crate_id).is_no_std())
    }

    /// Returns the root file of the given crate.
    pub fn crate_root(&self, crate_id: Crate) -> Cancellable<FileId> {
        self.with_db(|db| crate_id.data(db).root_file_id)
    }

    /// Returns the set of possible targets to run for the current file.
    pub fn runnables(&self, file_id: FileId) -> Cancellable<Vec<Runnable>> {
        self.with_db(|db| runnables::runnables(db, file_id))
    }

    /// Returns the set of tests for the given file position.
    pub fn related_tests(
        &self,
        position: FilePosition,
        search_scope: Option<SearchScope>,
    ) -> Cancellable<Vec<Runnable>> {
        let search_scope = AssertUnwindSafe(search_scope);
        self.with_db(|db| {
            let _ = &search_scope;
            runnables::related_tests(db, position, search_scope.0)
        })
    }

    /// Computes all ranges to highlight for a given item in a file.
    pub fn highlight_related(
        &self,
        config: HighlightRelatedConfig,
        position: FilePosition,
    ) -> Cancellable<Option<Vec<HighlightedRange>>> {
        self.with_db(|db| {
            highlight_related::highlight_related(&Semantics::new(db), config, position)
        })
    }

    /// Computes syntax highlighting for the given file
    pub fn highlight(
        &self,
        highlight_config: HighlightConfig<'_>,
        file_id: FileId,
    ) -> Cancellable<Vec<HlRange>> {
        self.with_db(|db| syntax_highlighting::highlight(db, &highlight_config, file_id, None))
    }

    /// Computes syntax highlighting for the given file range.
    pub fn highlight_range(
        &self,
        highlight_config: HighlightConfig<'_>,
        frange: FileRange,
    ) -> Cancellable<Vec<HlRange>> {
        self.with_db(|db| {
            syntax_highlighting::highlight(
                db,
                &highlight_config,
                frange.file_id,
                Some(frange.range),
            )
        })
    }

    /// Computes syntax highlighting for the given file.
    pub fn highlight_as_html_with_config(
        &self,
        config: HighlightConfig<'_>,
        file_id: FileId,
        rainbow: bool,
    ) -> Cancellable<String> {
        self.with_db(|db| {
            syntax_highlighting::highlight_as_html_with_config(db, &config, file_id, rainbow)
        })
    }

    /// Computes syntax highlighting for the given file.
    pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancellable<String> {
        self.with_db(|db| syntax_highlighting::highlight_as_html(db, file_id, rainbow))
    }

    /// Computes completions at the given position.
    pub fn completions(
        &self,
        config: &CompletionConfig<'_>,
        position: FilePosition,
        trigger_character: Option<char>,
    ) -> Cancellable<Option<Vec<CompletionItem>>> {
        self.with_db(|db| ide_completion::completions(db, config, position, trigger_character))
    }

    /// Resolves additional completion data at the position given.
    pub fn resolve_completion_edits(
        &self,
        config: &CompletionConfig<'_>,
        position: FilePosition,
        imports: impl IntoIterator<Item = String> + std::panic::UnwindSafe,
    ) -> Cancellable<Vec<TextEdit>> {
        Ok(self
            .with_db(|db| ide_completion::resolve_completion_edits(db, config, position, imports))?
            .unwrap_or_default())
    }

    /// Computes the set of parser level diagnostics for the given file.
    pub fn syntax_diagnostics(
        &self,
        config: &DiagnosticsConfig,
        file_id: FileId,
    ) -> Cancellable<Vec<Diagnostic>> {
        self.with_db(|db| ide_diagnostics::syntax_diagnostics(db, config, file_id))
    }

    /// Computes the set of semantic diagnostics for the given file.
    pub fn semantic_diagnostics(
        &self,
        config: &DiagnosticsConfig,
        resolve: AssistResolveStrategy,
        file_id: FileId,
    ) -> Cancellable<Vec<Diagnostic>> {
        self.with_db(|db| ide_diagnostics::semantic_diagnostics(db, config, &resolve, file_id))
    }

    /// Computes the set of both syntax and semantic diagnostics for the given file.
    pub fn full_diagnostics(
        &self,
        config: &DiagnosticsConfig,
        resolve: AssistResolveStrategy,
        file_id: FileId,
    ) -> Cancellable<Vec<Diagnostic>> {
        self.with_db(|db| ide_diagnostics::full_diagnostics(db, config, &resolve, file_id))
    }

    /// Convenience function to return assists + quick fixes for diagnostics
    pub fn assists_with_fixes(
        &self,
        assist_config: &AssistConfig,
        diagnostics_config: &DiagnosticsConfig,
        resolve: AssistResolveStrategy,
        frange: FileRange,
    ) -> Cancellable<Vec<Assist>> {
        let include_fixes = match &assist_config.allowed {
            Some(it) => it.contains(&AssistKind::QuickFix),
            None => true,
        };

        self.with_db(|db| {
            let diagnostic_assists = if diagnostics_config.enabled && include_fixes {
                ide_diagnostics::full_diagnostics(db, diagnostics_config, &resolve, frange.file_id)
                    .into_iter()
                    .flat_map(|it| it.fixes.unwrap_or_default())
                    .filter(|it| it.target.intersect(frange.range).is_some())
                    .collect()
            } else {
                Vec::new()
            };
            let ssr_assists = ssr::ssr_assists(db, &resolve, frange);
            let assists = ide_assists::assists(db, assist_config, resolve, frange);

            let mut res = diagnostic_assists;
            res.extend(ssr_assists);
            res.extend(assists);

            res
        })
    }

    /// Returns the edit required to rename reference at the position to the new
    /// name.
    pub fn rename(
        &self,
        position: FilePosition,
        new_name: &str,
        config: &RenameConfig,
    ) -> Cancellable<Result<SourceChange, RenameError>> {
        self.with_db(|db| rename::rename(db, position, new_name, config))
    }

    pub fn prepare_rename(
        &self,
        position: FilePosition,
    ) -> Cancellable<Result<RangeInfo<()>, RenameError>> {
        self.with_db(|db| rename::prepare_rename(db, position))
    }

    pub fn will_rename_file(
        &self,
        file_id: FileId,
        new_name_stem: &str,
    ) -> Cancellable<Option<SourceChange>> {
        self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem))
    }

    pub fn structural_search_replace(
        &self,
        query: &str,
        parse_only: bool,
        resolve_context: FilePosition,
        selections: Vec<FileRange>,
    ) -> Cancellable<Result<SourceChange, SsrError>> {
        self.with_db(|db| {
            let rule: ide_ssr::SsrRule = query.parse()?;
            let mut match_finder =
                ide_ssr::MatchFinder::in_context(db, resolve_context, selections)?;
            match_finder.add_rule(rule)?;
            let edits = if parse_only { Default::default() } else { match_finder.edits() };
            Ok(SourceChange::from_iter(edits))
        })
    }

    pub fn annotations(
        &self,
        config: &AnnotationConfig<'_>,
        file_id: FileId,
    ) -> Cancellable<Vec<Annotation>> {
        self.with_db(|db| annotations::annotations(db, config, file_id))
    }

    pub fn resolve_annotation(
        &self,
        config: &AnnotationConfig<'_>,
        annotation: Annotation,
    ) -> Cancellable<Annotation> {
        self.with_db(|db| annotations::resolve_annotation(db, config, annotation))
    }

    pub fn move_item(
        &self,
        range: FileRange,
        direction: Direction,
    ) -> Cancellable<Option<TextEdit>> {
        self.with_db(|db| move_item::move_item(db, range, direction))
    }

    pub fn get_recursive_memory_layout(
        &self,
        position: FilePosition,
    ) -> Cancellable<Option<RecursiveMemoryLayout>> {
        self.with_db(|db| view_memory_layout(db, position))
    }

    pub fn editioned_file_id_to_vfs(&self, file_id: hir::EditionedFileId) -> FileId {
        file_id.file_id(&self.db)
    }

    /// Performs an operation on the database that may be canceled.
    ///
    /// rust-analyzer needs to be able to answer semantic questions about the
    /// code while the code is being modified. A common problem is that a
    /// long-running query is being calculated when a new change arrives.
    ///
    /// We can't just apply the change immediately: this will cause the pending
    /// query to see inconsistent state (it will observe an absence of
    /// repeatable read). So what we do is we **cancel** all pending queries
    /// before applying the change.
    ///
    /// Salsa implements cancellation by unwinding with a special value and
    /// catching it on the API boundary.
    fn with_db<F, T>(&self, f: F) -> Cancellable<T>
    where
        F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe,
    {
        // We use `attach_db_allow_change()` and not `attach_db()` because fixture injection can change the database.
        hir::attach_db_allow_change(&self.db, || Cancelled::catch(|| f(&self.db)))
    }
}

#[test]
fn analysis_is_send() {
    fn is_send<T: Send>() {}
    is_send::<Analysis>();
}
