diff options
-rw-r--r-- | .prettierignore | 1 | ||||
-rw-r--r-- | cli/module_graph.rs | 2 | ||||
-rw-r--r-- | cli/swc_util.rs | 68 | ||||
-rw-r--r-- | cli/tests/integration_tests.rs | 12 | ||||
-rw-r--r-- | cli/tests/swc_syntax_error.ts | 3 | ||||
-rw-r--r-- | cli/tests/swc_syntax_error.ts.out | 1 | ||||
-rw-r--r-- | cli/tests/ts_decorators.ts | 14 | ||||
-rw-r--r-- | cli/tests/ts_decorators.ts.out | 2 | ||||
-rw-r--r-- | cli/tests/tsconfig.decorators.json | 5 | ||||
-rw-r--r-- | cli/tsc.rs | 1 | ||||
-rwxr-xr-x | tools/lint.py | 3 |
11 files changed, 86 insertions, 26 deletions
diff --git a/.prettierignore b/.prettierignore index b54ad0617..7795c3666 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,7 @@ cli/compilers/wasm_wrap.js cli/tests/error_syntax.js cli/tests/badly_formatted.js cli/tests/top_level_for_await.js +cli/tests/swc_syntax_error.ts std/**/testdata std/**/vendor std/node_modules 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", diff --git a/tools/lint.py b/tools/lint.py index 86c45b539..0e71fa946 100755 --- a/tools/lint.py +++ b/tools/lint.py @@ -61,7 +61,8 @@ def eslint(): "eslint") # Find all *directories* in the main repo that contain .ts/.js files. source_files = get_sources(root_path, [ - "*.js", "*.ts", ":!:std/**/testdata/*", ":!:std/**/node_modules/*", + "*.js", "*.ts", ":!:cli/tests/swc_syntax_error.ts", + ":!:std/**/testdata/*", ":!:std/**/node_modules/*", ":!:cli/compilers/wasm_wrap.js", ":!:cli/tests/error_syntax.js" ]) if source_files: |