Skip to content

Commit f84b6dc

Browse files
authored
Also emit swc recoverable errors (#9650)
1 parent 8add915 commit f84b6dc

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

packages/core/integration-tests/test/javascript.js

+47
Original file line numberDiff line numberDiff line change
@@ -6438,6 +6438,53 @@ describe('javascript', function () {
64386438
}
64396439
});
64406440

6441+
it(`should also fail on recoverable parse errors`, async () => {
6442+
await fsFixture(overlayFS, __dirname)`
6443+
js-recoverable-parse-errors
6444+
index.js:
6445+
1 / {2}`;
6446+
6447+
const fixture = path.join(
6448+
__dirname,
6449+
'/js-recoverable-parse-errors/index.js',
6450+
);
6451+
6452+
await assert.rejects(
6453+
() =>
6454+
bundle(fixture, {
6455+
inputFS: overlayFS,
6456+
}),
6457+
{
6458+
name: 'BuildError',
6459+
diagnostics: [
6460+
{
6461+
origin: '@parcel/transformer-js',
6462+
message: 'Unexpected token `}`. Expected identifier',
6463+
hints: null,
6464+
codeFrames: [
6465+
{
6466+
filePath: fixture,
6467+
codeHighlights: [
6468+
{
6469+
message: undefined,
6470+
start: {
6471+
column: 7,
6472+
line: 1,
6473+
},
6474+
end: {
6475+
column: 7,
6476+
line: 1,
6477+
},
6478+
},
6479+
],
6480+
},
6481+
],
6482+
},
6483+
],
6484+
},
6485+
);
6486+
});
6487+
64416488
for (let shouldScopeHoist of [false, true]) {
64426489
let options = {
64436490
defaultTargetOptions: {

packages/transformers/js/core/src/lib.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ use swc_core::common::source_map::SourceMapGenConfig;
2626
use swc_core::common::{chain, sync::Lrc, FileName, Globals, Mark, SourceMap};
2727
use swc_core::ecma::ast::{Module, ModuleItem, Program};
2828
use swc_core::ecma::codegen::text_writer::JsWriter;
29+
use swc_core::ecma::parser::error::Error;
2930
use swc_core::ecma::parser::lexer::Lexer;
30-
use swc_core::ecma::parser::{EsConfig, PResult, Parser, StringInput, Syntax, TsConfig};
31+
use swc_core::ecma::parser::{EsConfig, Parser, StringInput, Syntax, TsConfig};
3132
use swc_core::ecma::preset_env::{preset_env, Mode::Entry, Targets, Version, Versions};
3233
use swc_core::ecma::transforms::base::fixer::paren_remover;
3334
use swc_core::ecma::transforms::base::helpers;
@@ -158,10 +159,12 @@ pub fn transform(
158159
);
159160

160161
match module {
161-
Err(err) => {
162+
Err(errs) => {
162163
let error_buffer = ErrorBuffer::default();
163164
let handler = Handler::with_emitter(true, false, Box::new(error_buffer.clone()));
164-
err.into_diagnostic(&handler).emit();
165+
for err in errs {
166+
err.into_diagnostic(&handler).emit();
167+
}
165168

166169
result.diagnostics = Some(error_buffer_to_diagnostics(&error_buffer, &source_map));
167170
Ok(result)
@@ -514,13 +517,15 @@ pub fn transform(
514517
}
515518
}
516519

520+
pub type ParseResult<T> = Result<T, Vec<Error>>;
521+
517522
fn parse(
518523
code: &str,
519524
project_root: &str,
520525
filename: &str,
521526
source_map: &Lrc<SourceMap>,
522527
config: &Config,
523-
) -> PResult<(Program, SingleThreadedComments)> {
528+
) -> ParseResult<(Program, SingleThreadedComments)> {
524529
// Attempt to convert the path to be relative to the project root.
525530
// If outside the project root, use an absolute path so that if the project root moves the path still works.
526531
let filename: PathBuf = if let Ok(relative) = Path::new(filename).strip_prefix(project_root) {
@@ -543,6 +548,7 @@ fn parse(
543548
export_default_from: true,
544549
decorators: config.decorators,
545550
import_attributes: true,
551+
allow_return_outside_function: true,
546552
..Default::default()
547553
})
548554
};
@@ -555,10 +561,22 @@ fn parse(
555561
);
556562

557563
let mut parser = Parser::new_from(lexer);
558-
match parser.parse_program() {
559-
Err(err) => Err(err),
560-
Ok(module) => Ok((module, comments)),
564+
let result = parser.parse_program();
565+
566+
let module = match result {
567+
Err(err) => {
568+
// A fatal error
569+
return Err(vec![err]);
570+
}
571+
Ok(module) => module,
572+
};
573+
// Recoverable errors
574+
let errors = parser.take_errors();
575+
if !errors.is_empty() {
576+
return Err(errors);
561577
}
578+
579+
Ok((module, comments))
562580
}
563581

564582
fn emit(

0 commit comments

Comments
 (0)