Use the common workspace symbol logic

This commit is contained in:
Shuhei Takahashi 2025-12-15 23:10:12 +09:00
parent 179b7ab5dc
commit 49dcded846
4 changed files with 28 additions and 24 deletions

View file

@ -194,17 +194,7 @@ impl WorkspaceAnalyzer {
&self.indexed
}
pub fn cached_files_for_symbols(&self) -> Vec<Arc<AnalyzedFile>> {
self.cache
.read()
.unwrap()
.values()
.filter_map(|entry| entry.lock().unwrap().clone())
.filter(|file| !file.external)
.collect()
}
pub fn cached_files_for_references(&self) -> Vec<Arc<AnalyzedFile>> {
pub fn cached_files(&self) -> Vec<Arc<AnalyzedFile>> {
self.cache
.read()
.unwrap()

View file

@ -17,14 +17,15 @@ use std::path::Path;
use itertools::Itertools;
use tower_lsp::lsp_types::{
CodeAction, CodeActionKind, CodeActionOrCommand, CodeActionParams, CodeActionResponse, Command,
Diagnostic, NumberOrString, WorkspaceEdit,
Diagnostic, NumberOrString, SymbolKind, WorkspaceEdit,
};
use crate::{
common::{error::Result, utils::format_path},
diagnostics::{DiagnosticDataUndefined, DIAGNOSTIC_CODE_UNDEFINED},
server::{
imports::create_import_edit, providers::utils::get_text_document_path, RequestContext,
imports::create_import_edit, providers::utils::get_text_document_path,
symbols::collect_workspace_symbols, RequestContext,
},
};
@ -39,7 +40,7 @@ struct ImportCandidate {
pub edit: WorkspaceEdit,
}
fn compute_import_actions(
async fn compute_import_actions(
context: &RequestContext,
path: &Path,
name: &str,
@ -49,13 +50,23 @@ fn compute_import_actions(
return Vec::new();
};
let current_file = workspace.analyze_file(path, context.request_time);
let workspace_files = workspace.cached_files_for_symbols();
let imports: Vec<String> = workspace_files
let symbols = collect_workspace_symbols(&workspace).await;
let imports: Vec<String> = symbols
.into_iter()
.filter(|file| file.exports.get().variables.contains_key(name))
.map(|file| format_path(&file.document.path, &file.workspace_root))
.filter(|symbol| {
symbol.name == name
&& matches!(symbol.kind, SymbolKind::VARIABLE | SymbolKind::CONSTANT)
})
.map(|symbol| {
format_path(
&symbol.location.uri.to_file_path().unwrap(),
&workspace.context().root,
)
})
.sorted()
.collect();
if imports.is_empty() {
return Vec::new();
}
@ -114,9 +125,8 @@ pub async fn code_action(
else {
continue;
};
actions.extend(compute_import_actions(
context, &path, &data.name, diagnostic,
));
actions
.extend(compute_import_actions(context, &path, &data.name, diagnostic).await);
}
_ => {}
}

View file

@ -37,7 +37,7 @@ pub fn target_references(
) -> Result<Vec<Location>> {
let bad_prefixes = get_overlapping_targets(current_file.analyzed_root.get(), target_name);
let cached_files = workspace.cached_files_for_references();
let cached_files = workspace.cached_files();
let mut references: Vec<Location> = Vec::new();
for file in cached_files {

View file

@ -15,7 +15,10 @@
use either::Either;
use tower_lsp::lsp_types::{Location, SymbolInformation, SymbolKind, Url};
use crate::analyzer::{AnalyzedFile, Analyzer, WorkspaceAnalyzer};
use crate::{
analyzer::{AnalyzedFile, Analyzer, WorkspaceAnalyzer},
common::utils::is_good_for_scan,
};
pub async fn collect_global_symbols(analyzer: &Analyzer) -> Vec<SymbolInformation> {
let workspaces = analyzer.workspaces();
@ -29,9 +32,10 @@ pub async fn collect_global_symbols(analyzer: &Analyzer) -> Vec<SymbolInformatio
pub async fn collect_workspace_symbols(workspace: &WorkspaceAnalyzer) -> Vec<SymbolInformation> {
workspace.indexed().wait().await;
let files = workspace.cached_files_for_symbols();
let files = workspace.cached_files();
files
.into_iter()
.filter(|file| !file.external && is_good_for_scan(&file.document.path))
.flat_map(|file| extract_symbols(&file))
.collect()
}