summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/doc/class.rs21
-rw-r--r--cli/doc/interface.rs12
-rw-r--r--cli/doc/module.rs5
-rw-r--r--cli/doc/namespace.rs4
-rw-r--r--cli/doc/parser.rs150
-rw-r--r--cli/lib.rs1
-rw-r--r--cli/swc_util.rs164
7 files changed, 204 insertions, 153 deletions
diff --git a/cli/doc/class.rs b/cli/doc/class.rs
index 004be9e74..c4603972b 100644
--- a/cli/doc/class.rs
+++ b/cli/doc/class.rs
@@ -118,7 +118,7 @@ pub fn get_doc_for_class_decl(
Constructor(ctor) => {
let ctor_js_doc = doc_parser.js_doc_for_span(ctor.span());
let constructor_name =
- prop_name_to_string(&doc_parser.source_map, &ctor.key);
+ prop_name_to_string(&doc_parser.ast_parser.source_map, &ctor.key);
let mut params = vec![];
@@ -146,17 +146,16 @@ pub fn get_doc_for_class_decl(
accessibility: ctor.accessibility,
name: constructor_name,
params,
- location: doc_parser
- .source_map
- .lookup_char_pos(ctor.span.lo())
- .into(),
+ location: doc_parser.ast_parser.get_span_location(ctor.span).into(),
};
constructors.push(constructor_def);
}
Method(class_method) => {
let method_js_doc = doc_parser.js_doc_for_span(class_method.span());
- let method_name =
- prop_name_to_string(&doc_parser.source_map, &class_method.key);
+ let method_name = prop_name_to_string(
+ &doc_parser.ast_parser.source_map,
+ &class_method.key,
+ );
let fn_def = function_to_function_def(&class_method.function);
let method_def = ClassMethodDef {
js_doc: method_js_doc,
@@ -168,8 +167,8 @@ pub fn get_doc_for_class_decl(
kind: class_method.kind,
function_def: fn_def,
location: doc_parser
- .source_map
- .lookup_char_pos(class_method.span.lo())
+ .ast_parser
+ .get_span_location(class_method.span)
.into(),
};
methods.push(method_def);
@@ -198,8 +197,8 @@ pub fn get_doc_for_class_decl(
accessibility: class_prop.accessibility,
name: prop_name,
location: doc_parser
- .source_map
- .lookup_char_pos(class_prop.span.lo())
+ .ast_parser
+ .get_span_location(class_prop.span)
.into(),
};
properties.push(prop_def);
diff --git a/cli/doc/interface.rs b/cli/doc/interface.rs
index dd9acc650..fb7a2c853 100644
--- a/cli/doc/interface.rs
+++ b/cli/doc/interface.rs
@@ -114,8 +114,8 @@ pub fn get_doc_for_ts_interface_decl(
name,
js_doc: method_js_doc,
location: doc_parser
- .source_map
- .lookup_char_pos(ts_method_sig.span.lo())
+ .ast_parser
+ .get_span_location(ts_method_sig.span)
.into(),
optional: ts_method_sig.optional,
params,
@@ -151,8 +151,8 @@ pub fn get_doc_for_ts_interface_decl(
name,
js_doc: prop_js_doc,
location: doc_parser
- .source_map
- .lookup_char_pos(ts_prop_sig.span.lo())
+ .ast_parser
+ .get_span_location(ts_prop_sig.span)
.into(),
params,
ts_type,
@@ -183,8 +183,8 @@ pub fn get_doc_for_ts_interface_decl(
let call_sig_def = InterfaceCallSignatureDef {
js_doc: call_sig_js_doc,
location: doc_parser
- .source_map
- .lookup_char_pos(ts_call_sig.span.lo())
+ .ast_parser
+ .get_span_location(ts_call_sig.span)
.into(),
params,
ts_type,
diff --git a/cli/doc/module.rs b/cli/doc/module.rs
index d2284b36c..2de9c7ca8 100644
--- a/cli/doc/module.rs
+++ b/cli/doc/module.rs
@@ -14,10 +14,7 @@ pub fn get_doc_node_for_export_decl(
use crate::swc_ecma_ast::Decl;
let js_doc = doc_parser.js_doc_for_span(export_span);
- let location = doc_parser
- .source_map
- .lookup_char_pos(export_span.lo())
- .into();
+ let location = doc_parser.ast_parser.get_span_location(export_span).into();
match &export_decl.decl {
Decl::Class(class_decl) => {
diff --git a/cli/doc/namespace.rs b/cli/doc/namespace.rs
index 02f22b661..6cbc619e8 100644
--- a/cli/doc/namespace.rs
+++ b/cli/doc/namespace.rs
@@ -17,8 +17,8 @@ pub fn get_doc_for_ts_namespace_decl(
) -> DocNode {
let js_doc = doc_parser.js_doc_for_span(ts_namespace_decl.span);
let location = doc_parser
- .source_map
- .lookup_char_pos(ts_namespace_decl.span.lo())
+ .ast_parser
+ .get_span_location(ts_namespace_decl.span)
.into();
let namespace_name = ts_namespace_decl.id.sym.to_string();
diff --git a/cli/doc/parser.rs b/cli/doc/parser.rs
index 35694aa9a..2a15daa59 100644
--- a/cli/doc/parser.rs
+++ b/cli/doc/parser.rs
@@ -1,39 +1,20 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::op_error::OpError;
-use crate::swc_common;
use crate::swc_common::comments::CommentKind;
-use crate::swc_common::comments::Comments;
-use crate::swc_common::errors::Diagnostic;
-use crate::swc_common::errors::DiagnosticBuilder;
-use crate::swc_common::errors::Emitter;
-use crate::swc_common::errors::Handler;
-use crate::swc_common::errors::HandlerFlags;
-use crate::swc_common::FileName;
-use crate::swc_common::Globals;
-use crate::swc_common::SourceMap;
use crate::swc_common::Span;
use crate::swc_ecma_ast;
use crate::swc_ecma_ast::Decl;
use crate::swc_ecma_ast::ModuleDecl;
use crate::swc_ecma_ast::Stmt;
-use crate::swc_ecma_parser::lexer::Lexer;
-use crate::swc_ecma_parser::JscTarget;
-use crate::swc_ecma_parser::Parser;
-use crate::swc_ecma_parser::Session;
-use crate::swc_ecma_parser::SourceFileInput;
-use crate::swc_ecma_parser::Syntax;
-use crate::swc_ecma_parser::TsConfig;
+use crate::swc_util::AstParser;
+use crate::swc_util::SwcDiagnosticBuffer;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
use futures::Future;
use regex::Regex;
use std::collections::HashMap;
-use std::error::Error;
-use std::fmt;
use std::pin::Pin;
-use std::sync::Arc;
-use std::sync::RwLock;
use super::namespace::NamespaceDef;
use super::node;
@@ -42,50 +23,6 @@ use super::DocNode;
use super::DocNodeKind;
use super::Location;
-#[derive(Clone, Debug)]
-pub struct SwcDiagnosticBuffer {
- pub diagnostics: Vec<Diagnostic>,
-}
-
-impl Error for SwcDiagnosticBuffer {}
-
-impl fmt::Display for SwcDiagnosticBuffer {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let msg = self
- .diagnostics
- .iter()
- .map(|d| d.message())
- .collect::<Vec<String>>()
- .join(",");
-
- f.pad(&msg)
- }
-}
-
-#[derive(Clone)]
-pub struct SwcErrorBuffer(Arc<RwLock<SwcDiagnosticBuffer>>);
-
-impl SwcErrorBuffer {
- pub fn default() -> Self {
- Self(Arc::new(RwLock::new(SwcDiagnosticBuffer {
- diagnostics: vec![],
- })))
- }
-}
-
-impl Emitter for SwcErrorBuffer {
- fn emit(&mut self, db: &DiagnosticBuilder) {
- self.0.write().unwrap().diagnostics.push((**db).clone());
- }
-}
-
-impl From<SwcErrorBuffer> for SwcDiagnosticBuffer {
- fn from(buf: SwcErrorBuffer) -> Self {
- let s = buf.0.read().unwrap();
- s.clone()
- }
-}
-
pub trait DocFileLoader {
fn resolve(
&self,
@@ -102,34 +39,15 @@ pub trait DocFileLoader {
}
pub struct DocParser {
+ pub ast_parser: AstParser,
pub loader: Box<dyn DocFileLoader>,
- pub buffered_error: SwcErrorBuffer,
- pub source_map: Arc<SourceMap>,
- pub handler: Handler,
- pub comments: Comments,
- pub globals: Globals,
}
impl DocParser {
pub fn new(loader: Box<dyn DocFileLoader>) -> Self {
- let buffered_error = SwcErrorBuffer::default();
-
- let handler = Handler::with_emitter_and_flags(
- Box::new(buffered_error.clone()),
- HandlerFlags {
- dont_buffer_diagnostics: true,
- can_emit_warnings: true,
- ..Default::default()
- },
- );
-
DocParser {
loader,
- buffered_error,
- source_map: Arc::new(SourceMap::default()),
- handler,
- comments: Comments::default(),
- globals: Globals::new(),
+ ast_parser: AstParser::new(),
}
}
@@ -138,47 +56,19 @@ impl DocParser {
file_name: &str,
source_code: &str,
) -> Result<ModuleDoc, SwcDiagnosticBuffer> {
- swc_common::GLOBALS.set(&self.globals, || {
- let swc_source_file = self.source_map.new_source_file(
- FileName::Custom(file_name.to_string()),
- source_code.to_string(),
- );
-
- let buffered_err = self.buffered_error.clone();
- let session = Session {
- handler: &self.handler,
- };
-
- let mut ts_config = TsConfig::default();
- ts_config.dynamic_import = true;
- let syntax = Syntax::Typescript(ts_config);
-
- let lexer = Lexer::new(
- session,
- syntax,
- JscTarget::Es2019,
- SourceFileInput::from(&*swc_source_file),
- Some(&self.comments),
- );
-
- let mut parser = Parser::new_from(session, lexer);
-
- let module =
- parser
- .parse_module()
- .map_err(move |mut err: DiagnosticBuilder| {
- err.cancel();
- SwcDiagnosticBuffer::from(buffered_err)
- })?;
-
- let doc_entries = self.get_doc_nodes_for_module_body(module.body.clone());
- let reexports = self.get_reexports_for_module_body(module.body);
- let module_doc = ModuleDoc {
- exports: doc_entries,
- reexports,
- };
- Ok(module_doc)
- })
+ self
+ .ast_parser
+ .parse_module(file_name, source_code, |parse_result| {
+ let module = parse_result?;
+ let doc_entries =
+ self.get_doc_nodes_for_module_body(module.body.clone());
+ let reexports = self.get_reexports_for_module_body(module.body);
+ let module_doc = ModuleDoc {
+ exports: doc_entries,
+ reexports,
+ };
+ Ok(module_doc)
+ })
}
pub async fn parse(&self, file_name: &str) -> Result<Vec<DocNode>, ErrBox> {
@@ -323,7 +213,7 @@ impl DocParser {
fn details_for_span(&self, span: Span) -> (Option<String>, Location) {
let js_doc = self.js_doc_for_span(span);
- let location = self.source_map.lookup_char_pos(span.lo()).into();
+ let location = self.ast_parser.get_span_location(span).into();
(js_doc, location)
}
@@ -567,13 +457,13 @@ impl DocParser {
}
pub fn js_doc_for_span(&self, span: Span) -> Option<String> {
- let comments = self.comments.take_leading_comments(span.lo())?;
+ let comments = self.ast_parser.get_span_comments(span);
let js_doc_comment = comments.iter().find(|comment| {
comment.kind == CommentKind::Block && comment.text.starts_with('*')
})?;
let mut margin_pat = String::from("");
- if let Some(margin) = self.source_map.span_to_margin(span) {
+ if let Some(margin) = self.ast_parser.source_map.span_to_margin(span) {
for _ in 0..margin {
margin_pat.push(' ');
}
diff --git a/cli/lib.rs b/cli/lib.rs
index 2cd077ebb..9d35710ab 100644
--- a/cli/lib.rs
+++ b/cli/lib.rs
@@ -53,6 +53,7 @@ pub mod signal;
pub mod source_maps;
mod startup_data;
pub mod state;
+mod swc_util;
mod test_runner;
pub mod test_util;
mod tokio_util;
diff --git a/cli/swc_util.rs b/cli/swc_util.rs
new file mode 100644
index 000000000..2086a5ded
--- /dev/null
+++ b/cli/swc_util.rs
@@ -0,0 +1,164 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use crate::swc_common;
+use crate::swc_common::comments::Comments;
+use crate::swc_common::errors::Diagnostic;
+use crate::swc_common::errors::DiagnosticBuilder;
+use crate::swc_common::errors::Emitter;
+use crate::swc_common::errors::Handler;
+use crate::swc_common::errors::HandlerFlags;
+use crate::swc_common::FileName;
+use crate::swc_common::Globals;
+use crate::swc_common::SourceMap;
+use crate::swc_common::Span;
+use crate::swc_ecma_ast;
+use crate::swc_ecma_parser::lexer::Lexer;
+use crate::swc_ecma_parser::JscTarget;
+use crate::swc_ecma_parser::Parser;
+use crate::swc_ecma_parser::Session;
+use crate::swc_ecma_parser::SourceFileInput;
+use crate::swc_ecma_parser::Syntax;
+use crate::swc_ecma_parser::TsConfig;
+
+use std::error::Error;
+use std::fmt;
+use std::sync::Arc;
+use std::sync::RwLock;
+
+#[derive(Clone, Debug)]
+pub struct SwcDiagnosticBuffer {
+ pub diagnostics: Vec<Diagnostic>,
+}
+
+impl Error for SwcDiagnosticBuffer {}
+
+impl fmt::Display for SwcDiagnosticBuffer {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let msg = self
+ .diagnostics
+ .iter()
+ .map(|d| d.message())
+ .collect::<Vec<String>>()
+ .join(",");
+
+ f.pad(&msg)
+ }
+}
+
+#[derive(Clone)]
+pub struct SwcErrorBuffer(Arc<RwLock<SwcDiagnosticBuffer>>);
+
+impl SwcErrorBuffer {
+ pub fn default() -> Self {
+ Self(Arc::new(RwLock::new(SwcDiagnosticBuffer {
+ diagnostics: vec![],
+ })))
+ }
+}
+
+impl Emitter for SwcErrorBuffer {
+ fn emit(&mut self, db: &DiagnosticBuilder) {
+ self.0.write().unwrap().diagnostics.push((**db).clone());
+ }
+}
+
+impl From<SwcErrorBuffer> for SwcDiagnosticBuffer {
+ fn from(buf: SwcErrorBuffer) -> Self {
+ let s = buf.0.read().unwrap();
+ s.clone()
+ }
+}
+
+/// Low-level utility structure with common AST parsing functions.
+///
+/// Allows to build more complicated parser by providing a callback
+/// to `parse_module`.
+pub struct AstParser {
+ pub buffered_error: SwcErrorBuffer,
+ pub source_map: Arc<SourceMap>,
+ pub handler: Handler,
+ pub comments: Comments,
+ pub globals: Globals,
+}
+
+impl AstParser {
+ pub fn new() -> Self {
+ let buffered_error = SwcErrorBuffer::default();
+
+ let handler = Handler::with_emitter_and_flags(
+ Box::new(buffered_error.clone()),
+ HandlerFlags {
+ dont_buffer_diagnostics: true,
+ can_emit_warnings: true,
+ ..Default::default()
+ },
+ );
+
+ AstParser {
+ buffered_error,
+ source_map: Arc::new(SourceMap::default()),
+ handler,
+ comments: Comments::default(),
+ globals: Globals::new(),
+ }
+ }
+
+ pub fn parse_module<F, R>(
+ &self,
+ file_name: &str,
+ source_code: &str,
+ callback: F,
+ ) -> R
+ where
+ F: FnOnce(Result<swc_ecma_ast::Module, SwcDiagnosticBuffer>) -> R,
+ {
+ swc_common::GLOBALS.set(&self.globals, || {
+ let swc_source_file = self.source_map.new_source_file(
+ FileName::Custom(file_name.to_string()),
+ source_code.to_string(),
+ );
+
+ let buffered_err = self.buffered_error.clone();
+ let session = Session {
+ handler: &self.handler,
+ };
+
+ let mut ts_config = TsConfig::default();
+ ts_config.dynamic_import = true;
+ let syntax = Syntax::Typescript(ts_config);
+
+ let lexer = Lexer::new(
+ session,
+ syntax,
+ JscTarget::Es2019,
+ SourceFileInput::from(&*swc_source_file),
+ Some(&self.comments),
+ );
+
+ let mut parser = Parser::new_from(session, lexer);
+
+ let parse_result =
+ parser
+ .parse_module()
+ .map_err(move |mut err: DiagnosticBuilder| {
+ err.cancel();
+ SwcDiagnosticBuffer::from(buffered_err)
+ });
+
+ callback(parse_result)
+ })
+ }
+
+ pub fn get_span_location(&self, span: Span) -> swc_common::Loc {
+ self.source_map.lookup_char_pos(span.lo())
+ }
+
+ pub fn get_span_comments(
+ &self,
+ span: Span,
+ ) -> Vec<swc_common::comments::Comment> {
+ self
+ .comments
+ .take_leading_comments(span.lo())
+ .unwrap_or_else(|| vec![])
+ }
+}