diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-05-22 19:23:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-22 19:23:35 +0200 |
commit | 960f9ccb2e700332dc576163b62c518120c73f15 (patch) | |
tree | 3bca9c5c449c01344f7dea9a945032fe17bffe63 /cli/swc_util.rs | |
parent | e191c70989a1dbf29b095bf6c2f7b62b90de012a (diff) |
fix: SWC lexer settings and silent errors (#5752)
This commit changes how error occurring in SWC are handled.
Changed lexer settings to properly handle TS decorators.
Changed output of SWC error to annotate with position in file.
Diffstat (limited to 'cli/swc_util.rs')
-rw-r--r-- | cli/swc_util.rs | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/cli/swc_util.rs b/cli/swc_util.rs index 5d900a708..d3b2a9e4a 100644 --- a/cli/swc_util.rs +++ b/cli/swc_util.rs @@ -29,45 +29,63 @@ use std::sync::RwLock; #[derive(Clone, Debug)] pub struct SwcDiagnosticBuffer { - pub diagnostics: Vec<Diagnostic>, + pub diagnostics: Vec<String>, } 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(","); + let msg = self.diagnostics.join(","); f.pad(&msg) } } +impl SwcDiagnosticBuffer { + pub fn from_swc_error( + error_buffer: SwcErrorBuffer, + parser: &AstParser, + ) -> Self { + let s = error_buffer.0.read().unwrap().clone(); + + let diagnostics = s + .iter() + .map(|d| { + let mut msg = d.message(); + + if let Some(span) = d.span.primary_span() { + let location = parser.get_span_location(span); + let filename = match &location.file.name { + FileName::Custom(n) => n, + _ => unreachable!(), + }; + msg = format!( + "{} at {}:{}:{}", + msg, filename, location.line, location.col_display + ); + } + + msg + }) + .collect::<Vec<String>>(); + + Self { diagnostics } + } +} + #[derive(Clone)] -pub struct SwcErrorBuffer(Arc<RwLock<SwcDiagnosticBuffer>>); +pub struct SwcErrorBuffer(Arc<RwLock<Vec<Diagnostic>>>); impl SwcErrorBuffer { pub fn default() -> Self { - Self(Arc::new(RwLock::new(SwcDiagnosticBuffer { - diagnostics: vec![], - }))) + Self(Arc::new(RwLock::new(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() + self.0.write().unwrap().push((**db).clone()); } } @@ -125,8 +143,10 @@ impl AstParser { handler: &self.handler, }; + // TODO(bartlomieju): lexer should be configurable by the caller let mut ts_config = TsConfig::default(); ts_config.dynamic_import = true; + ts_config.decorators = true; let syntax = Syntax::Typescript(ts_config); let lexer = Lexer::new( @@ -143,8 +163,8 @@ impl AstParser { parser .parse_module() .map_err(move |mut err: DiagnosticBuilder| { - err.cancel(); - SwcDiagnosticBuffer::from(buffered_err) + err.emit(); + SwcDiagnosticBuffer::from_swc_error(buffered_err, self) }); callback(parse_result) @@ -411,6 +431,7 @@ pub struct TsReferenceDescriptor { } pub fn analyze_dependencies_and_references( + file_name: &str, source_code: &str, analyze_dynamic_imports: bool, ) -> Result< @@ -418,7 +439,7 @@ pub fn analyze_dependencies_and_references( SwcDiagnosticBuffer, > { let parser = AstParser::new(); - parser.parse_module("root.ts", source_code, |parse_result| { + parser.parse_module(file_name, source_code, |parse_result| { let module = parse_result?; let mut collector = NewDependencyVisitor { dependencies: vec![], @@ -526,7 +547,8 @@ console.log(qat.qat); "#; let (imports, references) = - analyze_dependencies_and_references(source, true).expect("Failed to parse"); + analyze_dependencies_and_references("some/file.ts", source, true) + .expect("Failed to parse"); assert_eq!( imports, |