analyzed-ra 0.4.2

Patched rust-analyzer bridge crate for analyzed
Documentation
use std::time::Duration;

use ide::{Cancellable, FileId};
use ide_db::base_db::{AnchoredPathBuf, Crate};
use lsp_types::Uri;
use vfs::VfsPath;

use crate::{
    global_state::{GlobalState, GlobalStateSnapshot},
    line_index::LineIndex,
    lsp::to_proto::url_from_abs_path,
    target_spec::TargetSpec,
};

impl GlobalState {
    pub(crate) fn new(
        sender: crossbeam_channel::Sender<lsp_server::Message>,
        config: crate::config::Config,
    ) -> Self {
        let registry = crate::shared_analyzer::shared_analyzer_registry();
        let provider = crate::shared_analyzer::SharedAnalyzerProvider::new(
            move |key, config, reload_path| registry.register(key, config, reload_path),
        );
        let (key, shared_config) = crate::shared_analyzer::shared_analyzer_context_from_config(&config)
            .expect("global state config must describe a shared analyzer context");
        let session = provider
            .resolve(key, shared_config)
            .expect("shared analyzer context must resolve");
        Self::new_with_shared(sender, config, provider, session.runtime(), Vec::new())
    }

    pub(crate) fn process_changes(&mut self) -> (bool, Option<Duration>) {
        let _p = tracing::span!(tracing::Level::INFO, "GlobalState::process_changes").entered();
        self.process_shared_changes()
    }
}

impl GlobalStateSnapshot {
    pub(crate) fn url_to_file_id(&self, url: &Uri) -> anyhow::Result<Option<FileId>> {
        self.shared.url_to_file_id(url)
    }

    pub(crate) fn file_id_to_url(&self, id: FileId) -> Uri {
        self.shared.file_id_to_url(id).expect("shared analyzer file id must have a url")
    }

    pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result<Option<FileId>> {
        self.shared.vfs_path_to_file_id(vfs_path)
    }

    pub(crate) fn base_vfs_path_to_file_id(
        &self,
        vfs_path: &VfsPath,
    ) -> anyhow::Result<Option<FileId>> {
        self.shared.base_vfs_path_to_file_id(vfs_path)
    }

    pub(crate) fn file_line_index(&self, id: FileId) -> Cancellable<LineIndex> {
        let endings = self.shared.line_endings(id).expect("shared line endings");
        let index = self.analysis.file_line_index(id)?;
        let encoding = self.config.caps().negotiated_encoding();
        Ok(LineIndex { index, endings, encoding })
    }

    pub(crate) fn file_version(&self, id: FileId) -> Option<i32> {
        let path = self.file_id_to_file_path(id);
        Some(self.mem_docs.get(&path)?.version)
    }

    pub(crate) fn anchored_path(&self, anchored: &AnchoredPathBuf) -> Uri {
        let mut anchor = self.file_id_to_file_path(anchored.anchor);
        anchor.pop();
        url_from_abs_path(anchor.join(&anchored.path).unwrap().as_path().unwrap())
    }

    pub(crate) fn file_id_to_file_path(&self, id: FileId) -> vfs::VfsPath {
        self.shared
            .file_id_to_vfs_path(id)
            .unwrap_or_else(|| panic!("shared analyzer file id {id:?} must have a path"))
    }

    pub(crate) fn file_exists(&self, id: FileId) -> bool {
        self.shared.file_exists(id).unwrap_or(false)
    }

    pub(crate) fn target_spec_for_file(
        &self,
        file_id: FileId,
        crate_id: Crate,
    ) -> Option<TargetSpec> {
        let path = self.file_id_to_file_path(file_id);
        let path = path.as_path()?;
        self.target_spec_from_workspaces(path, crate_id)
    }
}