mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Rejigger workspace symbols for more efficient caching
In effect, we make the Salsa query aspect keyed only on whether we want global symbols. We move everything else (hierarchical and querying) to an aggregate step *after* the query. This was a somewhat involved change since we want to return a flattened list from visiting the source while also preserving enough information to reform the symbols into a hierarchical structure that the LSP expects. But I think overall the API has gotten simpler and we encode more invariants into the type system. (For example, previously you got a runtime assertion if you tried to provide a query string while enabling hierarchical mode. But now that's prevented by construction.)
This commit is contained in:
parent
f407f12f4c
commit
205eae14d2
8 changed files with 317 additions and 164 deletions
|
@ -1,29 +1,16 @@
|
|||
use crate::symbols::{SymbolInfo, SymbolsOptions, symbols_for_file};
|
||||
use crate::symbols::{FlatSymbols, symbols_for_file};
|
||||
use ruff_db::files::File;
|
||||
use ty_project::Db;
|
||||
|
||||
/// Get all document symbols for a file with the given options.
|
||||
pub fn document_symbols_with_options(
|
||||
db: &dyn Db,
|
||||
file: File,
|
||||
options: &SymbolsOptions,
|
||||
) -> Vec<SymbolInfo> {
|
||||
symbols_for_file(db, file, options).cloned().collect()
|
||||
}
|
||||
|
||||
/// Get all document symbols for a file (hierarchical by default).
|
||||
pub fn document_symbols(db: &dyn Db, file: File) -> Vec<SymbolInfo> {
|
||||
let options = SymbolsOptions {
|
||||
hierarchical: true,
|
||||
global_only: false,
|
||||
query_string: None,
|
||||
};
|
||||
document_symbols_with_options(db, file, &options)
|
||||
pub fn document_symbols(db: &dyn Db, file: File) -> &FlatSymbols {
|
||||
symbols_for_file(db, file)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::symbols::{HierarchicalSymbols, SymbolId, SymbolInfo};
|
||||
use crate::tests::{CursorTest, IntoDiagnostic, cursor_test};
|
||||
use insta::assert_snapshot;
|
||||
use ruff_db::diagnostic::{
|
||||
|
@ -324,42 +311,45 @@ class OuterClass:
|
|||
|
||||
impl CursorTest {
|
||||
fn document_symbols(&self) -> String {
|
||||
let symbols = document_symbols(&self.db, self.cursor.file);
|
||||
let symbols = document_symbols(&self.db, self.cursor.file).to_hierarchical();
|
||||
|
||||
if symbols.is_empty() {
|
||||
return "No symbols found".to_string();
|
||||
}
|
||||
|
||||
self.render_diagnostics(
|
||||
symbols
|
||||
.into_iter()
|
||||
.flat_map(|symbol| symbol_to_diagnostics(symbol, self.cursor.file)),
|
||||
)
|
||||
self.render_diagnostics(symbols.iter().flat_map(|(id, symbol)| {
|
||||
symbol_to_diagnostics(&symbols, id, symbol, self.cursor.file)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_to_diagnostics(symbol: SymbolInfo, file: File) -> Vec<DocumentSymbolDiagnostic> {
|
||||
fn symbol_to_diagnostics<'db>(
|
||||
symbols: &'db HierarchicalSymbols,
|
||||
id: SymbolId,
|
||||
symbol: SymbolInfo<'db>,
|
||||
file: File,
|
||||
) -> Vec<DocumentSymbolDiagnostic<'db>> {
|
||||
// Output the symbol and recursively output all child symbols
|
||||
let mut diagnostics = vec![DocumentSymbolDiagnostic::new(symbol.clone(), file)];
|
||||
let mut diagnostics = vec![DocumentSymbolDiagnostic::new(symbol, file)];
|
||||
|
||||
for child in symbol.children {
|
||||
diagnostics.extend(symbol_to_diagnostics(child, file));
|
||||
for (child_id, child) in symbols.children(id) {
|
||||
diagnostics.extend(symbol_to_diagnostics(symbols, child_id, child, file));
|
||||
}
|
||||
|
||||
diagnostics
|
||||
}
|
||||
struct DocumentSymbolDiagnostic {
|
||||
symbol: SymbolInfo,
|
||||
struct DocumentSymbolDiagnostic<'db> {
|
||||
symbol: SymbolInfo<'db>,
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl DocumentSymbolDiagnostic {
|
||||
fn new(symbol: SymbolInfo, file: File) -> Self {
|
||||
impl<'db> DocumentSymbolDiagnostic<'db> {
|
||||
fn new(symbol: SymbolInfo<'db>, file: File) -> Self {
|
||||
Self { symbol, file }
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic for DocumentSymbolDiagnostic {
|
||||
impl IntoDiagnostic for DocumentSymbolDiagnostic<'_> {
|
||||
fn into_diagnostic(self) -> Diagnostic {
|
||||
let symbol_kind_str = self.symbol.kind.to_string();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue