diff options
Diffstat (limited to 'cli/lsp/code_lens.rs')
-rw-r--r-- | cli/lsp/code_lens.rs | 128 |
1 files changed, 65 insertions, 63 deletions
diff --git a/cli/lsp/code_lens.rs b/cli/lsp/code_lens.rs index 0570ac703..6755f50d5 100644 --- a/cli/lsp/code_lens.rs +++ b/cli/lsp/code_lens.rs @@ -1,11 +1,18 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use super::analysis; +use super::config::Config; +use super::config::WorkspaceSettings; use super::language_server; +use super::text::LineIndex; use super::tsc; -use crate::ast::ParsedModule; +use super::tsc::NavigationTree; -use deno_core::error::anyhow; +use deno_ast::swc::ast; +use deno_ast::swc::common::Span; +use deno_ast::swc::visit::Node; +use deno_ast::swc::visit::Visit; +use deno_ast::swc::visit::VisitWith; +use deno_ast::ParsedSource; use deno_core::error::AnyError; use deno_core::resolve_url; use deno_core::serde::Deserialize; @@ -18,11 +25,6 @@ use regex::Regex; use std::cell::RefCell; use std::collections::HashSet; use std::rc::Rc; -use swc_common::Span; -use swc_ecmascript::ast; -use swc_ecmascript::visit::Node; -use swc_ecmascript::visit::Visit; -use swc_ecmascript::visit::VisitWith; lazy_static::lazy_static! { static ref ABSTRACT_MODIFIER: Regex = Regex::new(r"\babstract\b").unwrap(); @@ -44,24 +46,24 @@ pub struct CodeLensData { pub specifier: ModuleSpecifier, } -fn span_to_range(span: &Span, parsed_module: &ParsedModule) -> lsp::Range { - let start = parsed_module.get_location(span.lo); - let end = parsed_module.get_location(span.hi); +fn span_to_range(span: &Span, parsed_source: &ParsedSource) -> lsp::Range { + let start = parsed_source.source().line_and_column_index(span.lo); + let end = parsed_source.source().line_and_column_index(span.hi); lsp::Range { start: lsp::Position { - line: (start.line - 1) as u32, - character: start.col as u32, + line: start.line_index as u32, + character: start.column_index as u32, }, end: lsp::Position { - line: (end.line - 1) as u32, - character: end.col as u32, + line: end.line_index as u32, + character: end.column_index as u32, }, } } struct DenoTestCollector<'a> { code_lenses: Vec<lsp::CodeLens>, - parsed_module: &'a ParsedModule, + parsed_source: &'a ParsedSource, specifier: ModuleSpecifier, test_vars: HashSet<String>, } @@ -69,18 +71,18 @@ struct DenoTestCollector<'a> { impl<'a> DenoTestCollector<'a> { pub fn new( specifier: ModuleSpecifier, - parsed_module: &'a ParsedModule, + parsed_source: &'a ParsedSource, ) -> Self { Self { code_lenses: Vec::new(), - parsed_module, + parsed_source, specifier, test_vars: HashSet::new(), } } fn add_code_lens<N: AsRef<str>>(&mut self, name: N, span: &Span) { - let range = span_to_range(span, self.parsed_module); + let range = span_to_range(span, self.parsed_source); self.code_lenses.push(lsp::CodeLens { range, command: Some(lsp::Command { @@ -370,36 +372,37 @@ pub(crate) async fn resolve_code_lens( pub(crate) async fn collect( specifier: &ModuleSpecifier, - language_server: &mut language_server::Inner, + parsed_source: Option<&ParsedSource>, + config: &Config, + line_index: &LineIndex, + navigation_tree: &NavigationTree, ) -> Result<Vec<lsp::CodeLens>, AnyError> { - let mut code_lenses = collect_test(specifier, language_server)?; - code_lenses.extend(collect_tsc(specifier, language_server).await?); + let mut code_lenses = collect_test(specifier, parsed_source, config)?; + code_lenses.extend( + collect_tsc( + specifier, + &config.get_workspace_settings(), + line_index, + navigation_tree, + ) + .await?, + ); Ok(code_lenses) } fn collect_test( specifier: &ModuleSpecifier, - language_server: &mut language_server::Inner, + parsed_source: Option<&ParsedSource>, + config: &Config, ) -> Result<Vec<lsp::CodeLens>, AnyError> { - if language_server.config.specifier_code_lens_test(specifier) { - let source = language_server - .get_text_content(specifier) - .ok_or_else(|| anyhow!("Missing text content: {}", specifier))?; - let media_type = language_server - .get_media_type(specifier) - .ok_or_else(|| anyhow!("Missing media type: {}", specifier))?; - // we swallow parsed errors, as they are meaningless here. - // TODO(@kitsonk) consider caching previous code_lens results to return if - // there is a parse error to avoid issues of lenses popping in and out - if let Ok(parsed_module) = - analysis::parse_module(specifier, &source, &media_type) - { + if config.specifier_code_lens_test(specifier) { + if let Some(parsed_source) = parsed_source { let mut collector = - DenoTestCollector::new(specifier.clone(), &parsed_module); - parsed_module.module.visit_with( + DenoTestCollector::new(specifier.clone(), parsed_source); + parsed_source.module().visit_with( &ast::Invalid { - span: swc_common::DUMMY_SP, + span: deno_ast::swc::common::DUMMY_SP, }, &mut collector, ); @@ -412,13 +415,10 @@ fn collect_test( /// Return tsc navigation tree code lenses. async fn collect_tsc( specifier: &ModuleSpecifier, - language_server: &mut language_server::Inner, + workspace_settings: &WorkspaceSettings, + line_index: &LineIndex, + navigation_tree: &NavigationTree, ) -> Result<Vec<lsp::CodeLens>, AnyError> { - let workspace_settings = language_server.config.get_workspace_settings(); - let line_index = language_server - .get_line_index_sync(specifier) - .ok_or_else(|| anyhow!("Missing line index."))?; - let navigation_tree = language_server.get_navigation_tree(specifier).await?; let code_lenses = Rc::new(RefCell::new(Vec::new())); navigation_tree.walk(&|i, mp| { let mut code_lenses = code_lenses.borrow_mut(); @@ -428,7 +428,7 @@ async fn collect_tsc( let source = CodeLensSource::Implementations; match i.kind { tsc::ScriptElementKind::InterfaceElement => { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } tsc::ScriptElementKind::ClassElement | tsc::ScriptElementKind::MemberFunctionElement @@ -436,7 +436,7 @@ async fn collect_tsc( | tsc::ScriptElementKind::MemberGetAccessorElement | tsc::ScriptElementKind::MemberSetAccessorElement => { if ABSTRACT_MODIFIER.is_match(&i.kind_modifiers) { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } } _ => (), @@ -448,31 +448,31 @@ async fn collect_tsc( let source = CodeLensSource::References; if let Some(parent) = &mp { if parent.kind == tsc::ScriptElementKind::EnumElement { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } } match i.kind { tsc::ScriptElementKind::FunctionElement => { if workspace_settings.code_lens.references_all_functions { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } } tsc::ScriptElementKind::ConstElement | tsc::ScriptElementKind::LetElement | tsc::ScriptElementKind::VariableElement => { if EXPORT_MODIFIER.is_match(&i.kind_modifiers) { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } } tsc::ScriptElementKind::ClassElement => { if i.text != "<class>" { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } } tsc::ScriptElementKind::InterfaceElement | tsc::ScriptElementKind::TypeElement | tsc::ScriptElementKind::EnumElement => { - code_lenses.push(i.to_code_lens(&line_index, specifier, &source)); + code_lenses.push(i.to_code_lens(line_index, specifier, &source)); } tsc::ScriptElementKind::LocalFunctionElement | tsc::ScriptElementKind::MemberGetAccessorElement @@ -485,11 +485,8 @@ async fn collect_tsc( tsc::ScriptElementKind::ClassElement | tsc::ScriptElementKind::InterfaceElement | tsc::ScriptElementKind::TypeElement => { - code_lenses.push(i.to_code_lens( - &line_index, - specifier, - &source, - )); + code_lenses + .push(i.to_code_lens(line_index, specifier, &source)); } _ => (), } @@ -505,8 +502,10 @@ async fn collect_tsc( #[cfg(test)] mod tests { + use deno_ast::MediaType; + use deno_ast::SourceTextInfo; + use super::*; - use crate::media_type::MediaType; #[test] fn test_deno_test_collector() { @@ -519,13 +518,16 @@ mod tests { Deno.test("test b", function anotherTest() {}); "#; - let parsed_module = - analysis::parse_module(&specifier, source, &MediaType::TypeScript) - .unwrap(); + let parsed_module = crate::lsp::analysis::parse_module( + &specifier, + SourceTextInfo::from_string(source.to_string()), + MediaType::TypeScript, + ) + .unwrap(); let mut collector = DenoTestCollector::new(specifier, &parsed_module); - parsed_module.module.visit_with( + parsed_module.module().visit_with( &ast::Invalid { - span: swc_common::DUMMY_SP, + span: deno_ast::swc::common::DUMMY_SP, }, &mut collector, ); |