Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/static_index.rs')
| -rw-r--r-- | crates/ide/src/static_index.rs | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index 806230544f..ab7a829bca 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -2,11 +2,13 @@ //! read-only code browsers and emitting LSIF use hir::{db::HirDatabase, Crate, Module}; -use ide_db::base_db::{FileId, SourceDatabaseExt}; +use ide_db::base_db::{FileId, FileRange, SourceDatabaseExt}; use ide_db::RootDatabase; use rustc_hash::FxHashSet; +use syntax::TextRange; +use syntax::{AstNode, SyntaxKind::*, T}; -use crate::{Analysis, Cancellable, Fold}; +use crate::{Analysis, Cancellable, Fold, HoverConfig, HoverDocFormat, HoverResult}; /// A static representation of fully analyzed source code. /// @@ -15,9 +17,15 @@ pub struct StaticIndex { pub files: Vec<StaticIndexedFile>, } +pub struct TokenStaticData { + pub range: TextRange, + pub hover: Option<HoverResult>, +} + pub struct StaticIndexedFile { pub file_id: FileId, pub folds: Vec<Fold>, + pub tokens: Vec<TokenStaticData>, } fn all_modules(db: &dyn HirDatabase) -> Vec<Module> { @@ -46,17 +54,48 @@ impl StaticIndex { let mut result_files = Vec::<StaticIndexedFile>::new(); for module in work { let file_id = module.definition_source(db).file_id.original_file(db); - if !visited_files.contains(&file_id) { - //let path = vfs.file_path(file_id); - //let path = path.as_path().unwrap(); - //let doc_id = lsif.add(Element::Vertex(Vertex::Document(Document { - // language_id: Language::Rust, - // uri: lsp_types::Url::from_file_path(path).unwrap(), - //}))); - let folds = analysis.folding_ranges(file_id)?; - result_files.push(StaticIndexedFile { file_id, folds }); - visited_files.insert(file_id); + if visited_files.contains(&file_id) { + continue; } + let folds = analysis.folding_ranges(file_id)?; + // hovers + let sema = hir::Semantics::new(db); + let tokens_or_nodes = sema.parse(file_id).syntax().clone(); + let tokens = tokens_or_nodes.descendants_with_tokens().filter_map(|x| match x { + syntax::NodeOrToken::Node(_) => None, + syntax::NodeOrToken::Token(x) => Some(x), + }); + let hover_config = + HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) }; + let tokens = tokens + .filter(|token| match token.kind() { + IDENT + | INT_NUMBER + | LIFETIME_IDENT + | T![self] + | T![super] + | T![crate] + | T!['('] + | T![')'] => true, + _ => false, + }) + .map(|token| { + let range = token.text_range(); + let hover = analysis + .hover( + &hover_config, + FileRange { + file_id, + range: TextRange::new(range.start(), range.start()), + }, + )? + .map(|x| x.info); + Ok(TokenStaticData { range, hover }) + }) + .collect::<Result<Vec<_>, _>>()?; + result_files.push(StaticIndexedFile { file_id, folds, tokens }); + // mark the file + visited_files.insert(file_id); } Ok(StaticIndex { files: result_files }) } |