summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-05-22 19:23:35 +0200
committerGitHub <noreply@github.com>2020-05-22 19:23:35 +0200
commit960f9ccb2e700332dc576163b62c518120c73f15 (patch)
tree3bca9c5c449c01344f7dea9a945032fe17bffe63 /cli
parente191c70989a1dbf29b095bf6c2f7b62b90de012a (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')
-rw-r--r--cli/module_graph.rs2
-rw-r--r--cli/swc_util.rs68
-rw-r--r--cli/tests/integration_tests.rs12
-rw-r--r--cli/tests/swc_syntax_error.ts3
-rw-r--r--cli/tests/swc_syntax_error.ts.out1
-rw-r--r--cli/tests/ts_decorators.ts14
-rw-r--r--cli/tests/ts_decorators.ts.out2
-rw-r--r--cli/tests/tsconfig.decorators.json5
-rw-r--r--cli/tsc.rs1
9 files changed, 83 insertions, 25 deletions
diff --git a/cli/module_graph.rs b/cli/module_graph.rs
index c63e6848f..8e423265c 100644
--- a/cli/module_graph.rs
+++ b/cli/module_graph.rs
@@ -188,6 +188,7 @@ impl ModuleGraphLoader {
};
let (import_descs, ref_descs) = analyze_dependencies_and_references(
+ &specifier,
&source_code,
self.analyze_dynamic_imports,
)?;
@@ -402,6 +403,7 @@ impl ModuleGraphLoader {
}
let (import_descs, ref_descs) = analyze_dependencies_and_references(
+ &module_specifier.to_string(),
&source_code,
self.analyze_dynamic_imports,
)?;
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,
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index 9f73c91b3..457a345dd 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -1575,7 +1575,17 @@ itest!(ts_type_imports {
args: "run --reload ts_type_imports.ts",
output: "ts_type_imports.ts.out",
exit_code: 1,
- http_server: true,
+});
+
+itest!(ts_decorators {
+ args: "run --reload -c tsconfig.decorators.json ts_decorators.ts",
+ output: "ts_decorators.ts.out",
+});
+
+itest!(swc_syntax_error {
+ args: "run --reload swc_syntax_error.ts",
+ output: "swc_syntax_error.ts.out",
+ exit_code: 1,
});
itest!(types {
diff --git a/cli/tests/swc_syntax_error.ts b/cli/tests/swc_syntax_error.ts
new file mode 100644
index 000000000..70e0de97d
--- /dev/null
+++ b/cli/tests/swc_syntax_error.ts
@@ -0,0 +1,3 @@
+for await (const req of s) {
+ let something:
+}
diff --git a/cli/tests/swc_syntax_error.ts.out b/cli/tests/swc_syntax_error.ts.out
new file mode 100644
index 000000000..0896faf68
--- /dev/null
+++ b/cli/tests/swc_syntax_error.ts.out
@@ -0,0 +1 @@
+error: Unexpected token Some(RBrace) at [WILDCARD]syntax_error.ts:3:0
diff --git a/cli/tests/ts_decorators.ts b/cli/tests/ts_decorators.ts
new file mode 100644
index 000000000..67fd0604f
--- /dev/null
+++ b/cli/tests/ts_decorators.ts
@@ -0,0 +1,14 @@
+/* eslint-disable */
+
+function Decorate() {
+ return function (constructor: any): any {
+ return class extends constructor {
+ protected someField: string = "asdf";
+ };
+ };
+}
+
+@Decorate()
+class SomeClass {}
+
+console.log(new SomeClass());
diff --git a/cli/tests/ts_decorators.ts.out b/cli/tests/ts_decorators.ts.out
new file mode 100644
index 000000000..69d5937a9
--- /dev/null
+++ b/cli/tests/ts_decorators.ts.out
@@ -0,0 +1,2 @@
+Compile [WILDCARD]
+SomeClass { someField: "asdf" }
diff --git a/cli/tests/tsconfig.decorators.json b/cli/tests/tsconfig.decorators.json
new file mode 100644
index 000000000..504cd646e
--- /dev/null
+++ b/cli/tests/tsconfig.decorators.json
@@ -0,0 +1,5 @@
+{
+ "compilerOptions": {
+ "experimentalDecorators": true
+ }
+}
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 34f3b6de4..664721bc1 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -466,7 +466,6 @@ impl TsCompiler {
let module_graph = module_graph_loader.get_graph();
let module_graph_json =
serde_json::to_value(module_graph).expect("Failed to serialize data");
-
let target = match target {
TargetLib::Main => "main",
TargetLib::Worker => "worker",