Unnamed repository; edit this file 'description' to name the repository.
scip: Rewrite tests to be closer to what we actually do.
It's also less code.
Emilio Cobos Álvarez 2022-10-22
parent 7ee7225 · commit ec6d72b
-rw-r--r--crates/rust-analyzer/src/cli/scip.rs85
1 files changed, 30 insertions, 55 deletions
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index d70bc3f195..8b77ccde0e 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -8,8 +8,8 @@ use std::{
use crate::line_index::{LineEndings, LineIndex, OffsetEncoding};
use hir::Name;
use ide::{
- LineCol, MonikerDescriptorKind, MonikerResult, StaticIndex, StaticIndexedFile, TextRange,
- TokenId,
+ LineCol, MonikerDescriptorKind, StaticIndex, StaticIndexedFile, TextRange, TokenId,
+ TokenStaticData,
};
use ide_db::LineIndexDatabase;
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
@@ -109,10 +109,7 @@ impl flags::Scip {
occurrence.symbol = tokens_to_symbol
.entry(id)
.or_insert_with(|| {
- let symbol = match &token.moniker {
- Some(moniker) => moniker_to_symbol(&moniker),
- None => new_local_symbol(),
- };
+ let symbol = token_to_symbol(&token).unwrap_or_else(&mut new_local_symbol);
scip::symbol::format_symbol(symbol)
})
.clone();
@@ -201,9 +198,11 @@ fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_ty
///
/// Only returns a Symbol when it's a non-local symbol.
/// So if the visibility isn't outside of a document, then it will return None
-fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
+fn token_to_symbol(token: &TokenStaticData) -> Option<scip_types::Symbol> {
use scip_types::descriptor::Suffix::*;
+ let moniker = token.moniker.as_ref()?;
+
let package_name = moniker.package_information.name.clone();
let version = moniker.package_information.version.clone();
let descriptors = moniker
@@ -227,7 +226,7 @@ fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
})
.collect();
- scip_types::Symbol {
+ Some(scip_types::Symbol {
scheme: "rust-analyzer".into(),
package: Some(scip_types::Package {
manager: "cargo".to_string(),
@@ -238,19 +237,15 @@ fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
.into(),
descriptors,
..Default::default()
- }
+ })
}
#[cfg(test)]
mod test {
use super::*;
- use hir::Semantics;
- use ide::{AnalysisHost, FilePosition};
- use ide_db::defs::IdentClass;
- use ide_db::{base_db::fixture::ChangeFixture, helpers::pick_best_token};
+ use ide::{AnalysisHost, FilePosition, StaticIndex, TextSize};
+ use ide_db::base_db::fixture::ChangeFixture;
use scip::symbol::format_symbol;
- use syntax::SyntaxKind::*;
- use syntax::{AstNode, T};
fn position(ra_fixture: &str) -> (AnalysisHost, FilePosition) {
let mut host = AnalysisHost::default();
@@ -267,53 +262,33 @@ mod test {
fn check_symbol(ra_fixture: &str, expected: &str) {
let (host, position) = position(ra_fixture);
+ let analysis = host.analysis();
+ let si = StaticIndex::compute(&analysis);
+
let FilePosition { file_id, offset } = position;
- let db = host.raw_database();
- let sema = &Semantics::new(db);
- let file = sema.parse(file_id).syntax().clone();
- let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
- IDENT
- | INT_NUMBER
- | LIFETIME_IDENT
- | T![self]
- | T![super]
- | T![crate]
- | T![Self]
- | COMMENT => 2,
- kind if kind.is_trivia() => 0,
- _ => 1,
- })
- .expect("OK OK");
-
- let navs = sema
- .descend_into_macros(original_token.clone())
- .into_iter()
- .filter_map(|token| {
- IdentClass::classify_token(sema, &token).map(IdentClass::definitions).map(|it| {
- it.into_iter().flat_map(|def| {
- let module = def.module(db).unwrap();
- let current_crate = module.krate();
-
- match MonikerResult::from_def(sema.db, def, current_crate) {
- Some(moniker_result) => Some(moniker_to_symbol(&moniker_result)),
- None => None,
- }
- })
- })
- })
- .flatten()
- .collect::<Vec<_>>();
+ let mut found_symbol = None;
+ for file in &si.files {
+ if file.file_id != file_id {
+ continue;
+ }
+ for &(range, id) in &file.tokens {
+ if range.contains(offset - TextSize::from(1)) {
+ let token = si.tokens.get(id).unwrap();
+ found_symbol = token_to_symbol(token);
+ break;
+ }
+ }
+ }
if expected == "" {
- assert_eq!(0, navs.len(), "must have no symbols {:?}", navs);
+ assert!(found_symbol.is_none(), "must have no symbols {:?}", found_symbol);
return;
}
- assert_eq!(1, navs.len(), "must have one symbol {:?}", navs);
-
- let res = navs.get(0).unwrap();
- let formatted = format_symbol(res.clone());
+ assert!(found_symbol.is_some(), "must have one symbol {:?}", found_symbol);
+ let res = found_symbol.unwrap();
+ let formatted = format_symbol(res);
assert_eq!(formatted, expected);
}