From 703fdd86071859cee452aafbd2cf9522289f7f19 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Fri, 7 Feb 2025 12:35:44 +0100 Subject: [PATCH] fix: panic with js lint plugins and invalid js syntax (#28006) Noticed that the LSP might panic during serialization when working on a file with a syntax error. This PR changes the serialization so that invalid nodes are simply serialized to the invalid node `0`. The plugin code treats the node with id `0` as an invalid node and will ignore it during visiting. I'm not sure how to write a test for the LSP. --- cli/tools/lint/ast_buffer/swc.rs | 33 +++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/cli/tools/lint/ast_buffer/swc.rs b/cli/tools/lint/ast_buffer/swc.rs index ef6fac90944893..8a319ea9eb3cbd 100644 --- a/cli/tools/lint/ast_buffer/swc.rs +++ b/cli/tools/lint/ast_buffer/swc.rs @@ -241,7 +241,10 @@ fn serialize_module_decl( // Already handled earlier ExportSpecifier::Namespace(_) => unreachable!(), // this is not syntactically valid - ExportSpecifier::Default(_) => unreachable!(), + ExportSpecifier::Default(_) => { + // Ignore syntax errors + NodeRef(0) + } } }) .collect::>(); @@ -444,7 +447,10 @@ fn serialize_import_attrs( .map(|prop| { let (key, value) = match prop { // Invalid syntax - PropOrSpread::Spread(_) => unreachable!(), + PropOrSpread::Spread(_) => { + // Ignore syntax errors + (NodeRef(0), NodeRef(0)) + } PropOrSpread::Prop(prop) => { match prop.as_ref() { Prop::Shorthand(ident) => ( @@ -459,7 +465,10 @@ fn serialize_import_attrs( Prop::Assign(_) | Prop::Getter(_) | Prop::Setter(_) - | Prop::Method(_) => unreachable!(), + | Prop::Method(_) => { + // Ignore syntax errors + (NodeRef(0), NodeRef(0)) + } } } }; @@ -770,7 +779,10 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef { SimpleAssignTarget::TsInstantiation(target) => { serialize_expr(ctx, &Expr::TsInstantiation(target.clone())) } - SimpleAssignTarget::Invalid(_) => unreachable!(), + SimpleAssignTarget::Invalid(_) => { + // Ignore syntax errors + NodeRef(0) + } } } AssignTarget::Pat(target) => match target { @@ -780,7 +792,10 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef { AssignTargetPat::Object(object_pat) => { serialize_pat(ctx, &Pat::Object(object_pat.clone())) } - AssignTargetPat::Invalid(_) => unreachable!(), + AssignTargetPat::Invalid(_) => { + // Ignore syntax errors + NodeRef(0) + } }, }; @@ -1101,7 +1116,8 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef { ctx.write_chain_expr(&node.span, expr) } Expr::Invalid(_) => { - unreachable!() + // Ignore syntax errors + NodeRef(0) } } } @@ -1908,7 +1924,10 @@ fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef { ctx.write_assign_pat(&node.span, left, right) } - Pat::Invalid(_) => unreachable!(), + Pat::Invalid(_) => { + // Ignore syntax errors + NodeRef(0) + } Pat::Expr(node) => serialize_expr(ctx, node), } }