diff options
Diffstat (limited to 'support/texlab/src/features/reference')
-rw-r--r-- | support/texlab/src/features/reference/entry.rs | 72 | ||||
-rw-r--r-- | support/texlab/src/features/reference/label.rs | 55 | ||||
-rw-r--r-- | support/texlab/src/features/reference/string.rs | 47 |
3 files changed, 99 insertions, 75 deletions
diff --git a/support/texlab/src/features/reference/entry.rs b/support/texlab/src/features/reference/entry.rs index a9e15ba5b6..f245b6eb8d 100644 --- a/support/texlab/src/features/reference/entry.rs +++ b/support/texlab/src/features/reference/entry.rs @@ -1,15 +1,17 @@ -use cancellation::CancellationToken; use lsp_types::{Location, ReferenceParams}; +use rowan::ast::AstNode; use crate::{ features::cursor::CursorContext, - syntax::{bibtex, latex, CstNode}, + syntax::{ + bibtex::{self, HasName}, + latex, + }, DocumentData, LineIndexExt, }; pub fn find_entry_references( context: &CursorContext<ReferenceParams>, - cancellation_token: &CancellationToken, references: &mut Vec<Location>, ) -> Option<()> { let (key_text, _) = context @@ -17,31 +19,33 @@ pub fn find_entry_references( .or_else(|| context.find_citation_key_command()) .or_else(|| context.find_entry_key())?; - for document in &context.request.subset.documents { - cancellation_token.result().ok()?; - + for document in context.request.workspace.documents_by_uri.values() { match &document.data { DocumentData::Latex(data) => { - data.root + latex::SyntaxNode::new_root(data.green.clone()) .descendants() .filter_map(latex::Citation::cast) .filter_map(|citation| citation.key_list()) .flat_map(|keys| keys.keys()) .filter(|key| key.to_string() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.small_range())) + .map(|key| { + document + .line_index + .line_col_lsp_range(latex::small_range(&key)) + }) .for_each(|range| { - references.push(Location::new(document.uri.as_ref().clone().into(), range)); + references.push(Location::new(document.uri.as_ref().clone(), range)); }); } DocumentData::Bibtex(data) if context.request.params.context.include_declaration => { - data.root + bibtex::SyntaxNode::new_root(data.green.clone()) .children() .filter_map(bibtex::Entry::cast) - .filter_map(|entry| entry.key()) - .filter(|key| key.to_string() == key_text) - .map(|key| document.line_index.line_col_lsp_range(key.small_range())) + .filter_map(|entry| entry.name_token()) + .filter(|key| key.text() == key_text) + .map(|key| document.line_index.line_col_lsp_range(key.text_range())) .for_each(|range| { - references.push(Location::new(document.uri.as_ref().clone().into(), range)); + references.push(Location::new(document.uri.as_ref().clone(), range)); }); } DocumentData::Bibtex(_) | DocumentData::BuildLog(_) => {} @@ -58,6 +62,14 @@ mod tests { use super::*; + fn sort_references(actual_references: &mut [Location]) { + actual_references.sort_by(|a, b| { + a.uri + .cmp(&b.uri) + .then_with(|| a.range.start.cmp(&b.range.start)) + }); + } + #[test] fn test_empty_latex_document() { let request = FeatureTester::builder() @@ -70,7 +82,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } @@ -87,7 +99,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } @@ -108,10 +120,11 @@ mod tests { let request = tester.reference(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![Location::new( - uri.as_ref().clone().into(), + uri.as_ref().clone(), Range::new_simple(0, 6, 0, 9), )]; assert_eq!(actual_references, expected_references); @@ -129,17 +142,18 @@ mod tests { .character(11) .include_declaration(true) .build(); - let uri1 = tester.uri("foo.bib"); - let uri2 = tester.uri("bar.tex"); + let uri1 = tester.uri("bar.tex"); + let uri2 = tester.uri("foo.bib"); let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![ - Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 9, 0, 12)), - Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 6, 0, 9)), + Location::new(uri1.as_ref().clone(), Range::new_simple(0, 6, 0, 9)), + Location::new(uri2.as_ref().clone(), Range::new_simple(0, 9, 0, 12)), ]; assert_eq!(actual_references, expected_references); } @@ -160,10 +174,11 @@ mod tests { let request = tester.reference(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![Location::new( - uri.as_ref().clone().into(), + uri.as_ref().clone(), Range::new_simple(0, 6, 0, 9), )]; assert_eq!(actual_references, expected_references); @@ -187,11 +202,12 @@ mod tests { let request = tester.reference(); let context = CursorContext::new(request); - find_entry_references(&context, CancellationToken::none(), &mut actual_references); + find_entry_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![ - Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 6, 0, 9)), - Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 9, 0, 12)), + Location::new(uri2.as_ref().clone(), Range::new_simple(0, 6, 0, 9)), + Location::new(uri1.as_ref().clone(), Range::new_simple(0, 9, 0, 12)), ]; assert_eq!(actual_references, expected_references); } diff --git a/support/texlab/src/features/reference/label.rs b/support/texlab/src/features/reference/label.rs index 45c6b90137..2fc3efc398 100644 --- a/support/texlab/src/features/reference/label.rs +++ b/support/texlab/src/features/reference/label.rs @@ -1,22 +1,17 @@ -use cancellation::CancellationToken; use lsp_types::{Location, ReferenceParams}; use crate::{features::cursor::CursorContext, LineIndexExt}; pub fn find_label_references( context: &CursorContext<ReferenceParams>, - cancellation_token: &CancellationToken, references: &mut Vec<Location>, ) -> Option<()> { - cancellation_token.result().ok()?; - let (name_text, _) = context .find_label_name_key() .or_else(|| context.find_label_name_command())?; - for document in &context.request.subset.documents { + for document in context.request.workspace.documents_by_uri.values() { if let Some(data) = document.data.as_latex() { - cancellation_token.result().ok()?; for name in data .extras .label_names @@ -27,7 +22,7 @@ pub fn find_label_references( }) { references.push(Location::new( - document.uri.as_ref().clone().into(), + document.uri.as_ref().clone(), document.line_index.line_col_lsp_range(name.range), )); } @@ -45,6 +40,14 @@ mod tests { use super::*; + fn sort_references(actual_references: &mut [Location]) { + actual_references.sort_by(|a, b| { + a.uri + .cmp(&b.uri) + .then_with(|| a.range.start.cmp(&b.range.start)) + }); + } + #[test] fn test_definition() { let tester = FeatureTester::builder() @@ -61,10 +64,11 @@ mod tests { let request = tester.reference(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![Location::new( - uri.as_ref().clone().into(), + uri.as_ref().clone(), Range::new_simple(0, 5, 0, 8), )]; assert_eq!(actual_references, expected_references); @@ -82,17 +86,18 @@ mod tests { .character(9) .include_declaration(true) .build(); - let uri1 = tester.uri("foo.tex"); - let uri2 = tester.uri("bar.tex"); + let uri1 = tester.uri("bar.tex"); + let uri2 = tester.uri("foo.tex"); let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![ - Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 7, 0, 10)), - Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)), + Location::new(uri1.as_ref().clone(), Range::new_simple(0, 5, 0, 8)), + Location::new(uri2.as_ref().clone(), Range::new_simple(0, 7, 0, 10)), ]; assert_eq!(actual_references, expected_references); } @@ -115,11 +120,12 @@ mod tests { let request = tester.reference(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![ - Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)), - Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)), + Location::new(uri1.as_ref().clone(), Range::new_simple(0, 5, 0, 8)), + Location::new(uri2.as_ref().clone(), Range::new_simple(0, 5, 0, 8)), ]; assert_eq!(actual_references, expected_references); } @@ -136,17 +142,18 @@ mod tests { .character(7) .include_declaration(true) .build(); - let uri1 = tester.uri("foo.tex"); - let uri2 = tester.uri("bar.tex"); + let uri1 = tester.uri("bar.tex"); + let uri2 = tester.uri("foo.tex"); let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); + sort_references(&mut actual_references); let expected_references = vec![ - Location::new(uri2.as_ref().clone().into(), Range::new_simple(0, 5, 0, 8)), - Location::new(uri1.as_ref().clone().into(), Range::new_simple(0, 7, 0, 10)), + Location::new(uri1.as_ref().clone(), Range::new_simple(0, 5, 0, 8)), + Location::new(uri2.as_ref().clone(), Range::new_simple(0, 7, 0, 10)), ]; assert_eq!(actual_references, expected_references); } @@ -163,7 +170,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } @@ -180,7 +187,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_label_references(&context, CancellationToken::none(), &mut actual_references); + find_label_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } diff --git a/support/texlab/src/features/reference/string.rs b/support/texlab/src/features/reference/string.rs index b7dd4e039a..c957244a53 100644 --- a/support/texlab/src/features/reference/string.rs +++ b/support/texlab/src/features/reference/string.rs @@ -1,41 +1,42 @@ -use cancellation::CancellationToken; use lsp_types::{Location, ReferenceParams}; +use rowan::ast::AstNode; use crate::{ features::cursor::CursorContext, - syntax::{bibtex, CstNode}, + syntax::bibtex::{self, HasName}, LineIndexExt, }; pub fn find_string_references( context: &CursorContext<ReferenceParams>, - cancellation_token: &CancellationToken, items: &mut Vec<Location>, ) -> Option<()> { let name_text = context .cursor .as_bibtex() - .filter(|token| token.kind() == bibtex::WORD) - .filter(|token| matches!(token.parent().kind(), bibtex::TOKEN | bibtex::STRING))? + .filter(|token| { + let parent = token.parent().unwrap(); + (token.kind() == bibtex::NAME && bibtex::Value::can_cast(parent.kind())) + || (token.kind() == bibtex::NAME && bibtex::StringDef::can_cast(parent.kind())) + })? .text(); let document = context.request.main_document(); let data = document.data.as_bibtex()?; - for node in data.root.descendants() { - cancellation_token.result().ok()?; - if let Some(name) = bibtex::String::cast(node) - .and_then(|string| string.name()) + for node in bibtex::SyntaxNode::new_root(data.green.clone()).descendants() { + if let Some(name) = bibtex::StringDef::cast(node.clone()) + .and_then(|string| string.name_token()) .filter(|name| { context.request.params.context.include_declaration && name.text() == name_text }) .or_else(|| { - bibtex::Token::cast(node) + bibtex::Value::cast(node) .and_then(|token| token.syntax().first_token()) .filter(|name| name.text() == name_text) }) { items.push(Location::new( - document.uri.as_ref().clone().into(), + document.uri.as_ref().clone(), document.line_index.line_col_lsp_range(name.text_range()), )); } @@ -72,10 +73,10 @@ mod tests { let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); let expected_references = vec![Location::new( - uri.as_ref().clone().into(), + uri.as_ref().clone(), Range::new_simple(2, 23, 2, 26), )]; assert_eq!(actual_references, expected_references); @@ -102,11 +103,11 @@ mod tests { let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); let expected_references = vec![ - Location::new(uri.as_ref().clone().into(), Range::new_simple(0, 8, 0, 11)), - Location::new(uri.as_ref().clone().into(), Range::new_simple(2, 23, 2, 26)), + Location::new(uri.as_ref().clone(), Range::new_simple(0, 8, 0, 11)), + Location::new(uri.as_ref().clone(), Range::new_simple(2, 23, 2, 26)), ]; assert_eq!(actual_references, expected_references); } @@ -131,10 +132,10 @@ mod tests { let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); let expected_references = vec![Location::new( - uri.as_ref().clone().into(), + uri.as_ref().clone(), Range::new_simple(2, 23, 2, 26), )]; assert_eq!(actual_references, expected_references); @@ -161,11 +162,11 @@ mod tests { let mut actual_references = Vec::new(); let request = tester.reference(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); let expected_references = vec![ - Location::new(uri.as_ref().clone().into(), Range::new_simple(0, 8, 0, 11)), - Location::new(uri.as_ref().clone().into(), Range::new_simple(2, 23, 2, 26)), + Location::new(uri.as_ref().clone(), Range::new_simple(0, 8, 0, 11)), + Location::new(uri.as_ref().clone(), Range::new_simple(2, 23, 2, 26)), ]; assert_eq!(actual_references, expected_references); } @@ -182,7 +183,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } @@ -199,7 +200,7 @@ mod tests { let mut actual_references = Vec::new(); let context = CursorContext::new(request); - find_string_references(&context, CancellationToken::none(), &mut actual_references); + find_string_references(&context, &mut actual_references); assert!(actual_references.is_empty()); } |