summaryrefslogtreecommitdiff
path: root/cli/lsp/code_lens.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2021-09-07 10:39:32 -0400
committerGitHub <noreply@github.com>2021-09-07 10:39:32 -0400
commit2c2e3ec1ca47803f791ea72ea6247d8eedf87ec8 (patch)
tree9ba3ddfde58f4a4feaf98fc230ec18861891c9be /cli/lsp/code_lens.rs
parenta5bcf7033e66a828dc88a313f4cca11f116c3f83 (diff)
refactor(lsp): use deno_ast and cache swc ASTs (#11780)
Diffstat (limited to 'cli/lsp/code_lens.rs')
-rw-r--r--cli/lsp/code_lens.rs128
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,
);