1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00

fix(lsp): handle import specifier not having a trailing quote (#13074)

* fix(lsp): handle import specifier not having a trailing quote

* clean up

* Add test.
This commit is contained in:
David Sherret 2021-12-13 16:28:35 -05:00 committed by GitHub
parent a54fc7a129
commit c9d32e0581
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,6 +7,9 @@ use super::tsc;
use crate::fs_util::is_supported_ext;
use crate::fs_util::specifier_to_file_path;
use deno_ast::swc::common::BytePos;
use deno_ast::LineAndColumnIndex;
use deno_ast::SourceTextInfo;
use deno_core::normalize_path;
use deno_core::resolve_path;
use deno_core::resolve_url;
@ -93,17 +96,32 @@ async fn check_auto_config_registry(
}
}
/// Ranges from the graph for specifiers include the leading and trailing quote,
/// Ranges from the graph for specifiers include the leading and maybe trailing quote,
/// which we want to ignore when replacing text.
fn to_narrow_lsp_range(range: &deno_graph::Range) -> lsp::Range {
fn to_narrow_lsp_range(
text_info: &SourceTextInfo,
range: &deno_graph::Range,
) -> lsp::Range {
let end_byte_index = text_info.byte_index(LineAndColumnIndex {
line_index: range.end.line,
column_index: range.end.character,
});
let text_bytes = text_info.text_str().as_bytes();
let has_trailing_quote =
matches!(text_bytes[end_byte_index.0 as usize - 1], (b'"' | b'\''));
lsp::Range {
start: lsp::Position {
line: range.start.line as u32,
// skip the leading quote
character: (range.start.character + 1) as u32,
},
end: lsp::Position {
line: range.end.line as u32,
character: (range.end.character - 1) as u32,
character: if has_trailing_quote {
range.end.character - 1 // do not include it
} else {
range.end.character
} as u32,
},
}
}
@ -119,7 +137,7 @@ pub(crate) async fn get_import_completions(
) -> Option<lsp::CompletionResponse> {
let document = state_snapshot.documents.get(specifier)?;
let (text, _, range) = document.get_maybe_dependency(position)?;
let range = to_narrow_lsp_range(&range);
let range = to_narrow_lsp_range(&document.text_info(), &range);
// completions for local relative modules
if text.starts_with("./") || text.starts_with("../") {
Some(lsp::CompletionResponse::List(lsp::CompletionList {
@ -437,6 +455,7 @@ mod tests {
use crate::lsp::documents::Documents;
use crate::lsp::documents::LanguageId;
use deno_core::resolve_url;
use deno_graph::Range;
use std::collections::HashMap;
use std::path::Path;
use std::sync::Arc;
@ -679,4 +698,52 @@ mod tests {
}]
);
}
#[test]
fn test_to_narrow_lsp_range() {
let text_info = SourceTextInfo::from_string(r#""te""#.to_string());
let range = to_narrow_lsp_range(
&text_info,
&Range {
specifier: ModuleSpecifier::parse("https://deno.land").unwrap(),
start: deno_graph::Position {
line: 0,
character: 0,
},
end: deno_graph::Position {
line: 0,
character: text_info.text_str().chars().count(),
},
},
);
assert_eq!(range.start.character, 1);
assert_eq!(
range.end.character,
(text_info.text_str().chars().count() - 1) as u32
);
}
#[test]
fn test_to_narrow_lsp_range_no_trailing_quote() {
let text_info = SourceTextInfo::from_string(r#""te"#.to_string());
let range = to_narrow_lsp_range(
&text_info,
&Range {
specifier: ModuleSpecifier::parse("https://deno.land").unwrap(),
start: deno_graph::Position {
line: 0,
character: 0,
},
end: deno_graph::Position {
line: 0,
character: text_info.text_str().chars().count(),
},
},
);
assert_eq!(range.start.character, 1);
assert_eq!(
range.end.character,
text_info.text_str().chars().count() as u32
);
}
}