diff --git a/.github/workflows/test262.yml b/.github/workflows/test262.yml index 38b5635ac73..0b45f5ec398 100644 --- a/.github/workflows/test262.yml +++ b/.github/workflows/test262.yml @@ -93,7 +93,7 @@ jobs: issue-number: ${{ steps.pr-number.outputs.pr }} body-includes: Test262 comparison coverage results on ${{ matrix.os }} - - name: Update comment + - name: Update existing comment if: github.event_name == 'pull_request' && steps.previous-comment.outputs.comment-id uses: peter-evans/create-or-update-comment@v1.4.5 continue-on-error: true diff --git a/crates/rome_formatter/src/ts/statements/statement.rs b/crates/rome_formatter/src/ts/statements/statement.rs index 8e28405f4d2..810b892e3f4 100644 --- a/crates/rome_formatter/src/ts/statements/statement.rs +++ b/crates/rome_formatter/src/ts/statements/statement.rs @@ -1,5 +1,5 @@ use crate::{FormatElement, FormatResult, Formatter, ToFormatElement}; -use rslint_parser::ast::JsAnyStatement; +use rslint_parser::{ast::JsAnyStatement, AstNode}; impl ToFormatElement for JsAnyStatement { fn to_format_element(&self, formatter: &Formatter) -> FormatResult { @@ -54,7 +54,9 @@ impl ToFormatElement for JsAnyStatement { JsAnyStatement::JsVariableDeclarationStatement(decl) => { decl.to_format_element(formatter) } - JsAnyStatement::JsUnknownStatement(_) => todo!(), + JsAnyStatement::JsUnknownStatement(unknown_statement) => { + Ok(formatter.format_raw(unknown_statement.syntax())) + } JsAnyStatement::ImportDecl(_) => todo!(), JsAnyStatement::ExportNamed(_) => todo!(), JsAnyStatement::ExportDefaultDecl(_) => todo!(), diff --git a/crates/rslint_parser/src/lib.rs b/crates/rslint_parser/src/lib.rs index f52bc35f776..439e5e4c4b3 100644 --- a/crates/rslint_parser/src/lib.rs +++ b/crates/rslint_parser/src/lib.rs @@ -64,6 +64,7 @@ mod lossless_tree_sink; mod lossy_tree_sink; mod numbers; mod parse; +pub(crate) mod parse_recovery; mod state; mod syntax_node; mod token_source; diff --git a/crates/rslint_parser/src/parse_recovery.rs b/crates/rslint_parser/src/parse_recovery.rs new file mode 100644 index 00000000000..0ec50015e7b --- /dev/null +++ b/crates/rslint_parser/src/parse_recovery.rs @@ -0,0 +1,98 @@ +use crate::{Parser, ParserError, TokenSet}; +use rslint_errors::Diagnostic; +use rslint_lexer::{SyntaxKind, T}; + +/// This struct contains the information needed to the parser to recover from a certain error +/// +/// By default it doesn't check curly braces, use [with_braces_included] to turn opt-in the check +#[derive(Debug)] +pub struct ParseRecovery { + /// The [Diagnostic] to emit + error: Option, + /// It tells the parser to recover if the position is inside a set of [tokens](TokenSet) + recovery: TokenSet, + /// It tells the parser to recover if the current token is a curly brace + include_braces: bool, + /// The kind of the unknown node the parser inserts if it isn't able to recover because + /// the current token is neither in the recovery set nor any of `{` or `}`. + unknown_node_kind: SyntaxKind, +} + +impl ParseRecovery { + pub fn new(recovery: TokenSet, unknown_node_kind: SyntaxKind) -> Self { + Self { + error: None, + recovery, + include_braces: false, + unknown_node_kind, + } + } + + pub fn with_error>( + recovery: TokenSet, + unknown_node_kind: SyntaxKind, + error: Err, + ) -> Self { + Self { + error: Some(error.into()), + recovery, + include_braces: false, + unknown_node_kind, + } + } + + /// Enable check of curly braces as recovery tokens + pub fn enabled_braces_check(mut self) -> Self { + self.include_braces = true; + self + } + + /// The main function that tells to the parser how to recover itself. + /// + /// Recover from an error with a [recovery set](TokenSet) or by using a `{` or `}`. + /// + /// If [ParserRecoverer] has an error, it gets tracked in the events. + pub fn recover(&self, p: &mut Parser) { + let error = self.get_error(); + if let Some(error) = error { + p.error(error); + } else { + // the check on state should be done only when there's no error + if p.state.no_recovery { + return; + } + } + if !self.parsing_is_recoverable(p) { + let m = p.start(); + p.bump_any(); + m.complete(p, self.get_unknown_node_kind()); + } + } + + /// Checks if the parsing phase is recoverable by checking curly braces and [tokens set](TokenSet) + fn parsing_is_recoverable(&self, parser: &Parser) -> bool { + self.is_at_token_set(parser) || self.is_at_braces(parser) || self.is_at_eof(parser) + } + + /// It returns the diagnostic + fn get_error(&self) -> Option { + self.error.to_owned() + } + + /// It returns the unknown node kind that will be used to complete the parsing + fn get_unknown_node_kind(&self) -> SyntaxKind { + self.unknown_node_kind + } + + fn is_at_braces(&self, parser: &Parser) -> bool { + matches!(parser.cur(), T!['{'] | T!['}'] if self.include_braces) + } + + fn is_at_token_set(&self, parser: &Parser) -> bool { + parser.at_ts(self.recovery) + } + + fn is_at_eof(&self, parser: &Parser) -> bool { + parser.cur() == SyntaxKind::EOF + } +} diff --git a/crates/rslint_parser/src/parser.rs b/crates/rslint_parser/src/parser.rs index 1a1fa701ffa..4c492435cef 100644 --- a/crates/rslint_parser/src/parser.rs +++ b/crates/rslint_parser/src/parser.rs @@ -190,58 +190,6 @@ impl<'t> Parser<'t> { } } - /// Recover from an error with a recovery set or by using a `{` or `}`. - pub fn err_recover( - &mut self, - error: impl Into, - recovery: TokenSet, - include_braces: bool, - ) -> Option<()> { - if self.state.no_recovery { - return None; - } - - match self.cur() { - T!['{'] | T!['}'] if include_braces => { - self.error(error); - return Some(()); - } - _ => (), - } - - if self.at_ts(recovery) || self.cur() == EOF { - self.error(error); - return Some(()); - } - - let m = self.start(); - self.error(error); - self.bump_any(); - m.complete(self, SyntaxKind::ERROR); - Some(()) - } - - /// Recover from an error but don't add an error to the events - pub fn err_recover_no_err(&mut self, recovery: TokenSet, include_braces: bool) { - match self.cur() { - T!['{'] | T!['}'] if include_braces => { - return; - } - EOF => { - return; - } - _ => (), - } - - if self.at_ts(recovery) { - return; - } - - let m = self.start(); - self.bump_any(); - m.complete(self, SyntaxKind::ERROR); - } - /// Starts a new node in the syntax tree. All nodes and tokens /// consumed between the `start` and the corresponding `Marker::complete` /// belong to the same node. @@ -507,11 +455,7 @@ impl<'t> Parser<'t> { start..end } - pub fn expr_with_semi_recovery( - &mut self, - assign: bool, - unknown_syntax_kind: SyntaxKind, - ) -> Option { + pub fn expr_with_semi_recovery(&mut self, assign: bool) -> Option { let func = if assign { syntax::expr::assign_expr } else { @@ -523,10 +467,10 @@ impl<'t> Parser<'t> { let err = self .err_builder("expected an expression, but found `;` instead") .primary(self.cur_tok().range, ""); - self.error(err); self.bump_any(); - m.complete(self, unknown_syntax_kind); + m.complete(self, SyntaxKind::JS_UNKNOWN_EXPRESSION); + return None; } diff --git a/crates/rslint_parser/src/syntax/class.rs b/crates/rslint_parser/src/syntax/class.rs index 228098acf9a..e396ef25683 100644 --- a/crates/rslint_parser/src/syntax/class.rs +++ b/crates/rslint_parser/src/syntax/class.rs @@ -1,3 +1,4 @@ +use crate::parse_recovery::ParseRecovery; use crate::syntax::decl::{formal_param_pat, parameter_list, parameters_list}; use crate::syntax::expr::assign_expr; use crate::syntax::function::{function_body, ts_parameter_types, ts_return_type}; @@ -29,6 +30,8 @@ pub(super) fn class_expression(p: &mut Parser) -> CompletedMarker { // class extends {} // class // class foo { set {} } +// class A extends bar extends foo {} +// class A extends bar, foo {} /// Parses a class declaration pub(super) fn class_declaration(p: &mut Parser) -> CompletedMarker { class(p, ClassKind::Declaration) @@ -482,6 +485,38 @@ fn class_member(p: &mut Parser) -> CompletedMarker { if matches!(member_name, "get" | "set") && !is_at_line_break_or_generator { let is_getter = member_name == "get"; + // test getter_class_member + // class Getters { + // get foo() {} + // get static() {} + // static get bar() {} + // get "baz"() {} + // get ["a" + "b"]() {} + // get 5() {} + // get #private() {} + // } + // class NotGetters { + // get() {} + // async get() {} + // static get() {} + // } + + // test setter_class_number + // class Setters { + // set foo(a) {} + // set static(a) {} + // static set bar(a) {} + // set "baz"(a) {} + // set ["a" + "b"](a) {} + // set 5(a) {} + // set #private(a) {} + // } + // class NotSetters { + // set(a) {} + // async set(a) {} + // static set(a) {} + // } + // The tree currently holds a STATIC_MEMBER_NAME node that wraps a ident token but we now found // out that the 'get' or 'set' isn't a member name in this context but instead are the // 'get'/'set' keywords for getters/setters. That's why we need to undo the member name node, @@ -528,11 +563,12 @@ fn class_member(p: &mut Parser) -> CompletedMarker { let err = p .err_builder("expected `;`, a property, or a method for a class body, but found none") .primary(p.cur_tok().range, ""); - p.err_recover( - err, + ParseRecovery::with_error( token_set![T![;], T![ident], T![async], T![yield], T!['}'], T![#]], - false, - ); + JS_UNKNOWN_MEMBER, + err, + ) + .recover(p); member_marker.complete(p, JS_UNKNOWN_MEMBER) } diff --git a/crates/rslint_parser/src/syntax/decl.rs b/crates/rslint_parser/src/syntax/decl.rs index 1aac8181bb0..3915057279a 100644 --- a/crates/rslint_parser/src/syntax/decl.rs +++ b/crates/rslint_parser/src/syntax/decl.rs @@ -3,6 +3,7 @@ use super::expr::assign_expr; use super::pat::pattern; use super::typescript::*; +use crate::parse_recovery::ParseRecovery; use crate::syntax::function::function_body; use crate::{SyntaxKind::*, *}; @@ -198,7 +199,9 @@ pub(super) fn parameters_list( } Some(res) } else { - p.err_recover_no_err( + // test_err formal_params_invalid + // function (a++, c) {} + ParseRecovery::new( token_set![ T![ident], T![await], @@ -208,8 +211,10 @@ pub(super) fn parameters_list( T![...], T![')'], ], - true, - ); + JS_UNKNOWN_PATTERN, + ) + .enabled_braces_check() + .recover(p); None } }; diff --git a/crates/rslint_parser/src/syntax/expr.rs b/crates/rslint_parser/src/syntax/expr.rs index 540815f2cbc..78c3691d948 100644 --- a/crates/rslint_parser/src/syntax/expr.rs +++ b/crates/rslint_parser/src/syntax/expr.rs @@ -7,6 +7,7 @@ use super::decl::{arrow_body, parameter_list}; use super::pat::pattern; use super::typescript::*; use super::util::*; +use crate::parse_recovery::ParseRecovery; use crate::syntax::class::class_expression; use crate::syntax::function::function_expression; use crate::syntax::object::object_expr; @@ -244,6 +245,7 @@ fn assign_expr_recursive( // function *foo() { // yield foo; // yield* foo; +// yield; // } pub fn yield_expr(p: &mut Parser) -> CompletedMarker { let m = p.start(); @@ -705,6 +707,7 @@ pub fn args(p: &mut Parser) -> CompletedMarker { // test_err paren_or_arrow_expr_invalid_params // (5 + 5) => {} +// (a, ,b) => {} pub fn paren_or_arrow_expr(p: &mut Parser, can_be_arrow: bool) -> CompletedMarker { let m = p.start(); let checkpoint = p.checkpoint(); @@ -749,7 +752,8 @@ pub fn paren_or_arrow_expr(p: &mut Parser, can_be_arrow: bool) -> CompletedMarke let err = temp.err_builder(&format!("expect a closing parenthesis after a spread element, but instead found `{}`", temp.cur_src())) .primary(temp.cur_tok().range, ""); - temp.err_recover(err, EXPR_RECOVERY_SET, false); + ParseRecovery::with_error(EXPR_RECOVERY_SET, JS_UNKNOWN_PATTERN, err) + .recover(&mut temp); } } break; @@ -1085,7 +1089,9 @@ pub fn primary_expr(p: &mut Parser) -> Option { let err = p .err_builder("Expected an expression, but found none") .primary(p.cur_tok().range, "Expected an expression here"); - p.err_recover(err, p.state.expr_recovery_set, true); + ParseRecovery::with_error(p.state.expr_recovery_set, JS_UNKNOWN_EXPRESSION, err) + .enabled_braces_check() + .recover(p); return None; } }; @@ -1105,7 +1111,9 @@ pub fn reference_identifier_expression(p: &mut Parser) -> Option CompletedMarker { /// An individual object property such as `"a": b` or `5: 6 + 6`. fn object_member(p: &mut Parser) -> Option { match p.cur() { - // test object_expr_getter_setter + // test object_expr_getter // let a = { // get foo() { // return foo; @@ -61,7 +62,7 @@ fn object_member(p: &mut Parser) -> Option { Some(getter_object_member(p)) } - // test object_expr_getter_setter + // test object_expr_setter // let b = { // set [foo](bar) { // return 5; @@ -104,8 +105,14 @@ fn object_member(p: &mut Parser) -> Option { // test object_expr_method // let b = { - // foo() {}, + // foo() {}, + // "bar"(a, b, c) {}, + // ["foo" + "bar"](a) {}, + // 5(...rest) {} // } + + // test_err object_expr_method + // let b = { foo) } if p.at(T!['(']) || p.at(T![<]) { method_object_member_body(p).ok()?; Some(m.complete(p, JS_METHOD_OBJECT_MEMBER)) @@ -139,7 +146,7 @@ fn object_member(p: &mut Parser) -> Option { // test_err object_expr_non_ident_literal_prop // let b = {5} - p.err_recover_no_err(token_set![T![:], T![,]], false); + ParseRecovery::new(token_set![T![:], T![,]], ERROR).recover(p); if p.eat(T![:]) { assign_expr(p); @@ -205,7 +212,7 @@ pub fn object_prop_name(p: &mut Parser, binding: bool) -> Option Option { @@ -226,7 +233,6 @@ pub(crate) fn computed_member_name(p: &mut Parser) -> CompletedMarker { pub(super) fn literal_member_name(p: &mut Parser) -> Option { let m = p.start(); - match p.cur() { JS_STRING_LITERAL | JS_NUMBER_LITERAL | T![ident] => { p.bump_any(); @@ -298,7 +304,7 @@ fn method_object_member_body(p: &mut Parser) -> Result<(), ()> { .err_builder("expected a method definition, but found none") .primary(p.cur_tok().range, ""); - p.err_recover(err, BASE_METHOD_RECOVERY_SET, false); + ParseRecovery::with_error(BASE_METHOD_RECOVERY_SET, JS_UNKNOWN_MEMBER, err).recover(p); Err(()) }; diff --git a/crates/rslint_parser/src/syntax/pat.rs b/crates/rslint_parser/src/syntax/pat.rs index 3434258f59c..108e6c87a76 100644 --- a/crates/rslint_parser/src/syntax/pat.rs +++ b/crates/rslint_parser/src/syntax/pat.rs @@ -1,6 +1,6 @@ use super::expr::{assign_expr, identifier_name, lhs_expr, reference_identifier_expression}; use crate::syntax::object::object_prop_name; -use crate::{SyntaxKind::*, *}; +use crate::{parse_recovery::ParseRecovery, SyntaxKind::*, *}; pub fn pattern(p: &mut Parser, parameters: bool, assignment: bool) -> Option { Some(match p.cur() { @@ -77,7 +77,7 @@ pub fn pattern(p: &mut Parser, parameters: bool, assignment: bool) -> Option Option { // } // let eval = 5; pub fn binding_identifier(p: &mut Parser) -> Option { + let mut kind_to_change = NAME; if p.at(T![yield]) && p.state.in_generator { let err = p .err_builder("Illegal use of `yield` as an identifier in generator function") .primary(p.cur_tok().range, ""); + kind_to_change = JS_UNKNOWN_PATTERN; p.error(err); } @@ -112,7 +114,7 @@ pub fn binding_identifier(p: &mut Parser) -> Option { let err = p .err_builder("Illegal use of `await` as an identifier in an async context") .primary(p.cur_tok().range, ""); - + kind_to_change = JS_UNKNOWN_PATTERN; p.error(err); } @@ -125,12 +127,12 @@ pub fn binding_identifier(p: &mut Parser) -> Option { p.cur_src() )) .primary(p.cur_tok().range, ""); - + kind_to_change = JS_UNKNOWN_PATTERN; p.error(err); } let mut m = reference_identifier_expression(p)?; - m.change_kind(p, NAME); + m.change_kind(p, kind_to_change); Some(m) } @@ -152,6 +154,8 @@ pub fn binding_element( left } +// test_err +// let [ default: , hey , ] = [] pub fn array_binding_pattern( p: &mut Parser, parameters: bool, @@ -175,10 +179,11 @@ pub fn array_binding_pattern( m.complete(p, REST_PATTERN); break; } else if binding_element(p, parameters, assignment).is_none() { - p.err_recover_no_err( + ParseRecovery::new( token_set![T![await], T![ident], T![yield], T![:], T![=], T![']']], - false, - ); + JS_UNKNOWN_PATTERN, + ) + .recover(p); } if !p.at(T![']']) { p.expect(T![,]); @@ -191,6 +196,11 @@ pub fn array_binding_pattern( m.complete(p, ARRAY_PATTERN) } +// test_err object_binding_pattern +// let { 5 } } = { eval: "foo" }; +// let { eval } = { eval: "foo" }; +// let { 5, 6 } = { eval: "foo" }; +// let { default: , bar } = {}; pub fn object_binding_pattern(p: &mut Parser, parameters: bool) -> CompletedMarker { let m = p.start(); p.expect(T!['{']); @@ -244,10 +254,11 @@ fn object_binding_prop(p: &mut Parser, parameters: bool) -> Option>) -> Option // We must explicitly handle this case or else infinite recursion can happen if p.at_ts(token_set![T!['}'], T![import], T![export]]) { - p.err_and_bump(err, ERROR); + p.err_and_bump(err, JS_UNKNOWN_STATEMENT); return None; } - - p.err_recover(err, recovery_set.into().unwrap_or(STMT_RECOVERY_SET), false); + ParseRecovery::with_error( + recovery_set.into().unwrap_or(STMT_RECOVERY_SET), + JS_UNKNOWN_STATEMENT, + err, + ) + .recover(p); return None; } }; @@ -143,6 +148,13 @@ pub fn stmt(p: &mut Parser, recovery_set: impl Into>) -> Option Some(res) } +// test_err double_label +// label1: { +// label2: { +// label1: {} +// } +// } + fn expr_stmt(p: &mut Parser) -> Option { let start = p.cur_tok().range.start; // this is *technically* wrong because it would be an expr stmt in js but for our purposes @@ -189,7 +201,7 @@ fn expr_stmt(p: &mut Parser) -> Option { m.complete(p, ERROR); } - let mut expr = p.expr_with_semi_recovery(false, ERROR)?; + let mut expr = p.expr_with_semi_recovery(false)?; // Labelled stmt if expr.kind() == JS_REFERENCE_IDENTIFIER_EXPRESSION && p.at(T![:]) { expr.change_kind(p, NAME); @@ -217,7 +229,7 @@ fn expr_stmt(p: &mut Parser) -> Option { &format!("`{}` is first used as a label here", text), ) .primary( - p.cur_tok().range, + text_range, &format!("a second use of `{}` here is not allowed", text), ); @@ -241,6 +253,14 @@ fn expr_stmt(p: &mut Parser) -> Option { /// A debugger statement such as `debugger;` // test debugger_stmt // debugger; + +// test_err debugger_stmt +// function foo() { +// debugger { +// var something = "lorem"; +// } +// } + pub fn debugger_stmt(p: &mut Parser) -> CompletedMarker { let m = p.start(); let range = p.cur_tok().range; @@ -273,7 +293,7 @@ pub fn throw_stmt(p: &mut Parser) -> CompletedMarker { p.error(err); } else { - p.expr_with_semi_recovery(false, ERROR); + p.expr_with_semi_recovery(false); } semi(p, start..p.cur_tok().range.end); m.complete(p, JS_THROW_STATEMENT) @@ -365,7 +385,7 @@ pub fn return_stmt(p: &mut Parser) -> CompletedMarker { let start = p.cur_tok().range.start; p.expect(T![return]); if !p.has_linebreak_before_n(0) && p.at_ts(STARTS_EXPR) { - p.expr_with_semi_recovery(false, ERROR); + p.expr_with_semi_recovery(false); } semi(p, start..p.cur_tok().range.end); let complete = m.complete(p, JS_RETURN_STATEMENT); @@ -579,6 +599,7 @@ pub fn if_stmt(p: &mut Parser) -> CompletedMarker { // if (true) else // if else {} // if () {} else {} + // if (true)}}}} {} let m = p.start(); p.expect(T![if]); @@ -655,6 +676,7 @@ pub fn while_stmt(p: &mut Parser) -> CompletedMarker { // let bar, foo; // const a = 5; // const { foo: [bar], baz } = {}; +// let foo = "lorem", bar = "ipsum", third = "value", fourth = 6; pub fn variable_declaration_statement(p: &mut Parser) -> CompletedMarker { // test_err var_decl_err // var a =; @@ -791,7 +813,7 @@ fn variable_initializer(p: &mut Parser) { let m = p.start(); p.expect(T![=]); - p.expr_with_semi_recovery(true, ERROR); + p.expr_with_semi_recovery(true); m.complete(p, SyntaxKind::JS_EQUAL_VALUE_CLAUSE); } @@ -924,6 +946,7 @@ pub fn for_stmt(p: &mut Parser) -> CompletedMarker { // test_err for_stmt_err // for ;; {} // for let i = 5; i < 10; i++ {} + // for let i = 5; i < 10; ++i {} let m = p.start(); p.expect(T![for]); // FIXME: This should emit an error for non-for-of @@ -984,7 +1007,9 @@ fn switch_clause(p: &mut Parser) -> Option> { "Expected the start to a case or default clause here", ); - p.err_recover(err, STMT_RECOVERY_SET, true); + ParseRecovery::with_error(STMT_RECOVERY_SET, JS_UNKNOWN_STATEMENT, err) + .enabled_braces_check() + .recover(p); } } None @@ -1019,7 +1044,7 @@ pub fn switch_stmt(p: &mut Parser) -> CompletedMarker { break_allowed: true, ..p.state.clone() }); - if let Some(range) = switch_clause(&mut *temp) { + if let Some(default_range) = switch_clause(&mut *temp) { if let Some(ref err_range) = first_default { let err = temp .err_builder( @@ -1029,11 +1054,11 @@ pub fn switch_stmt(p: &mut Parser) -> CompletedMarker { err_range.to_owned(), "the first default clause is defined here", ) - .primary(range, "a second clause here is not allowed"); + .primary(default_range, "a second clause here is not allowed"); temp.error(err); } else { - first_default = Some(range); + first_default = Some(default_range); } } } @@ -1108,8 +1133,11 @@ fn catch_declaration(p: &mut Parser) { /// } /// ``` // test try_stmt +// try {} catch {} // try {} catch (e) {} // try {} catch {} finally {} +// try {} catch (e) {} finally {} +// try {} finally {} pub fn try_stmt(p: &mut Parser) -> CompletedMarker { // TODO: recover from `try catch` and `try finally`. The issue is block_items // will cause infinite recursion because parsing a stmt would not consume the catch token diff --git a/crates/rslint_parser/src/syntax/typescript.rs b/crates/rslint_parser/src/syntax/typescript.rs index 3f617c9e657..b1f1988507e 100644 --- a/crates/rslint_parser/src/syntax/typescript.rs +++ b/crates/rslint_parser/src/syntax/typescript.rs @@ -3,6 +3,7 @@ use super::decl::*; use super::expr::{assign_expr, identifier_name, lhs_expr, literal_expression}; use super::stmt::{semi, statements, variable_declaration_statement}; +use crate::parse_recovery::ParseRecovery; use crate::syntax::class::class_declaration; use crate::syntax::expr::any_reference_member; use crate::syntax::function::function_declaration; @@ -604,11 +605,12 @@ pub fn ts_enum(p: &mut Parser) -> CompletedMarker { .err_builder("expected an identifier or string for an enum variant, but found none") .primary(p.cur_tok().range, ""); - p.err_recover( - err, + ParseRecovery::with_error( token_set![T!['}'], T![ident], T![yield], T![await], T![=], T![,]], - false, - ); + ERROR, + err, + ) + .recover(p); true } else { if !p.eat(JS_STRING_LITERAL) { @@ -1034,8 +1036,7 @@ pub fn ts_non_array_type(p: &mut Parser) -> Option { .err_builder("expected a type") .primary(p.cur_tok().range, ""); - p.err_recover( - err, + ParseRecovery::with_error( BASE_TS_RECOVERY_SET.union(token_set![ T![typeof], T!['{'], @@ -1053,8 +1054,10 @@ pub fn ts_non_array_type(p: &mut Parser) -> Option { T![&], T![|] ]), - false, - ); + ERROR, + err, + ) + .recover(p); None } } @@ -1162,11 +1165,12 @@ fn type_param(p: &mut Parser) -> Option { .err_builder("expected a type parameter, but found none") .primary(p.cur_tok().range, ""); - p.err_recover( - err, + ParseRecovery::with_error( token_set![T![ident], T![yield], T![await], T![>], T![=]], - false, - ); + ERROR, + err, + ) + .recover(p); None } } @@ -1402,6 +1406,6 @@ pub fn ts_type_name( )) .primary(p.cur_tok().range, ""); - p.err_recover(err, set, false)?; + ParseRecovery::with_error(set, ERROR, err).recover(p); None } diff --git a/crates/rslint_parser/test_data/inline/err/binding_identifier_invalid.rast b/crates/rslint_parser/test_data/inline/err/binding_identifier_invalid.rast index 14a85334a27..ca44204f7a5 100644 --- a/crates/rslint_parser/test_data/inline/err/binding_identifier_invalid.rast +++ b/crates/rslint_parser/test_data/inline/err/binding_identifier_invalid.rast @@ -20,7 +20,7 @@ 1: LIST@18..27 0: JS_VARIABLE_DECLARATOR@18..27 0: SINGLE_PATTERN@18..24 - 0: NAME@18..24 + 0: JS_UNKNOWN_PATTERN@18..24 0: IDENT@18..24 "await" [] [Whitespace(" ")] 1: JS_EQUAL_VALUE_CLAUSE@24..27 0: EQ@24..26 "=" [] [Whitespace(" ")] @@ -48,7 +48,7 @@ 1: LIST@56..65 0: JS_VARIABLE_DECLARATOR@56..65 0: SINGLE_PATTERN@56..62 - 0: NAME@56..62 + 0: JS_UNKNOWN_PATTERN@56..62 0: IDENT@56..62 "yield" [] [Whitespace(" ")] 1: JS_EQUAL_VALUE_CLAUSE@62..65 0: EQ@62..64 "=" [] [Whitespace(" ")] @@ -62,7 +62,7 @@ 1: LIST@73..81 0: JS_VARIABLE_DECLARATOR@73..81 0: SINGLE_PATTERN@73..78 - 0: NAME@73..78 + 0: JS_UNKNOWN_PATTERN@73..78 0: IDENT@73..78 "eval" [] [Whitespace(" ")] 1: JS_EQUAL_VALUE_CLAUSE@78..81 0: EQ@78..80 "=" [] [Whitespace(" ")] diff --git a/crates/rslint_parser/test_data/inline/err/block_stmt_in_class.rast b/crates/rslint_parser/test_data/inline/err/block_stmt_in_class.rast index 88646410c33..7c30facc3e8 100644 --- a/crates/rslint_parser/test_data/inline/err/block_stmt_in_class.rast +++ b/crates/rslint_parser/test_data/inline/err/block_stmt_in_class.rast @@ -9,10 +9,10 @@ 2: L_CURLY@7..8 "{" [] [] 3: LIST@8..9 0: JS_UNKNOWN_MEMBER@8..9 - 0: ERROR@8..9 + 0: JS_UNKNOWN_MEMBER@8..9 0: L_CURLY@8..9 "{" [] [] 4: R_CURLY@9..10 "}" [] [] - 1: ERROR@10..11 + 1: JS_UNKNOWN_STATEMENT@10..11 0: R_CURLY@10..11 "}" [] [] 3: EOF@11..12 "" [Whitespace("\n")] [] -- diff --git a/crates/rslint_parser/test_data/inline/err/class_decl_err.rast b/crates/rslint_parser/test_data/inline/err/class_decl_err.rast index d05db01432c..7f46ab04797 100644 --- a/crates/rslint_parser/test_data/inline/err/class_decl_err.rast +++ b/crates/rslint_parser/test_data/inline/err/class_decl_err.rast @@ -36,7 +36,7 @@ 2: JS_UNKNOWN_MEMBER@59..65 0: JS_LITERAL_MEMBER_NAME@59..63 0: IDENT@59..63 "foo" [] [Whitespace(" ")] - 1: ERROR@63..65 + 1: JS_UNKNOWN_MEMBER@63..65 0: L_CURLY@63..65 "{" [] [Whitespace(" ")] 3: JS_SETTER_CLASS_MEMBER@65..72 0: SET_KW@65..69 "set" [] [Whitespace(" ")] diff --git a/crates/rslint_parser/test_data/inline/err/debugger_stmt.js b/crates/rslint_parser/test_data/inline/err/debugger_stmt.js new file mode 100644 index 00000000000..1ffa5855857 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/debugger_stmt.js @@ -0,0 +1,5 @@ +function foo() { + debugger { + var something = "lorem"; + } +} diff --git a/crates/rslint_parser/test_data/inline/err/debugger_stmt.rast b/crates/rslint_parser/test_data/inline/err/debugger_stmt.rast new file mode 100644 index 00000000000..d01f4977c98 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/debugger_stmt.rast @@ -0,0 +1,53 @@ +0: JS_ROOT@0..61 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..60 + 0: JS_FUNCTION_DECLARATION@0..60 + 0: FUNCTION_KW@0..9 "function" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@9..12 + 0: IDENT@9..12 "foo" [] [] + 2: JS_PARAMETER_LIST@12..15 + 0: L_PAREN@12..13 "(" [] [] + 1: LIST@13..13 + 2: R_PAREN@13..15 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@15..60 + 0: L_CURLY@15..16 "{" [] [] + 1: LIST@16..16 + 2: LIST@16..58 + 0: JS_DEBUGGER_STATEMENT@16..27 + 0: DEBUGGER_KW@16..27 "debugger" [Whitespace("\n\t")] [Whitespace(" ")] + 1: (empty) + 1: JS_BLOCK_STATEMENT@27..58 + 0: L_CURLY@27..28 "{" [] [] + 1: LIST@28..55 + 0: JS_VARIABLE_DECLARATION_STATEMENT@28..55 + 0: JS_VARIABLE_DECLARATION@28..54 + 0: VAR_KW@28..35 "var" [Whitespace("\n\t\t")] [Whitespace(" ")] + 1: LIST@35..54 + 0: JS_VARIABLE_DECLARATOR@35..54 + 0: SINGLE_PATTERN@35..45 + 0: NAME@35..45 + 0: IDENT@35..45 "something" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@45..54 + 0: EQ@45..47 "=" [] [Whitespace(" ")] + 1: JS_STRING_LITERAL_EXPRESSION@47..54 + 0: JS_STRING_LITERAL@47..54 "\"lorem\"" [] [] + 1: SEMICOLON@54..55 ";" [] [] + 2: R_CURLY@55..58 "}" [Whitespace("\n\t")] [] + 3: R_CURLY@58..60 "}" [Whitespace("\n")] [] + 3: EOF@60..61 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: Expected a semicolon or an implicit semicolon after a statement, but found none + ┌─ debugger_stmt.js:2:11 + │ +2 │ debugger { + │ -------- ^ An explicit or implicit semicolon is expected here... + │ │ + │ ...Which is required to end this statement + +-- +function foo() { + debugger { + var something = "lorem"; + } +} diff --git a/crates/rslint_parser/test_data/inline/err/double_label.js b/crates/rslint_parser/test_data/inline/err/double_label.js new file mode 100644 index 00000000000..153e974c4b0 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/double_label.js @@ -0,0 +1,5 @@ +label1: { + label2: { + label1: {} + } +} diff --git a/crates/rslint_parser/test_data/inline/err/double_label.rast b/crates/rslint_parser/test_data/inline/err/double_label.rast new file mode 100644 index 00000000000..c7d7f6bbed7 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/double_label.rast @@ -0,0 +1,42 @@ +0: JS_ROOT@0..39 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..38 + 0: JS_LABELED_STATEMENT@0..38 + 0: IDENT@0..6 "label1" [] [] + 1: COLON@6..8 ":" [] [Whitespace(" ")] + 2: JS_BLOCK_STATEMENT@8..38 + 0: L_CURLY@8..9 "{" [] [] + 1: LIST@9..36 + 0: JS_LABELED_STATEMENT@9..36 + 0: IDENT@9..17 "label2" [Whitespace("\n\t")] [] + 1: COLON@17..19 ":" [] [Whitespace(" ")] + 2: JS_BLOCK_STATEMENT@19..36 + 0: L_CURLY@19..20 "{" [] [] + 1: LIST@20..33 + 0: JS_LABELED_STATEMENT@20..33 + 0: IDENT@20..29 "label1" [Whitespace("\n\t\t")] [] + 1: COLON@29..31 ":" [] [Whitespace(" ")] + 2: JS_BLOCK_STATEMENT@31..33 + 0: L_CURLY@31..32 "{" [] [] + 1: LIST@32..32 + 2: R_CURLY@32..33 "}" [] [] + 2: R_CURLY@33..36 "}" [Whitespace("\n\t")] [] + 2: R_CURLY@36..38 "}" [Whitespace("\n")] [] + 3: EOF@38..39 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: Duplicate statement labels are not allowed + ┌─ double_label.js:3:3 + │ +1 │ label1: { + │ ------ `label1` is first used as a label here +2 │ label2: { +3 │ label1: {} + │ ^^^^^^ a second use of `label1` here is not allowed + +-- +label1: { + label2: { + label1: {} + } +} diff --git a/crates/rslint_parser/test_data/inline/err/for_stmt_err.js b/crates/rslint_parser/test_data/inline/err/for_stmt_err.js index 79642a08382..8077c930c6a 100644 --- a/crates/rslint_parser/test_data/inline/err/for_stmt_err.js +++ b/crates/rslint_parser/test_data/inline/err/for_stmt_err.js @@ -1,2 +1,3 @@ for ;; {} +for let i = 5; i < 10; i++ {} for let i = 5; i < 10; ++i {} diff --git a/crates/rslint_parser/test_data/inline/err/for_stmt_err.rast b/crates/rslint_parser/test_data/inline/err/for_stmt_err.rast index 3a2574ccbe1..1bce1f67983 100644 --- a/crates/rslint_parser/test_data/inline/err/for_stmt_err.rast +++ b/crates/rslint_parser/test_data/inline/err/for_stmt_err.rast @@ -1,7 +1,7 @@ -0: JS_ROOT@0..40 +0: JS_ROOT@0..70 0: (empty) 1: LIST@0..0 - 2: LIST@0..39 + 2: LIST@0..69 0: FOR_STMT@0..39 0: FOR_KW@0..4 "for" [] [Whitespace(" ")] 1: (empty) @@ -38,16 +38,50 @@ 0: JS_NUMBER_LITERAL@29..31 "10" [] [] 5: SEMICOLON@31..33 ";" [] [Whitespace(" ")] 6: FOR_STMT_UPDATE@33..37 - 0: JS_PRE_UPDATE_EXPRESSION@33..37 - 0: PLUS2@33..35 "++" [] [] - 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@35..37 - 0: IDENT@35..37 "i" [] [Whitespace(" ")] + 0: JS_POST_UPDATE_EXPRESSION@33..37 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@33..34 + 0: IDENT@33..34 "i" [] [] + 1: PLUS2@34..37 "++" [] [Whitespace(" ")] 7: (empty) 8: JS_BLOCK_STATEMENT@37..39 0: L_CURLY@37..38 "{" [] [] 1: LIST@38..38 2: R_CURLY@38..39 "}" [] [] - 3: EOF@39..40 "" [Whitespace("\n")] [] + 1: FOR_STMT@39..69 + 0: FOR_KW@39..44 "for" [Whitespace("\n")] [Whitespace(" ")] + 1: (empty) + 2: FOR_STMT_INIT@44..53 + 0: JS_VARIABLE_DECLARATION@44..53 + 0: LET_KW@44..48 "let" [] [Whitespace(" ")] + 1: LIST@48..53 + 0: JS_VARIABLE_DECLARATOR@48..53 + 0: SINGLE_PATTERN@48..50 + 0: NAME@48..50 + 0: IDENT@48..50 "i" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@50..53 + 0: EQ@50..52 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@52..53 + 0: JS_NUMBER_LITERAL@52..53 "5" [] [] + 3: SEMICOLON@53..55 ";" [] [Whitespace(" ")] + 4: FOR_STMT_TEST@55..61 + 0: JS_BINARY_EXPRESSION@55..61 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@55..57 + 0: IDENT@55..57 "i" [] [Whitespace(" ")] + 1: L_ANGLE@57..59 "<" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@59..61 + 0: JS_NUMBER_LITERAL@59..61 "10" [] [] + 5: SEMICOLON@61..63 ";" [] [Whitespace(" ")] + 6: FOR_STMT_UPDATE@63..67 + 0: JS_PRE_UPDATE_EXPRESSION@63..67 + 0: PLUS2@63..65 "++" [] [] + 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@65..67 + 0: IDENT@65..67 "i" [] [Whitespace(" ")] + 7: (empty) + 8: JS_BLOCK_STATEMENT@67..69 + 0: L_CURLY@67..68 "{" [] [] + 1: LIST@68..68 + 2: R_CURLY@68..69 "}" [] [] + 3: EOF@69..70 "" [Whitespace("\n")] [] -- error[SyntaxError]: expected `'('` but instead found `;` ┌─ for_stmt_err.js:1:5 @@ -59,23 +93,38 @@ error[SyntaxError]: expected `'('` but instead found `;` error[SyntaxError]: expected `')'` but instead found `for` ┌─ for_stmt_err.js:2:1 │ -2 │ for let i = 5; i < 10; ++i {} +2 │ for let i = 5; i < 10; i++ {} │ ^^^ unexpected -- error[SyntaxError]: expected `'('` but instead found `let` ┌─ for_stmt_err.js:2:5 │ -2 │ for let i = 5; i < 10; ++i {} +2 │ for let i = 5; i < 10; i++ {} │ ^^^ unexpected -- error[SyntaxError]: expected `')'` but instead found `{` ┌─ for_stmt_err.js:2:28 │ -2 │ for let i = 5; i < 10; ++i {} +2 │ for let i = 5; i < 10; i++ {} + │ ^ unexpected + +-- +error[SyntaxError]: expected `'('` but instead found `let` + ┌─ for_stmt_err.js:3:5 + │ +3 │ for let i = 5; i < 10; ++i {} + │ ^^^ unexpected + +-- +error[SyntaxError]: expected `')'` but instead found `{` + ┌─ for_stmt_err.js:3:28 + │ +3 │ for let i = 5; i < 10; ++i {} │ ^ unexpected -- for ;; {} +for let i = 5; i < 10; i++ {} for let i = 5; i < 10; ++i {} diff --git a/crates/rslint_parser/test_data/inline/err/formal_params_invalid.js b/crates/rslint_parser/test_data/inline/err/formal_params_invalid.js new file mode 100644 index 00000000000..3a8f1374ddc --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/formal_params_invalid.js @@ -0,0 +1 @@ +function (a++, c) {} diff --git a/crates/rslint_parser/test_data/inline/err/formal_params_invalid.rast b/crates/rslint_parser/test_data/inline/err/formal_params_invalid.rast new file mode 100644 index 00000000000..44c8286c58c --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/formal_params_invalid.rast @@ -0,0 +1,49 @@ +0: JS_ROOT@0..21 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..20 + 0: JS_FUNCTION_DECLARATION@0..20 + 0: FUNCTION_KW@0..9 "function" [] [Whitespace(" ")] + 1: JS_PARAMETER_LIST@9..18 + 0: L_PAREN@9..10 "(" [] [] + 1: LIST@10..16 + 0: SINGLE_PATTERN@10..11 + 0: NAME@10..11 + 0: IDENT@10..11 "a" [] [] + 1: (empty) + 2: JS_UNKNOWN_PATTERN@11..13 + 0: PLUS2@11..13 "++" [] [] + 3: COMMA@13..15 "," [] [Whitespace(" ")] + 4: SINGLE_PATTERN@15..16 + 0: NAME@15..16 + 0: IDENT@15..16 "c" [] [] + 2: R_PAREN@16..18 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@18..20 + 0: L_CURLY@18..19 "{" [] [] + 1: LIST@19..19 + 2: LIST@19..19 + 3: R_CURLY@19..20 "}" [] [] + 3: EOF@20..21 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: expected a name for the function in a function declaration, but found none + ┌─ formal_params_invalid.js:1:10 + │ +1 │ function (a++, c) {} + │ ^ + +-- +error[SyntaxError]: expected `,` but instead found `++` + ┌─ formal_params_invalid.js:1:12 + │ +1 │ function (a++, c) {} + │ ^^ unexpected + +-- +error[SyntaxError]: Expected an identifier or pattern, but found none + ┌─ formal_params_invalid.js:1:12 + │ +1 │ function (a++, c) {} + │ ^^ + +-- +function (a++, c) {} diff --git a/crates/rslint_parser/test_data/inline/err/formal_params_no_binding_element.rast b/crates/rslint_parser/test_data/inline/err/formal_params_no_binding_element.rast index b09c8437509..628a417f071 100644 --- a/crates/rslint_parser/test_data/inline/err/formal_params_no_binding_element.rast +++ b/crates/rslint_parser/test_data/inline/err/formal_params_no_binding_element.rast @@ -9,7 +9,7 @@ 2: JS_PARAMETER_LIST@12..19 0: L_PAREN@12..13 "(" [] [] 1: LIST@13..17 - 0: ERROR@13..17 + 0: JS_UNKNOWN_PATTERN@13..17 0: TRUE_KW@13..17 "true" [] [] 2: R_PAREN@17..19 ")" [] [Whitespace(" ")] 3: JS_FUNCTION_BODY@19..21 diff --git a/crates/rslint_parser/test_data/inline/err/function_broken.js b/crates/rslint_parser/test_data/inline/err/function_broken.js new file mode 100644 index 00000000000..046ecf3ecb7 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/function_broken.js @@ -0,0 +1 @@ +function foo())})}{{{ {} diff --git a/crates/rslint_parser/test_data/inline/err/function_broken.rast b/crates/rslint_parser/test_data/inline/err/function_broken.rast new file mode 100644 index 00000000000..a1f8dc7845f --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/function_broken.rast @@ -0,0 +1,95 @@ +0: JS_ROOT@0..26 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..25 + 0: JS_FUNCTION_DECLARATION@0..14 + 0: FUNCTION_KW@0..9 "function" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@9..12 + 0: IDENT@9..12 "foo" [] [] + 2: JS_PARAMETER_LIST@12..14 + 0: L_PAREN@12..13 "(" [] [] + 1: LIST@13..13 + 2: R_PAREN@13..14 ")" [] [] + 1: JS_UNKNOWN_STATEMENT@14..15 + 0: R_PAREN@14..15 ")" [] [] + 2: JS_UNKNOWN_STATEMENT@15..16 + 0: R_CURLY@15..16 "}" [] [] + 3: JS_UNKNOWN_STATEMENT@16..17 + 0: R_PAREN@16..17 ")" [] [] + 4: JS_UNKNOWN_STATEMENT@17..18 + 0: R_CURLY@17..18 "}" [] [] + 5: JS_BLOCK_STATEMENT@18..25 + 0: L_CURLY@18..19 "{" [] [] + 1: LIST@19..25 + 0: JS_BLOCK_STATEMENT@19..25 + 0: L_CURLY@19..20 "{" [] [] + 1: LIST@20..25 + 0: JS_BLOCK_STATEMENT@20..25 + 0: L_CURLY@20..23 "{" [] [Whitespace(" ")] + 1: LIST@23..25 + 0: JS_BLOCK_STATEMENT@23..25 + 0: L_CURLY@23..24 "{" [] [] + 1: LIST@24..24 + 2: R_CURLY@24..25 "}" [] [] + 2: (empty) + 2: (empty) + 2: (empty) + 3: EOF@25..26 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: expected a block statement but instead found `)` + ┌─ function_broken.js:1:15 + │ +1 │ function foo())})}{{{ {} + │ ^ + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ function_broken.js:1:15 + │ +1 │ function foo())})}{{{ {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ function_broken.js:1:16 + │ +1 │ function foo())})}{{{ {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ function_broken.js:1:17 + │ +1 │ function foo())})}{{{ {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ function_broken.js:1:18 + │ +1 │ function foo())})}{{{ {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: expected `'}'` but instead the file ends + ┌─ function_broken.js:2:1 + │ +2 │ + │ ^ the file ends here + +-- +error[SyntaxError]: expected `'}'` but instead the file ends + ┌─ function_broken.js:2:1 + │ +2 │ + │ ^ the file ends here + +-- +error[SyntaxError]: expected `'}'` but instead the file ends + ┌─ function_broken.js:2:1 + │ +2 │ + │ ^ the file ends here + +-- +function foo())})}{{{ {} diff --git a/crates/rslint_parser/test_data/inline/err/function_decl_err.rast b/crates/rslint_parser/test_data/inline/err/function_decl_err.rast index 6ffab5e3b19..51d946e8cf5 100644 --- a/crates/rslint_parser/test_data/inline/err/function_decl_err.rast +++ b/crates/rslint_parser/test_data/inline/err/function_decl_err.rast @@ -18,17 +18,17 @@ 1: JS_PARAMETER_LIST@23..39 0: (empty) 1: LIST@23..37 - 0: ERROR@23..24 + 0: JS_UNKNOWN_PATTERN@23..24 0: L_CURLY@23..24 "{" [] [] 1: (empty) - 2: ERROR@24..25 + 2: JS_UNKNOWN_PATTERN@24..25 0: R_CURLY@24..25 "}" [] [] - 3: ERROR@25..35 + 3: JS_UNKNOWN_PATTERN@25..35 0: FUNCTION_KW@25..35 "function" [Whitespace("\n")] [Whitespace(" ")] 4: (empty) - 5: ERROR@35..36 + 5: JS_UNKNOWN_PATTERN@35..36 0: STAR@35..36 "*" [] [] - 6: ERROR@36..37 + 6: JS_UNKNOWN_PATTERN@36..37 0: L_PAREN@36..37 "(" [] [] 2: R_PAREN@37..39 ")" [] [Whitespace(" ")] 2: JS_FUNCTION_BODY@39..41 diff --git a/crates/rslint_parser/test_data/inline/err/if_broken.js b/crates/rslint_parser/test_data/inline/err/if_broken.js new file mode 100644 index 00000000000..a571f99a0cb --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/if_broken.js @@ -0,0 +1 @@ +if (true)}}}} {} diff --git a/crates/rslint_parser/test_data/inline/err/if_broken.rast b/crates/rslint_parser/test_data/inline/err/if_broken.rast new file mode 100644 index 00000000000..df5773e701f --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/if_broken.rast @@ -0,0 +1,53 @@ +0: JS_ROOT@0..17 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..16 + 0: JS_IF_STATEMENT@0..10 + 0: IF_KW@0..3 "if" [] [Whitespace(" ")] + 1: L_PAREN@3..4 "(" [] [] + 2: JS_BOOLEAN_LITERAL_EXPRESSION@4..8 + 0: TRUE_KW@4..8 "true" [] [] + 3: R_PAREN@8..9 ")" [] [] + 4: JS_UNKNOWN_STATEMENT@9..10 + 0: R_CURLY@9..10 "}" [] [] + 1: JS_UNKNOWN_STATEMENT@10..11 + 0: R_CURLY@10..11 "}" [] [] + 2: JS_UNKNOWN_STATEMENT@11..12 + 0: R_CURLY@11..12 "}" [] [] + 3: JS_UNKNOWN_STATEMENT@12..14 + 0: R_CURLY@12..14 "}" [] [Whitespace(" ")] + 4: JS_BLOCK_STATEMENT@14..16 + 0: L_CURLY@14..15 "{" [] [] + 1: LIST@15..15 + 2: R_CURLY@15..16 "}" [] [] + 3: EOF@16..17 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_broken.js:1:10 + │ +1 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_broken.js:1:11 + │ +1 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_broken.js:1:12 + │ +1 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_broken.js:1:13 + │ +1 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +if (true)}}}} {} diff --git a/crates/rslint_parser/test_data/inline/err/if_stmt_err.js b/crates/rslint_parser/test_data/inline/err/if_stmt_err.js index 2a953332092..544717864aa 100644 --- a/crates/rslint_parser/test_data/inline/err/if_stmt_err.js +++ b/crates/rslint_parser/test_data/inline/err/if_stmt_err.js @@ -2,3 +2,4 @@ if (true) else {} if (true) else if else {} if () {} else {} +if (true)}}}} {} diff --git a/crates/rslint_parser/test_data/inline/err/if_stmt_err.rast b/crates/rslint_parser/test_data/inline/err/if_stmt_err.rast index 7133ef5d7fc..16e47db2396 100644 --- a/crates/rslint_parser/test_data/inline/err/if_stmt_err.rast +++ b/crates/rslint_parser/test_data/inline/err/if_stmt_err.rast @@ -1,7 +1,7 @@ -0: JS_ROOT@0..61 +0: JS_ROOT@0..78 0: (empty) 1: LIST@0..0 - 2: LIST@0..60 + 2: LIST@0..77 0: JS_IF_STATEMENT@0..17 0: IF_KW@0..3 "if" [] [Whitespace(" ")] 1: L_PAREN@3..4 "(" [] [] @@ -46,7 +46,25 @@ 0: L_CURLY@58..59 "{" [] [] 1: LIST@59..59 2: R_CURLY@59..60 "}" [] [] - 3: EOF@60..61 "" [Whitespace("\n")] [] + 3: JS_IF_STATEMENT@60..71 + 0: IF_KW@60..64 "if" [Whitespace("\n")] [Whitespace(" ")] + 1: L_PAREN@64..65 "(" [] [] + 2: JS_BOOLEAN_LITERAL_EXPRESSION@65..69 + 0: TRUE_KW@65..69 "true" [] [] + 3: R_PAREN@69..70 ")" [] [] + 4: JS_UNKNOWN_STATEMENT@70..71 + 0: R_CURLY@70..71 "}" [] [] + 4: JS_UNKNOWN_STATEMENT@71..72 + 0: R_CURLY@71..72 "}" [] [] + 5: JS_UNKNOWN_STATEMENT@72..73 + 0: R_CURLY@72..73 "}" [] [] + 6: JS_UNKNOWN_STATEMENT@73..75 + 0: R_CURLY@73..75 "}" [] [Whitespace(" ")] + 7: JS_BLOCK_STATEMENT@75..77 + 0: L_CURLY@75..76 "{" [] [] + 1: LIST@76..76 + 2: R_CURLY@76..77 "}" [] [] + 3: EOF@77..78 "" [Whitespace("\n")] [] -- error[SyntaxError]: Expected a statement or declaration, but found none ┌─ if_stmt_err.js:1:11 @@ -96,8 +114,37 @@ error[SyntaxError]: Expected an expression, but found none 4 │ if () {} else {} │ ^ Expected an expression here +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_stmt_err.js:5:10 + │ +5 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_stmt_err.js:5:11 + │ +5 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_stmt_err.js:5:12 + │ +5 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ if_stmt_err.js:5:13 + │ +5 │ if (true)}}}} {} + │ ^ Expected a statement or declaration here + -- if (true) else {} if (true) else if else {} if () {} else {} +if (true)}}}} {} diff --git a/crates/rslint_parser/test_data/inline/err/invalid_method_recover.rast b/crates/rslint_parser/test_data/inline/err/invalid_method_recover.rast index e1edb265a9e..c58bc0a2942 100644 --- a/crates/rslint_parser/test_data/inline/err/invalid_method_recover.rast +++ b/crates/rslint_parser/test_data/inline/err/invalid_method_recover.rast @@ -38,7 +38,7 @@ 0: IDENT@36..37 "a" [] [] 1: JS_EQUAL_VALUE_CLAUSE@37..39 0: EQ@37..38 "=" [] [] - 1: ERROR@38..39 + 1: JS_UNKNOWN_EXPRESSION@38..39 0: SEMICOLON@38..39 ";" [] [] 1: (empty) 3: R_CURLY@39..43 "}" [Whitespace("\n ")] [] diff --git a/crates/rslint_parser/test_data/inline/err/object_binding_pattern.js b/crates/rslint_parser/test_data/inline/err/object_binding_pattern.js new file mode 100644 index 00000000000..552ae54eaa5 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/object_binding_pattern.js @@ -0,0 +1,4 @@ +let { 5 } } = { eval: "foo" }; +let { eval } = { eval: "foo" }; +let { 5, 6 } = { eval: "foo" }; +let { default: , bar } = {}; diff --git a/crates/rslint_parser/test_data/inline/err/object_binding_pattern.rast b/crates/rslint_parser/test_data/inline/err/object_binding_pattern.rast new file mode 100644 index 00000000000..09c9c3d9011 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/object_binding_pattern.rast @@ -0,0 +1,186 @@ +0: JS_ROOT@0..124 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..123 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..10 + 0: JS_VARIABLE_DECLARATION@0..10 + 0: LET_KW@0..4 "let" [] [Whitespace(" ")] + 1: LIST@4..10 + 0: JS_VARIABLE_DECLARATOR@4..10 + 0: OBJECT_PATTERN@4..10 + 0: L_CURLY@4..6 "{" [] [Whitespace(" ")] + 1: LIST@6..8 + 0: JS_NUMBER_LITERAL_EXPRESSION@6..8 + 0: JS_NUMBER_LITERAL@6..8 "5" [] [Whitespace(" ")] + 2: R_CURLY@8..10 "}" [] [Whitespace(" ")] + 1: (empty) + 1: JS_UNKNOWN_STATEMENT@10..12 + 0: R_CURLY@10..12 "}" [] [Whitespace(" ")] + 2: JS_UNKNOWN_STATEMENT@12..14 + 0: EQ@12..14 "=" [] [Whitespace(" ")] + 3: JS_BLOCK_STATEMENT@14..29 + 0: L_CURLY@14..16 "{" [] [Whitespace(" ")] + 1: LIST@16..28 + 0: JS_LABELED_STATEMENT@16..28 + 0: IDENT@16..20 "eval" [] [] + 1: COLON@20..22 ":" [] [Whitespace(" ")] + 2: JS_EXPRESSION_STATEMENT@22..28 + 0: JS_STRING_LITERAL_EXPRESSION@22..28 + 0: JS_STRING_LITERAL@22..28 "\"foo\"" [] [Whitespace(" ")] + 1: (empty) + 2: R_CURLY@28..29 "}" [] [] + 4: JS_EMPTY_STATEMENT@29..30 + 0: SEMICOLON@29..30 ";" [] [] + 5: JS_VARIABLE_DECLARATION_STATEMENT@30..62 + 0: JS_VARIABLE_DECLARATION@30..61 + 0: LET_KW@30..35 "let" [Whitespace("\n")] [Whitespace(" ")] + 1: LIST@35..61 + 0: JS_VARIABLE_DECLARATOR@35..61 + 0: OBJECT_PATTERN@35..44 + 0: L_CURLY@35..37 "{" [] [Whitespace(" ")] + 1: LIST@37..42 + 0: JS_UNKNOWN_PATTERN@37..42 + 0: IDENT@37..42 "eval" [] [Whitespace(" ")] + 2: R_CURLY@42..44 "}" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@44..61 + 0: EQ@44..46 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@46..61 + 0: L_CURLY@46..48 "{" [] [Whitespace(" ")] + 1: LIST@48..60 + 0: JS_PROPERTY_OBJECT_MEMBER@48..60 + 0: JS_LITERAL_MEMBER_NAME@48..52 + 0: IDENT@48..52 "eval" [] [] + 1: COLON@52..54 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@54..60 + 0: JS_STRING_LITERAL@54..60 "\"foo\"" [] [Whitespace(" ")] + 2: R_CURLY@60..61 "}" [] [] + 1: SEMICOLON@61..62 ";" [] [] + 6: JS_VARIABLE_DECLARATION_STATEMENT@62..94 + 0: JS_VARIABLE_DECLARATION@62..93 + 0: LET_KW@62..67 "let" [Whitespace("\n")] [Whitespace(" ")] + 1: LIST@67..93 + 0: JS_VARIABLE_DECLARATOR@67..93 + 0: OBJECT_PATTERN@67..76 + 0: L_CURLY@67..69 "{" [] [Whitespace(" ")] + 1: LIST@69..74 + 0: JS_NUMBER_LITERAL_EXPRESSION@69..70 + 0: JS_NUMBER_LITERAL@69..70 "5" [] [] + 1: COMMA@70..72 "," [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@72..74 + 0: JS_NUMBER_LITERAL@72..74 "6" [] [Whitespace(" ")] + 2: R_CURLY@74..76 "}" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@76..93 + 0: EQ@76..78 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@78..93 + 0: L_CURLY@78..80 "{" [] [Whitespace(" ")] + 1: LIST@80..92 + 0: JS_PROPERTY_OBJECT_MEMBER@80..92 + 0: JS_LITERAL_MEMBER_NAME@80..84 + 0: IDENT@80..84 "eval" [] [] + 1: COLON@84..86 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@86..92 + 0: JS_STRING_LITERAL@86..92 "\"foo\"" [] [Whitespace(" ")] + 2: R_CURLY@92..93 "}" [] [] + 1: SEMICOLON@93..94 ";" [] [] + 7: JS_VARIABLE_DECLARATION_STATEMENT@94..123 + 0: JS_VARIABLE_DECLARATION@94..122 + 0: LET_KW@94..99 "let" [Whitespace("\n")] [Whitespace(" ")] + 1: LIST@99..122 + 0: JS_VARIABLE_DECLARATOR@99..122 + 0: OBJECT_PATTERN@99..118 + 0: L_CURLY@99..101 "{" [] [Whitespace(" ")] + 1: LIST@101..116 + 0: KEY_VALUE_PATTERN@101..112 + 0: NAME@101..108 + 0: IDENT@101..108 "default" [] [] + 1: COLON@108..110 ":" [] [Whitespace(" ")] + 2: JS_UNKNOWN_PATTERN@110..112 + 0: COMMA@110..112 "," [] [Whitespace(" ")] + 1: (empty) + 2: SINGLE_PATTERN@112..116 + 0: NAME@112..116 + 0: IDENT@112..116 "bar" [] [Whitespace(" ")] + 2: R_CURLY@116..118 "}" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@118..122 + 0: EQ@118..120 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@120..122 + 0: L_CURLY@120..121 "{" [] [] + 1: LIST@121..121 + 2: R_CURLY@121..122 "}" [] [] + 1: SEMICOLON@122..123 ";" [] [] + 3: EOF@123..124 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: Expected an identifier for a pattern, but found none + ┌─ object_binding_pattern.js:1:7 + │ +1 │ let { 5 } } = { eval: "foo" }; + │ ^ + +-- +error[SyntaxError]: Object and Array patterns require initializers + ┌─ object_binding_pattern.js:1:5 + │ +1 │ let { 5 } } = { eval: "foo" }; + │ ^^^^^ this pattern is declared, but it is not given an initialized value + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ object_binding_pattern.js:1:11 + │ +1 │ let { 5 } } = { eval: "foo" }; + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Expected a statement or declaration, but found none + ┌─ object_binding_pattern.js:1:13 + │ +1 │ let { 5 } } = { eval: "foo" }; + │ ^ Expected a statement or declaration here + +-- +error[SyntaxError]: Illegal use of `eval` as an identifier in strict mode + ┌─ object_binding_pattern.js:2:7 + │ +2 │ let { eval } = { eval: "foo" }; + │ ^^^^ + +-- +error[SyntaxError]: Expected an identifier for a pattern, but found none + ┌─ object_binding_pattern.js:2:7 + │ +2 │ let { eval } = { eval: "foo" }; + │ ^^^^ + +-- +error[SyntaxError]: Expected an identifier for a pattern, but found none + ┌─ object_binding_pattern.js:3:7 + │ +3 │ let { 5, 6 } = { eval: "foo" }; + │ ^ + +-- +error[SyntaxError]: Expected an identifier for a pattern, but found none + ┌─ object_binding_pattern.js:3:10 + │ +3 │ let { 5, 6 } = { eval: "foo" }; + │ ^ + +-- +error[SyntaxError]: Expected an identifier or pattern, but found none + ┌─ object_binding_pattern.js:4:16 + │ +4 │ let { default: , bar } = {}; + │ ^ + +-- +error[SyntaxError]: expected `,` but instead found `bar` + ┌─ object_binding_pattern.js:4:18 + │ +4 │ let { default: , bar } = {}; + │ ^^^ unexpected + +-- +let { 5 } } = { eval: "foo" }; +let { eval } = { eval: "foo" }; +let { 5, 6 } = { eval: "foo" }; +let { default: , bar } = {}; diff --git a/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.js b/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.js index 8c9013724c8..7170c447e6d 100644 --- a/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.js +++ b/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.js @@ -1,2 +1,4 @@ let a = { /: 6, /: /foo/ } let a = {{}} +test_err object_expr_non_ident_literal_prop +let b = {5} diff --git a/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.rast b/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.rast index 24fb361e9e8..fb741646803 100644 --- a/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.rast +++ b/crates/rslint_parser/test_data/inline/err/object_expr_error_prop_name.rast @@ -1,7 +1,7 @@ -0: JS_ROOT@0..40 +0: JS_ROOT@0..96 0: (empty) 1: LIST@0..0 - 2: LIST@0..39 + 2: LIST@0..95 0: JS_VARIABLE_DECLARATION_STATEMENT@0..26 0: JS_VARIABLE_DECLARATION@0..26 0: LET_KW@0..4 "let" [] [Whitespace(" ")] @@ -41,9 +41,36 @@ 0: L_CURLY@36..37 "{" [] [] 2: R_CURLY@37..38 "}" [] [] 1: (empty) - 2: ERROR@38..39 + 2: JS_UNKNOWN_STATEMENT@38..39 0: R_CURLY@38..39 "}" [] [] - 3: EOF@39..40 "" [Whitespace("\n")] [] + 3: JS_EXPRESSION_STATEMENT@39..49 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@39..49 + 0: IDENT@39..49 "test_err" [Whitespace("\n")] [Whitespace(" ")] + 1: (empty) + 4: JS_EXPRESSION_STATEMENT@49..83 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@49..83 + 0: IDENT@49..83 "object_expr_non_ident_literal_prop" [] [] + 1: (empty) + 5: JS_VARIABLE_DECLARATION_STATEMENT@83..95 + 0: JS_VARIABLE_DECLARATION@83..95 + 0: LET_KW@83..88 "let" [Whitespace("\n")] [Whitespace(" ")] + 1: LIST@88..95 + 0: JS_VARIABLE_DECLARATOR@88..95 + 0: SINGLE_PATTERN@88..90 + 0: NAME@88..90 + 0: IDENT@88..90 "b" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@90..95 + 0: EQ@90..92 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@92..95 + 0: L_CURLY@92..93 "{" [] [] + 1: LIST@93..94 + 0: JS_PROPERTY_OBJECT_MEMBER@93..94 + 0: JS_LITERAL_MEMBER_NAME@93..94 + 0: JS_NUMBER_LITERAL@93..94 "5" [] [] + 1: (empty) + 2: R_CURLY@94..95 "}" [] [] + 1: (empty) + 3: EOF@95..96 "" [Whitespace("\n")] [] -- error[SyntaxError]: Expected an identifier, a keyword, or a string or number literal ┌─ object_expr_error_prop_name.js:1:11 @@ -65,6 +92,32 @@ error[SyntaxError]: Expected a statement or declaration, but found none 2 │ let a = {{}} │ ^ Expected a statement or declaration here +-- +error[SyntaxError]: Expected a semicolon or an implicit semicolon after a statement, but found none + ┌─ object_expr_error_prop_name.js:3:10 + │ +3 │ test_err object_expr_non_ident_literal_prop + │ ---------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ An explicit or implicit semicolon is expected here... + │ ...Which is required to end this statement + +-- +error[SyntaxError]: expected `:` but instead found `}` + ┌─ object_expr_error_prop_name.js:4:11 + │ +4 │ let b = {5} + │ ^ unexpected + +-- +error[SyntaxError]: Expected an expression, but found none + ┌─ object_expr_error_prop_name.js:4:11 + │ +4 │ let b = {5} + │ ^ Expected an expression here + -- let a = { /: 6, /: /foo/ } let a = {{}} +test_err object_expr_non_ident_literal_prop +let b = {5} diff --git a/crates/rslint_parser/test_data/inline/err/object_expr_method.js b/crates/rslint_parser/test_data/inline/err/object_expr_method.js new file mode 100644 index 00000000000..8d7c07c1263 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/object_expr_method.js @@ -0,0 +1 @@ +let b = { foo) } diff --git a/crates/rslint_parser/test_data/inline/err/object_expr_method.rast b/crates/rslint_parser/test_data/inline/err/object_expr_method.rast new file mode 100644 index 00000000000..ab74d8a9d01 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/object_expr_method.rast @@ -0,0 +1,58 @@ +0: JS_ROOT@0..17 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..16 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..16 + 0: JS_VARIABLE_DECLARATION@0..16 + 0: LET_KW@0..4 "let" [] [Whitespace(" ")] + 1: LIST@4..16 + 0: JS_VARIABLE_DECLARATOR@4..16 + 0: SINGLE_PATTERN@4..6 + 0: NAME@4..6 + 0: IDENT@4..6 "b" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@6..16 + 0: EQ@6..8 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@8..16 + 0: L_CURLY@8..10 "{" [] [Whitespace(" ")] + 1: LIST@10..15 + 0: JS_PROPERTY_OBJECT_MEMBER@10..13 + 0: JS_LITERAL_MEMBER_NAME@10..13 + 0: IDENT@10..13 "foo" [] [] + 1: (empty) + 1: (empty) + 2: JS_UNKNOWN_MEMBER@13..15 + 0: ERROR@13..15 + 0: R_PAREN@13..15 ")" [] [Whitespace(" ")] + 2: R_CURLY@15..16 "}" [] [] + 1: (empty) + 3: EOF@16..17 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: expected `:` but instead found `)` + ┌─ object_expr_method.js:1:14 + │ +1 │ let b = { foo) } + │ ^ unexpected + +-- +error[SyntaxError]: Expected an expression, but found none + ┌─ object_expr_method.js:1:14 + │ +1 │ let b = { foo) } + │ ^ Expected an expression here + +-- +error[SyntaxError]: expected `,` but instead found `)` + ┌─ object_expr_method.js:1:14 + │ +1 │ let b = { foo) } + │ ^ unexpected + +-- +error[SyntaxError]: Expected an identifier, a keyword, or a string or number literal + ┌─ object_expr_method.js:1:14 + │ +1 │ let b = { foo) } + │ ^ Expected an identifier, a keyword, or a string or number literal here + +-- +let b = { foo) } diff --git a/crates/rslint_parser/test_data/inline/err/paren_or_arrow_expr_invalid_params.rast b/crates/rslint_parser/test_data/inline/err/paren_or_arrow_expr_invalid_params.rast index f838dd5ba00..ca57a3eb5de 100644 --- a/crates/rslint_parser/test_data/inline/err/paren_or_arrow_expr_invalid_params.rast +++ b/crates/rslint_parser/test_data/inline/err/paren_or_arrow_expr_invalid_params.rast @@ -7,16 +7,16 @@ 0: JS_PARAMETER_LIST@0..5 0: L_PAREN@0..1 "(" [] [] 1: LIST@1..5 - 0: ERROR@1..3 + 0: JS_UNKNOWN_PATTERN@1..3 0: JS_NUMBER_LITERAL@1..3 "5" [] [Whitespace(" ")] - 1: ERROR@3..5 + 1: JS_UNKNOWN_PATTERN@3..5 0: PLUS@3..5 "+" [] [Whitespace(" ")] 2: (empty) 1: JS_NUMBER_LITERAL@5..6 "5" [] [] 1: (empty) - 1: ERROR@6..8 + 1: JS_UNKNOWN_STATEMENT@6..8 0: R_PAREN@6..8 ")" [] [Whitespace(" ")] - 2: ERROR@8..11 + 2: JS_UNKNOWN_STATEMENT@8..11 0: FAT_ARROW@8..11 "=>" [] [Whitespace(" ")] 3: JS_BLOCK_STATEMENT@11..13 0: L_CURLY@11..12 "{" [] [] @@ -29,7 +29,7 @@ 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@15..16 0: IDENT@15..16 "a" [] [] 1: COMMA@16..18 "," [] [Whitespace(" ")] - 2: ERROR@18..19 + 2: JS_UNKNOWN_EXPRESSION@18..19 0: COMMA@18..19 "," [] [] 3: (empty) 1: (empty) @@ -37,9 +37,9 @@ 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@19..20 0: IDENT@19..20 "b" [] [] 1: (empty) - 6: ERROR@20..22 + 6: JS_UNKNOWN_STATEMENT@20..22 0: R_PAREN@20..22 ")" [] [Whitespace(" ")] - 7: ERROR@22..25 + 7: JS_UNKNOWN_STATEMENT@22..25 0: FAT_ARROW@22..25 "=>" [] [Whitespace(" ")] 8: JS_BLOCK_STATEMENT@25..27 0: L_CURLY@25..26 "{" [] [] diff --git a/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.js b/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.js new file mode 100644 index 00000000000..c193c56e2cc --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.js @@ -0,0 +1,4 @@ +switch (foo) { + default: {} + default: {} +} diff --git a/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.rast b/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.rast new file mode 100644 index 00000000000..d85e53075e1 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/err/switch_stmt_double_default.rast @@ -0,0 +1,44 @@ +0: JS_ROOT@0..43 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..42 + 0: JS_SWITCH_STATEMENT@0..42 + 0: SWITCH_KW@0..7 "switch" [] [Whitespace(" ")] + 1: L_PAREN@7..8 "(" [] [] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@8..11 + 0: IDENT@8..11 "foo" [] [] + 3: R_PAREN@11..13 ")" [] [Whitespace(" ")] + 4: L_CURLY@13..14 "{" [] [] + 5: LIST@14..40 + 0: JS_DEFAULT_CLAUSE@14..27 + 0: DEFAULT_KW@14..23 "default" [Whitespace("\n\t")] [] + 1: COLON@23..25 ":" [] [Whitespace(" ")] + 2: LIST@25..27 + 0: JS_BLOCK_STATEMENT@25..27 + 0: L_CURLY@25..26 "{" [] [] + 1: LIST@26..26 + 2: R_CURLY@26..27 "}" [] [] + 1: JS_DEFAULT_CLAUSE@27..40 + 0: DEFAULT_KW@27..36 "default" [Whitespace("\n\t")] [] + 1: COLON@36..38 ":" [] [Whitespace(" ")] + 2: LIST@38..40 + 0: JS_BLOCK_STATEMENT@38..40 + 0: L_CURLY@38..39 "{" [] [] + 1: LIST@39..39 + 2: R_CURLY@39..40 "}" [] [] + 6: R_CURLY@40..42 "}" [Whitespace("\n")] [] + 3: EOF@42..43 "" [Whitespace("\n")] [] +-- +error[SyntaxError]: Multiple default clauses inside of a switch statement are not allowed + ┌─ switch_stmt_double_default.js:3:2 + │ +2 │ default: {} + │ ---------- the first default clause is defined here +3 │ default: {} + │ ^^^^^^^^^^ a second clause here is not allowed + +-- +switch (foo) { + default: {} + default: {} +} diff --git a/crates/rslint_parser/test_data/inline/err/var_decl_err.rast b/crates/rslint_parser/test_data/inline/err/var_decl_err.rast index f1541f017e6..e9b81011a27 100644 --- a/crates/rslint_parser/test_data/inline/err/var_decl_err.rast +++ b/crates/rslint_parser/test_data/inline/err/var_decl_err.rast @@ -12,7 +12,7 @@ 0: IDENT@4..6 "a" [] [Whitespace(" ")] 1: JS_EQUAL_VALUE_CLAUSE@6..8 0: EQ@6..7 "=" [] [] - 1: ERROR@7..8 + 1: JS_UNKNOWN_EXPRESSION@7..8 0: SEMICOLON@7..8 ";" [] [] 1: (empty) 1: JS_VARIABLE_DECLARATION_STATEMENT@8..21 diff --git a/crates/rslint_parser/test_data/inline/err/while_stmt_err.rast b/crates/rslint_parser/test_data/inline/err/while_stmt_err.rast index 53de94ec078..901a9c1dda4 100644 --- a/crates/rslint_parser/test_data/inline/err/while_stmt_err.rast +++ b/crates/rslint_parser/test_data/inline/err/while_stmt_err.rast @@ -36,7 +36,7 @@ 2: JS_BOOLEAN_LITERAL_EXPRESSION@44..48 0: TRUE_KW@44..48 "true" [] [] 3: R_PAREN@48..50 ")" [] [Whitespace(" ")] - 4: ERROR@50..51 + 4: JS_UNKNOWN_STATEMENT@50..51 0: R_CURLY@50..51 "}" [] [] 3: EOF@51..52 "" [Whitespace("\n")] [] -- diff --git a/crates/rslint_parser/test_data/inline/ok/binary_expressions.js b/crates/rslint_parser/test_data/inline/ok/binary_expressions.js index 1ab7f7fa2a6..b8d9a2e68ec 100644 --- a/crates/rslint_parser/test_data/inline/ok/binary_expressions.js +++ b/crates/rslint_parser/test_data/inline/ok/binary_expressions.js @@ -5,5 +5,6 @@ 1 / 2 74 in foo foo instanceof Array +foo ?? bar 1 + 1 + 1 + 1 5 + 6 - 1 * 2 / 1 ** 6 diff --git a/crates/rslint_parser/test_data/inline/ok/binary_expressions.rast b/crates/rslint_parser/test_data/inline/ok/binary_expressions.rast index 6f168e0712b..4adbede1a03 100644 --- a/crates/rslint_parser/test_data/inline/ok/binary_expressions.rast +++ b/crates/rslint_parser/test_data/inline/ok/binary_expressions.rast @@ -1,7 +1,7 @@ -0: JS_ROOT@0..114 +0: JS_ROOT@0..125 0: (empty) 1: LIST@0..0 - 2: LIST@0..113 + 2: LIST@0..124 0: JS_EXPRESSION_STATEMENT@0..5 0: JS_BINARY_EXPRESSION@0..5 0: JS_NUMBER_LITERAL_EXPRESSION@0..2 @@ -73,44 +73,52 @@ 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@71..76 0: IDENT@71..76 "Array" [] [] 1: (empty) - 6: JS_EXPRESSION_STATEMENT@76..90 - 0: JS_BINARY_EXPRESSION@76..90 - 0: JS_BINARY_EXPRESSION@76..87 - 0: JS_BINARY_EXPRESSION@76..83 - 0: JS_NUMBER_LITERAL_EXPRESSION@76..79 - 0: JS_NUMBER_LITERAL@76..79 "1" [Whitespace("\n")] [Whitespace(" ")] - 1: PLUS@79..81 "+" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@81..83 - 0: JS_NUMBER_LITERAL@81..83 "1" [] [Whitespace(" ")] - 1: PLUS@83..85 "+" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@85..87 - 0: JS_NUMBER_LITERAL@85..87 "1" [] [Whitespace(" ")] - 1: PLUS@87..89 "+" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@89..90 - 0: JS_NUMBER_LITERAL@89..90 "1" [] [] + 6: JS_EXPRESSION_STATEMENT@76..87 + 0: JS_LOGICAL_EXPRESSION@76..87 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@76..81 + 0: IDENT@76..81 "foo" [Whitespace("\n")] [Whitespace(" ")] + 1: QUESTION2@81..84 "??" [] [Whitespace(" ")] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@84..87 + 0: IDENT@84..87 "bar" [] [] 1: (empty) - 7: JS_EXPRESSION_STATEMENT@90..113 - 0: JS_BINARY_EXPRESSION@90..113 - 0: JS_BINARY_EXPRESSION@90..97 - 0: JS_NUMBER_LITERAL_EXPRESSION@90..93 - 0: JS_NUMBER_LITERAL@90..93 "5" [Whitespace("\n")] [Whitespace(" ")] - 1: PLUS@93..95 "+" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@95..97 - 0: JS_NUMBER_LITERAL@95..97 "6" [] [Whitespace(" ")] - 1: MINUS@97..99 "-" [] [Whitespace(" ")] - 2: JS_BINARY_EXPRESSION@99..113 - 0: JS_BINARY_EXPRESSION@99..105 - 0: JS_NUMBER_LITERAL_EXPRESSION@99..101 - 0: JS_NUMBER_LITERAL@99..101 "1" [] [Whitespace(" ")] - 1: STAR@101..103 "*" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@103..105 - 0: JS_NUMBER_LITERAL@103..105 "2" [] [Whitespace(" ")] - 1: SLASH@105..107 "/" [] [Whitespace(" ")] - 2: JS_BINARY_EXPRESSION@107..113 - 0: JS_NUMBER_LITERAL_EXPRESSION@107..109 - 0: JS_NUMBER_LITERAL@107..109 "1" [] [Whitespace(" ")] - 1: STAR2@109..112 "**" [] [Whitespace(" ")] - 2: JS_NUMBER_LITERAL_EXPRESSION@112..113 - 0: JS_NUMBER_LITERAL@112..113 "6" [] [] + 7: JS_EXPRESSION_STATEMENT@87..101 + 0: JS_BINARY_EXPRESSION@87..101 + 0: JS_BINARY_EXPRESSION@87..98 + 0: JS_BINARY_EXPRESSION@87..94 + 0: JS_NUMBER_LITERAL_EXPRESSION@87..90 + 0: JS_NUMBER_LITERAL@87..90 "1" [Whitespace("\n")] [Whitespace(" ")] + 1: PLUS@90..92 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@92..94 + 0: JS_NUMBER_LITERAL@92..94 "1" [] [Whitespace(" ")] + 1: PLUS@94..96 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@96..98 + 0: JS_NUMBER_LITERAL@96..98 "1" [] [Whitespace(" ")] + 1: PLUS@98..100 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@100..101 + 0: JS_NUMBER_LITERAL@100..101 "1" [] [] 1: (empty) - 3: EOF@113..114 "" [Whitespace("\n")] [] + 8: JS_EXPRESSION_STATEMENT@101..124 + 0: JS_BINARY_EXPRESSION@101..124 + 0: JS_BINARY_EXPRESSION@101..108 + 0: JS_NUMBER_LITERAL_EXPRESSION@101..104 + 0: JS_NUMBER_LITERAL@101..104 "5" [Whitespace("\n")] [Whitespace(" ")] + 1: PLUS@104..106 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@106..108 + 0: JS_NUMBER_LITERAL@106..108 "6" [] [Whitespace(" ")] + 1: MINUS@108..110 "-" [] [Whitespace(" ")] + 2: JS_BINARY_EXPRESSION@110..124 + 0: JS_BINARY_EXPRESSION@110..116 + 0: JS_NUMBER_LITERAL_EXPRESSION@110..112 + 0: JS_NUMBER_LITERAL@110..112 "1" [] [Whitespace(" ")] + 1: STAR@112..114 "*" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@114..116 + 0: JS_NUMBER_LITERAL@114..116 "2" [] [Whitespace(" ")] + 1: SLASH@116..118 "/" [] [Whitespace(" ")] + 2: JS_BINARY_EXPRESSION@118..124 + 0: JS_NUMBER_LITERAL_EXPRESSION@118..120 + 0: JS_NUMBER_LITERAL@118..120 "1" [] [Whitespace(" ")] + 1: STAR2@120..123 "**" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@123..124 + 0: JS_NUMBER_LITERAL@123..124 "6" [] [] + 1: (empty) + 3: EOF@124..125 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/bracket_expr.js b/crates/rslint_parser/test_data/inline/ok/bracket_expr.js new file mode 100644 index 00000000000..3f8f380377d --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/bracket_expr.js @@ -0,0 +1,5 @@ +foo[bar] +foo[5 + 5] +foo["bar"] +foo[bar][baz] +foo?.[bar] diff --git a/crates/rslint_parser/test_data/inline/ok/bracket_expr.rast b/crates/rslint_parser/test_data/inline/ok/bracket_expr.rast new file mode 100644 index 00000000000..6059915b346 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/bracket_expr.rast @@ -0,0 +1,60 @@ +0: JS_ROOT@0..56 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..55 + 0: JS_EXPRESSION_STATEMENT@0..8 + 0: JS_COMPUTED_MEMBER_EXPRESSION@0..8 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@0..3 + 0: IDENT@0..3 "foo" [] [] + 1: L_BRACK@3..4 "[" [] [] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@4..7 + 0: IDENT@4..7 "bar" [] [] + 3: R_BRACK@7..8 "]" [] [] + 1: (empty) + 1: JS_EXPRESSION_STATEMENT@8..19 + 0: JS_COMPUTED_MEMBER_EXPRESSION@8..19 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@8..12 + 0: IDENT@8..12 "foo" [Whitespace("\n")] [] + 1: L_BRACK@12..13 "[" [] [] + 2: JS_BINARY_EXPRESSION@13..18 + 0: JS_NUMBER_LITERAL_EXPRESSION@13..15 + 0: JS_NUMBER_LITERAL@13..15 "5" [] [Whitespace(" ")] + 1: PLUS@15..17 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@17..18 + 0: JS_NUMBER_LITERAL@17..18 "5" [] [] + 3: R_BRACK@18..19 "]" [] [] + 1: (empty) + 2: JS_EXPRESSION_STATEMENT@19..30 + 0: JS_COMPUTED_MEMBER_EXPRESSION@19..30 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@19..23 + 0: IDENT@19..23 "foo" [Whitespace("\n")] [] + 1: L_BRACK@23..24 "[" [] [] + 2: JS_STRING_LITERAL_EXPRESSION@24..29 + 0: JS_STRING_LITERAL@24..29 "\"bar\"" [] [] + 3: R_BRACK@29..30 "]" [] [] + 1: (empty) + 3: JS_EXPRESSION_STATEMENT@30..44 + 0: JS_COMPUTED_MEMBER_EXPRESSION@30..44 + 0: JS_COMPUTED_MEMBER_EXPRESSION@30..39 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@30..34 + 0: IDENT@30..34 "foo" [Whitespace("\n")] [] + 1: L_BRACK@34..35 "[" [] [] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@35..38 + 0: IDENT@35..38 "bar" [] [] + 3: R_BRACK@38..39 "]" [] [] + 1: L_BRACK@39..40 "[" [] [] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@40..43 + 0: IDENT@40..43 "baz" [] [] + 3: R_BRACK@43..44 "]" [] [] + 1: (empty) + 4: JS_EXPRESSION_STATEMENT@44..55 + 0: JS_COMPUTED_MEMBER_EXPRESSION@44..55 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@44..48 + 0: IDENT@44..48 "foo" [Whitespace("\n")] [] + 1: QUESTIONDOT@48..50 "?." [] [] + 2: L_BRACK@50..51 "[" [] [] + 3: JS_REFERENCE_IDENTIFIER_EXPRESSION@51..54 + 0: IDENT@51..54 "bar" [] [] + 4: R_BRACK@54..55 "]" [] [] + 1: (empty) + 3: EOF@55..56 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/class_decl.js b/crates/rslint_parser/test_data/inline/ok/class_decl.js new file mode 100644 index 00000000000..4a2383ca5b0 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/class_decl.js @@ -0,0 +1,3 @@ +class foo {} +class foo extends bar {} +class foo extends foo.bar {} diff --git a/crates/rslint_parser/test_data/inline/ok/class_decl.rast b/crates/rslint_parser/test_data/inline/ok/class_decl.rast new file mode 100644 index 00000000000..380a6aface8 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/class_decl.rast @@ -0,0 +1,38 @@ +0: JS_ROOT@0..67 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..66 + 0: JS_CLASS_DECLARATION@0..12 + 0: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@6..10 + 0: IDENT@6..10 "foo" [] [Whitespace(" ")] + 2: L_CURLY@10..11 "{" [] [] + 3: LIST@11..11 + 4: R_CURLY@11..12 "}" [] [] + 1: JS_CLASS_DECLARATION@12..37 + 0: CLASS_KW@12..19 "class" [Whitespace("\n")] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@19..23 + 0: IDENT@19..23 "foo" [] [Whitespace(" ")] + 2: JS_EXTENDS_CLAUSE@23..35 + 0: EXTENDS_KW@23..31 "extends" [] [Whitespace(" ")] + 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@31..35 + 0: IDENT@31..35 "bar" [] [Whitespace(" ")] + 3: L_CURLY@35..36 "{" [] [] + 4: LIST@36..36 + 5: R_CURLY@36..37 "}" [] [] + 2: JS_CLASS_DECLARATION@37..66 + 0: CLASS_KW@37..44 "class" [Whitespace("\n")] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@44..48 + 0: IDENT@44..48 "foo" [] [Whitespace(" ")] + 2: JS_EXTENDS_CLAUSE@48..64 + 0: EXTENDS_KW@48..56 "extends" [] [Whitespace(" ")] + 1: JS_STATIC_MEMBER_EXPRESSION@56..64 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@56..59 + 0: IDENT@56..59 "foo" [] [] + 1: DOT@59..60 "." [] [] + 2: JS_REFERENCE_IDENTIFIER_MEMBER@60..64 + 0: IDENT@60..64 "bar" [] [Whitespace(" ")] + 3: L_CURLY@64..65 "{" [] [] + 4: LIST@65..65 + 5: R_CURLY@65..66 "}" [] [] + 3: EOF@66..67 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/dot_expr.js b/crates/rslint_parser/test_data/inline/ok/dot_expr.js new file mode 100644 index 00000000000..535346087a0 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/dot_expr.js @@ -0,0 +1,6 @@ +foo.bar +foo.await +foo.yield +foo.for +foo?.for +foo?.bar diff --git a/crates/rslint_parser/test_data/inline/ok/dot_expr.rast b/crates/rslint_parser/test_data/inline/ok/dot_expr.rast index 310555060ce..0a51fbbe30c 100644 --- a/crates/rslint_parser/test_data/inline/ok/dot_expr.rast +++ b/crates/rslint_parser/test_data/inline/ok/dot_expr.rast @@ -3,51 +3,51 @@ 1: LIST@0..0 2: LIST@0..53 0: JS_EXPRESSION_STATEMENT@0..7 - 0: DOT_EXPR@0..7 + 0: JS_STATIC_MEMBER_EXPRESSION@0..7 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@0..3 0: IDENT@0..3 "foo" [] [] 1: DOT@3..4 "." [] [] - 2: NAME@4..7 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@4..7 0: IDENT@4..7 "bar" [] [] 1: (empty) 1: JS_EXPRESSION_STATEMENT@7..17 - 0: DOT_EXPR@7..17 + 0: JS_STATIC_MEMBER_EXPRESSION@7..17 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@7..11 0: IDENT@7..11 "foo" [Whitespace("\n")] [] 1: DOT@11..12 "." [] [] - 2: NAME@12..17 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@12..17 0: IDENT@12..17 "await" [] [] 1: (empty) 2: JS_EXPRESSION_STATEMENT@17..27 - 0: DOT_EXPR@17..27 + 0: JS_STATIC_MEMBER_EXPRESSION@17..27 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@17..21 0: IDENT@17..21 "foo" [Whitespace("\n")] [] 1: DOT@21..22 "." [] [] - 2: NAME@22..27 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@22..27 0: IDENT@22..27 "yield" [] [] 1: (empty) 3: JS_EXPRESSION_STATEMENT@27..35 - 0: DOT_EXPR@27..35 + 0: JS_STATIC_MEMBER_EXPRESSION@27..35 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@27..31 0: IDENT@27..31 "foo" [Whitespace("\n")] [] 1: DOT@31..32 "." [] [] - 2: NAME@32..35 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@32..35 0: IDENT@32..35 "for" [] [] 1: (empty) 4: JS_EXPRESSION_STATEMENT@35..44 - 0: DOT_EXPR@35..44 + 0: JS_STATIC_MEMBER_EXPRESSION@35..44 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@35..39 0: IDENT@35..39 "foo" [Whitespace("\n")] [] 1: QUESTIONDOT@39..41 "?." [] [] - 2: NAME@41..44 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@41..44 0: IDENT@41..44 "for" [] [] 1: (empty) 5: JS_EXPRESSION_STATEMENT@44..53 - 0: DOT_EXPR@44..53 + 0: JS_STATIC_MEMBER_EXPRESSION@44..53 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@44..48 0: IDENT@44..48 "foo" [Whitespace("\n")] [] 1: QUESTIONDOT@48..50 "?." [] [] - 2: NAME@50..53 + 2: JS_REFERENCE_IDENTIFIER_MEMBER@50..53 0: IDENT@50..53 "bar" [] [] 1: (empty) 3: EOF@53..54 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/getter_class_member.js b/crates/rslint_parser/test_data/inline/ok/getter_class_member.js index a308da7fd74..bbe3aaf1e5f 100644 --- a/crates/rslint_parser/test_data/inline/ok/getter_class_member.js +++ b/crates/rslint_parser/test_data/inline/ok/getter_class_member.js @@ -2,19 +2,13 @@ class Getters { get foo() {} get static() {} static get bar() {} - get "baz"() {} - get ["a" + "b"]() {} - get 5() {} - get #private() {} } - class NotGetters { get() {} async get() {} static get() {} } - diff --git a/crates/rslint_parser/test_data/inline/ok/getter_class_member.rast b/crates/rslint_parser/test_data/inline/ok/getter_class_member.rast index dcf037cff5f..0bea5ffef35 100644 --- a/crates/rslint_parser/test_data/inline/ok/getter_class_member.rast +++ b/crates/rslint_parser/test_data/inline/ok/getter_class_member.rast @@ -1,13 +1,13 @@ -0: JS_ROOT@0..209 +0: JS_ROOT@0..203 0: (empty) 1: LIST@0..0 - 2: LIST@0..207 - 0: JS_CLASS_DECLARATION@0..142 + 2: LIST@0..202 + 0: JS_CLASS_DECLARATION@0..138 0: CLASS_KW@0..6 "class" [] [Whitespace(" ")] 1: JS_IDENTIFIER_BINDING@6..14 0: IDENT@6..14 "Getters" [] [Whitespace(" ")] 2: L_CURLY@14..15 "{" [] [] - 3: LIST@15..140 + 3: LIST@15..136 0: JS_GETTER_CLASS_MEMBER@15..29 0: GET_KW@15..21 "get" [Whitespace("\n\t")] [Whitespace(" ")] 1: JS_LITERAL_MEMBER_NAME@21..24 @@ -42,102 +42,102 @@ 1: LIST@66..66 2: LIST@66..66 3: R_CURLY@66..67 "}" [] [] - 3: JS_GETTER_CLASS_MEMBER@67..84 - 0: GET_KW@67..74 "get" [Whitespace("\n\n\t")] [Whitespace(" ")] - 1: JS_LITERAL_MEMBER_NAME@74..79 - 0: JS_STRING_LITERAL@74..79 "\"baz\"" [] [] - 2: L_PAREN@79..80 "(" [] [] - 3: R_PAREN@80..82 ")" [] [Whitespace(" ")] - 4: JS_FUNCTION_BODY@82..84 - 0: L_CURLY@82..83 "{" [] [] - 1: LIST@83..83 - 2: LIST@83..83 - 3: R_CURLY@83..84 "}" [] [] - 4: JS_GETTER_CLASS_MEMBER@84..107 - 0: GET_KW@84..91 "get" [Whitespace("\n\n\t")] [Whitespace(" ")] - 1: JS_COMPUTED_MEMBER_NAME@91..102 - 0: L_BRACK@91..92 "[" [] [] - 1: JS_BINARY_EXPRESSION@92..101 - 0: JS_STRING_LITERAL_EXPRESSION@92..96 - 0: JS_STRING_LITERAL@92..96 "\"a\"" [] [Whitespace(" ")] - 1: PLUS@96..98 "+" [] [Whitespace(" ")] - 2: JS_STRING_LITERAL_EXPRESSION@98..101 - 0: JS_STRING_LITERAL@98..101 "\"b\"" [] [] - 2: R_BRACK@101..102 "]" [] [] - 2: L_PAREN@102..103 "(" [] [] - 3: R_PAREN@103..105 ")" [] [Whitespace(" ")] - 4: JS_FUNCTION_BODY@105..107 - 0: L_CURLY@105..106 "{" [] [] - 1: LIST@106..106 - 2: LIST@106..106 - 3: R_CURLY@106..107 "}" [] [] - 5: JS_GETTER_CLASS_MEMBER@107..120 - 0: GET_KW@107..114 "get" [Whitespace("\n\n\t")] [Whitespace(" ")] - 1: JS_LITERAL_MEMBER_NAME@114..115 - 0: JS_NUMBER_LITERAL@114..115 "5" [] [] - 2: L_PAREN@115..116 "(" [] [] - 3: R_PAREN@116..118 ")" [] [Whitespace(" ")] - 4: JS_FUNCTION_BODY@118..120 - 0: L_CURLY@118..119 "{" [] [] - 1: LIST@119..119 - 2: LIST@119..119 - 3: R_CURLY@119..120 "}" [] [] - 6: JS_GETTER_CLASS_MEMBER@120..140 - 0: GET_KW@120..127 "get" [Whitespace("\n\n\t")] [Whitespace(" ")] - 1: JS_PRIVATE_CLASS_MEMBER_NAME@127..135 - 0: HASH@127..128 "#" [] [] - 1: IDENT@128..135 "private" [] [] - 2: L_PAREN@135..136 "(" [] [] - 3: R_PAREN@136..138 ")" [] [Whitespace(" ")] - 4: JS_FUNCTION_BODY@138..140 - 0: L_CURLY@138..139 "{" [] [] - 1: LIST@139..139 - 2: LIST@139..139 - 3: R_CURLY@139..140 "}" [] [] - 4: R_CURLY@140..142 "}" [Whitespace("\n")] [] - 1: JS_CLASS_DECLARATION@142..207 - 0: CLASS_KW@142..150 "class" [Whitespace("\n\n")] [Whitespace(" ")] - 1: JS_IDENTIFIER_BINDING@150..161 - 0: IDENT@150..161 "NotGetters" [] [Whitespace(" ")] - 2: L_CURLY@161..162 "{" [] [] - 3: LIST@162..205 - 0: JS_METHOD_CLASS_MEMBER@162..172 - 0: JS_LITERAL_MEMBER_NAME@162..167 - 0: IDENT@162..167 "get" [Whitespace("\n\t")] [] - 1: JS_PARAMETER_LIST@167..170 - 0: L_PAREN@167..168 "(" [] [] - 1: LIST@168..168 - 2: R_PAREN@168..170 ")" [] [Whitespace(" ")] - 2: JS_FUNCTION_BODY@170..172 - 0: L_CURLY@170..171 "{" [] [] - 1: LIST@171..171 - 2: LIST@171..171 - 3: R_CURLY@171..172 "}" [] [] - 1: JS_METHOD_CLASS_MEMBER@172..188 - 0: ASYNC_KW@172..180 "async" [Whitespace("\n\t")] [Whitespace(" ")] - 1: JS_LITERAL_MEMBER_NAME@180..183 - 0: IDENT@180..183 "get" [] [] - 2: JS_PARAMETER_LIST@183..186 - 0: L_PAREN@183..184 "(" [] [] - 1: LIST@184..184 - 2: R_PAREN@184..186 ")" [] [Whitespace(" ")] - 3: JS_FUNCTION_BODY@186..188 - 0: L_CURLY@186..187 "{" [] [] - 1: LIST@187..187 - 2: LIST@187..187 - 3: R_CURLY@187..188 "}" [] [] - 2: JS_METHOD_CLASS_MEMBER@188..205 - 0: STATIC_KW@188..197 "static" [Whitespace("\n\t")] [Whitespace(" ")] - 1: JS_LITERAL_MEMBER_NAME@197..200 - 0: IDENT@197..200 "get" [] [] - 2: JS_PARAMETER_LIST@200..203 - 0: L_PAREN@200..201 "(" [] [] - 1: LIST@201..201 - 2: R_PAREN@201..203 ")" [] [Whitespace(" ")] - 3: JS_FUNCTION_BODY@203..205 - 0: L_CURLY@203..204 "{" [] [] - 1: LIST@204..204 - 2: LIST@204..204 - 3: R_CURLY@204..205 "}" [] [] - 4: R_CURLY@205..207 "}" [Whitespace("\n")] [] - 3: EOF@207..209 "" [Whitespace("\n\n")] [] + 3: JS_GETTER_CLASS_MEMBER@67..83 + 0: GET_KW@67..73 "get" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@73..78 + 0: JS_STRING_LITERAL@73..78 "\"baz\"" [] [] + 2: L_PAREN@78..79 "(" [] [] + 3: R_PAREN@79..81 ")" [] [Whitespace(" ")] + 4: JS_FUNCTION_BODY@81..83 + 0: L_CURLY@81..82 "{" [] [] + 1: LIST@82..82 + 2: LIST@82..82 + 3: R_CURLY@82..83 "}" [] [] + 4: JS_GETTER_CLASS_MEMBER@83..105 + 0: GET_KW@83..89 "get" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_COMPUTED_MEMBER_NAME@89..100 + 0: L_BRACK@89..90 "[" [] [] + 1: JS_BINARY_EXPRESSION@90..99 + 0: JS_STRING_LITERAL_EXPRESSION@90..94 + 0: JS_STRING_LITERAL@90..94 "\"a\"" [] [Whitespace(" ")] + 1: PLUS@94..96 "+" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@96..99 + 0: JS_STRING_LITERAL@96..99 "\"b\"" [] [] + 2: R_BRACK@99..100 "]" [] [] + 2: L_PAREN@100..101 "(" [] [] + 3: R_PAREN@101..103 ")" [] [Whitespace(" ")] + 4: JS_FUNCTION_BODY@103..105 + 0: L_CURLY@103..104 "{" [] [] + 1: LIST@104..104 + 2: LIST@104..104 + 3: R_CURLY@104..105 "}" [] [] + 5: JS_GETTER_CLASS_MEMBER@105..117 + 0: GET_KW@105..111 "get" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@111..112 + 0: JS_NUMBER_LITERAL@111..112 "5" [] [] + 2: L_PAREN@112..113 "(" [] [] + 3: R_PAREN@113..115 ")" [] [Whitespace(" ")] + 4: JS_FUNCTION_BODY@115..117 + 0: L_CURLY@115..116 "{" [] [] + 1: LIST@116..116 + 2: LIST@116..116 + 3: R_CURLY@116..117 "}" [] [] + 6: JS_GETTER_CLASS_MEMBER@117..136 + 0: GET_KW@117..123 "get" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_PRIVATE_CLASS_MEMBER_NAME@123..131 + 0: HASH@123..124 "#" [] [] + 1: IDENT@124..131 "private" [] [] + 2: L_PAREN@131..132 "(" [] [] + 3: R_PAREN@132..134 ")" [] [Whitespace(" ")] + 4: JS_FUNCTION_BODY@134..136 + 0: L_CURLY@134..135 "{" [] [] + 1: LIST@135..135 + 2: LIST@135..135 + 3: R_CURLY@135..136 "}" [] [] + 4: R_CURLY@136..138 "}" [Whitespace("\n")] [] + 1: JS_CLASS_DECLARATION@138..202 + 0: CLASS_KW@138..145 "class" [Whitespace("\n")] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@145..156 + 0: IDENT@145..156 "NotGetters" [] [Whitespace(" ")] + 2: L_CURLY@156..157 "{" [] [] + 3: LIST@157..200 + 0: JS_METHOD_CLASS_MEMBER@157..167 + 0: JS_LITERAL_MEMBER_NAME@157..162 + 0: IDENT@157..162 "get" [Whitespace("\n\t")] [] + 1: JS_PARAMETER_LIST@162..165 + 0: L_PAREN@162..163 "(" [] [] + 1: LIST@163..163 + 2: R_PAREN@163..165 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@165..167 + 0: L_CURLY@165..166 "{" [] [] + 1: LIST@166..166 + 2: LIST@166..166 + 3: R_CURLY@166..167 "}" [] [] + 1: JS_METHOD_CLASS_MEMBER@167..183 + 0: ASYNC_KW@167..175 "async" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@175..178 + 0: IDENT@175..178 "get" [] [] + 2: JS_PARAMETER_LIST@178..181 + 0: L_PAREN@178..179 "(" [] [] + 1: LIST@179..179 + 2: R_PAREN@179..181 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@181..183 + 0: L_CURLY@181..182 "{" [] [] + 1: LIST@182..182 + 2: LIST@182..182 + 3: R_CURLY@182..183 "}" [] [] + 2: JS_METHOD_CLASS_MEMBER@183..200 + 0: STATIC_KW@183..192 "static" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@192..195 + 0: IDENT@192..195 "get" [] [] + 2: JS_PARAMETER_LIST@195..198 + 0: L_PAREN@195..196 "(" [] [] + 1: LIST@196..196 + 2: R_PAREN@196..198 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@198..200 + 0: L_CURLY@198..199 "{" [] [] + 1: LIST@199..199 + 2: LIST@199..199 + 3: R_CURLY@199..200 "}" [] [] + 4: R_CURLY@200..202 "}" [Whitespace("\n")] [] + 3: EOF@202..203 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/grouping_expr.js b/crates/rslint_parser/test_data/inline/ok/grouping_expr.js new file mode 100644 index 00000000000..0b56526bc61 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/grouping_expr.js @@ -0,0 +1,2 @@ +((foo)) +(foo) diff --git a/crates/rslint_parser/test_data/inline/ok/grouping_expr.rast b/crates/rslint_parser/test_data/inline/ok/grouping_expr.rast new file mode 100644 index 00000000000..a9b658f2bc5 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/grouping_expr.rast @@ -0,0 +1,22 @@ +0: JS_ROOT@0..14 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..13 + 0: JS_EXPRESSION_STATEMENT@0..13 + 0: CALL_EXPR@0..13 + 0: JS_PARENTHESIZED_EXPRESSION@0..7 + 0: L_PAREN@0..1 "(" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@1..6 + 0: L_PAREN@1..2 "(" [] [] + 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@2..5 + 0: IDENT@2..5 "foo" [] [] + 2: R_PAREN@5..6 ")" [] [] + 2: R_PAREN@6..7 ")" [] [] + 1: ARG_LIST@7..13 + 0: L_PAREN@7..9 "(" [Whitespace("\n")] [] + 1: LIST@9..12 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@9..12 + 0: IDENT@9..12 "foo" [] [] + 2: R_PAREN@12..13 ")" [] [] + 1: (empty) + 3: EOF@13..14 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_getter.js b/crates/rslint_parser/test_data/inline/ok/object_expr_getter.js new file mode 100644 index 00000000000..962c788d77f --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_getter.js @@ -0,0 +1,5 @@ +let a = { + get foo() { + return foo; + } +} diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_getter.rast b/crates/rslint_parser/test_data/inline/ok/object_expr_getter.rast new file mode 100644 index 00000000000..9755f03f43d --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_getter.rast @@ -0,0 +1,36 @@ +0: JS_ROOT@0..43 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..42 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..42 + 0: JS_VARIABLE_DECLARATION@0..42 + 0: LET_KW@0..4 "let" [] [Whitespace(" ")] + 1: LIST@4..42 + 0: JS_VARIABLE_DECLARATOR@4..42 + 0: SINGLE_PATTERN@4..6 + 0: NAME@4..6 + 0: IDENT@4..6 "a" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@6..42 + 0: EQ@6..8 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@8..42 + 0: L_CURLY@8..9 "{" [] [] + 1: LIST@9..40 + 0: JS_GETTER_OBJECT_MEMBER@9..40 + 0: GET_KW@9..15 "get" [Whitespace("\n ")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@15..18 + 0: IDENT@15..18 "foo" [] [] + 2: L_PAREN@18..19 "(" [] [] + 3: R_PAREN@19..21 ")" [] [Whitespace(" ")] + 4: JS_FUNCTION_BODY@21..40 + 0: L_CURLY@21..22 "{" [] [] + 1: LIST@22..22 + 2: LIST@22..37 + 0: JS_RETURN_STATEMENT@22..37 + 0: RETURN_KW@22..33 "return" [Whitespace("\n ")] [Whitespace(" ")] + 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@33..36 + 0: IDENT@33..36 "foo" [] [] + 2: SEMICOLON@36..37 ";" [] [] + 3: R_CURLY@37..40 "}" [Whitespace("\n ")] [] + 2: R_CURLY@40..42 "}" [Whitespace("\n")] [] + 1: (empty) + 3: EOF@42..43 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_method.js b/crates/rslint_parser/test_data/inline/ok/object_expr_method.js index d7c0ef23dd5..791956320aa 100644 --- a/crates/rslint_parser/test_data/inline/ok/object_expr_method.js +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_method.js @@ -1,6 +1,6 @@ let b = { - foo() {}, - "bar"(a, b, c) {}, - ["foo" + "bar"](a) {}, - 5(...rest) {} +foo() {}, +"bar"(a, b, c) {}, +["foo" + "bar"](a) {}, +5(...rest) {} } diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_method.rast b/crates/rslint_parser/test_data/inline/ok/object_expr_method.rast index a5dcea3ae39..9b155422932 100644 --- a/crates/rslint_parser/test_data/inline/ok/object_expr_method.rast +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_method.rast @@ -1,97 +1,97 @@ -0: JS_ROOT@0..83 +0: JS_ROOT@0..78 0: (empty) 1: LIST@0..0 - 2: LIST@0..82 - 0: JS_VARIABLE_DECLARATION_STATEMENT@0..82 - 0: JS_VARIABLE_DECLARATION@0..82 + 2: LIST@0..77 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..77 + 0: JS_VARIABLE_DECLARATION@0..77 0: LET_KW@0..4 "let" [] [Whitespace(" ")] - 1: LIST@4..82 - 0: JS_VARIABLE_DECLARATOR@4..82 + 1: LIST@4..77 + 0: JS_VARIABLE_DECLARATOR@4..77 0: SINGLE_PATTERN@4..6 0: NAME@4..6 0: IDENT@4..6 "b" [] [Whitespace(" ")] - 1: JS_EQUAL_VALUE_CLAUSE@6..82 + 1: JS_EQUAL_VALUE_CLAUSE@6..77 0: EQ@6..8 "=" [] [Whitespace(" ")] - 1: JS_OBJECT_EXPRESSION@8..82 + 1: JS_OBJECT_EXPRESSION@8..77 0: L_CURLY@8..9 "{" [] [] - 1: LIST@9..80 - 0: JS_METHOD_OBJECT_MEMBER@9..20 - 0: JS_LITERAL_MEMBER_NAME@9..15 - 0: IDENT@9..15 "foo" [Whitespace("\n \t")] [] - 1: JS_PARAMETER_LIST@15..18 - 0: L_PAREN@15..16 "(" [] [] - 1: LIST@16..16 - 2: R_PAREN@16..18 ")" [] [Whitespace(" ")] - 2: JS_FUNCTION_BODY@18..20 - 0: L_CURLY@18..19 "{" [] [] - 1: LIST@19..19 - 2: LIST@19..19 - 3: R_CURLY@19..20 "}" [] [] - 1: COMMA@20..21 "," [] [] - 2: JS_METHOD_OBJECT_MEMBER@21..40 - 0: JS_LITERAL_MEMBER_NAME@21..28 - 0: JS_STRING_LITERAL@21..28 "\"bar\"" [Whitespace("\n\t")] [] - 1: JS_PARAMETER_LIST@28..38 - 0: L_PAREN@28..29 "(" [] [] - 1: LIST@29..36 - 0: SINGLE_PATTERN@29..30 + 1: LIST@9..75 + 0: JS_METHOD_OBJECT_MEMBER@9..18 + 0: JS_LITERAL_MEMBER_NAME@9..13 + 0: IDENT@9..13 "foo" [Whitespace("\n")] [] + 1: JS_PARAMETER_LIST@13..16 + 0: L_PAREN@13..14 "(" [] [] + 1: LIST@14..14 + 2: R_PAREN@14..16 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@16..18 + 0: L_CURLY@16..17 "{" [] [] + 1: LIST@17..17 + 2: LIST@17..17 + 3: R_CURLY@17..18 "}" [] [] + 1: COMMA@18..19 "," [] [] + 2: JS_METHOD_OBJECT_MEMBER@19..37 + 0: JS_LITERAL_MEMBER_NAME@19..25 + 0: JS_STRING_LITERAL@19..25 "\"bar\"" [Whitespace("\n")] [] + 1: JS_PARAMETER_LIST@25..35 + 0: L_PAREN@25..26 "(" [] [] + 1: LIST@26..33 + 0: SINGLE_PATTERN@26..27 + 0: NAME@26..27 + 0: IDENT@26..27 "a" [] [] + 1: COMMA@27..29 "," [] [Whitespace(" ")] + 2: SINGLE_PATTERN@29..30 0: NAME@29..30 - 0: IDENT@29..30 "a" [] [] - 1: COMMA@30..32 "," [] [Whitespace(" ")] - 2: SINGLE_PATTERN@32..33 + 0: IDENT@29..30 "b" [] [] + 3: COMMA@30..32 "," [] [Whitespace(" ")] + 4: SINGLE_PATTERN@32..33 0: NAME@32..33 - 0: IDENT@32..33 "b" [] [] - 3: COMMA@33..35 "," [] [Whitespace(" ")] - 4: SINGLE_PATTERN@35..36 - 0: NAME@35..36 - 0: IDENT@35..36 "c" [] [] - 2: R_PAREN@36..38 ")" [] [Whitespace(" ")] - 2: JS_FUNCTION_BODY@38..40 - 0: L_CURLY@38..39 "{" [] [] - 1: LIST@39..39 - 2: LIST@39..39 - 3: R_CURLY@39..40 "}" [] [] - 3: COMMA@40..41 "," [] [] - 4: JS_METHOD_OBJECT_MEMBER@41..64 - 0: JS_COMPUTED_MEMBER_NAME@41..58 - 0: L_BRACK@41..44 "[" [Whitespace("\n\t")] [] - 1: JS_BINARY_EXPRESSION@44..57 - 0: JS_STRING_LITERAL_EXPRESSION@44..50 - 0: JS_STRING_LITERAL@44..50 "\"foo\"" [] [Whitespace(" ")] - 1: PLUS@50..52 "+" [] [Whitespace(" ")] - 2: JS_STRING_LITERAL_EXPRESSION@52..57 - 0: JS_STRING_LITERAL@52..57 "\"bar\"" [] [] - 2: R_BRACK@57..58 "]" [] [] - 1: JS_PARAMETER_LIST@58..62 - 0: L_PAREN@58..59 "(" [] [] - 1: LIST@59..60 - 0: SINGLE_PATTERN@59..60 - 0: NAME@59..60 - 0: IDENT@59..60 "a" [] [] - 2: R_PAREN@60..62 ")" [] [Whitespace(" ")] - 2: JS_FUNCTION_BODY@62..64 - 0: L_CURLY@62..63 "{" [] [] - 1: LIST@63..63 - 2: LIST@63..63 - 3: R_CURLY@63..64 "}" [] [] - 5: COMMA@64..65 "," [] [] - 6: JS_METHOD_OBJECT_MEMBER@65..80 - 0: JS_LITERAL_MEMBER_NAME@65..68 - 0: JS_NUMBER_LITERAL@65..68 "5" [Whitespace("\n\t")] [] - 1: JS_PARAMETER_LIST@68..78 - 0: L_PAREN@68..69 "(" [] [] - 1: LIST@69..76 - 0: JS_REST_PARAMETER@69..76 - 0: DOT2@69..72 "..." [] [] - 1: SINGLE_PATTERN@72..76 - 0: NAME@72..76 - 0: IDENT@72..76 "rest" [] [] - 2: R_PAREN@76..78 ")" [] [Whitespace(" ")] - 2: JS_FUNCTION_BODY@78..80 - 0: L_CURLY@78..79 "{" [] [] - 1: LIST@79..79 - 2: LIST@79..79 - 3: R_CURLY@79..80 "}" [] [] - 2: R_CURLY@80..82 "}" [Whitespace("\n")] [] + 0: IDENT@32..33 "c" [] [] + 2: R_PAREN@33..35 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@35..37 + 0: L_CURLY@35..36 "{" [] [] + 1: LIST@36..36 + 2: LIST@36..36 + 3: R_CURLY@36..37 "}" [] [] + 3: COMMA@37..38 "," [] [] + 4: JS_METHOD_OBJECT_MEMBER@38..60 + 0: JS_COMPUTED_MEMBER_NAME@38..54 + 0: L_BRACK@38..40 "[" [Whitespace("\n")] [] + 1: JS_BINARY_EXPRESSION@40..53 + 0: JS_STRING_LITERAL_EXPRESSION@40..46 + 0: JS_STRING_LITERAL@40..46 "\"foo\"" [] [Whitespace(" ")] + 1: PLUS@46..48 "+" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@48..53 + 0: JS_STRING_LITERAL@48..53 "\"bar\"" [] [] + 2: R_BRACK@53..54 "]" [] [] + 1: JS_PARAMETER_LIST@54..58 + 0: L_PAREN@54..55 "(" [] [] + 1: LIST@55..56 + 0: SINGLE_PATTERN@55..56 + 0: NAME@55..56 + 0: IDENT@55..56 "a" [] [] + 2: R_PAREN@56..58 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@58..60 + 0: L_CURLY@58..59 "{" [] [] + 1: LIST@59..59 + 2: LIST@59..59 + 3: R_CURLY@59..60 "}" [] [] + 5: COMMA@60..61 "," [] [] + 6: JS_METHOD_OBJECT_MEMBER@61..75 + 0: JS_LITERAL_MEMBER_NAME@61..63 + 0: JS_NUMBER_LITERAL@61..63 "5" [Whitespace("\n")] [] + 1: JS_PARAMETER_LIST@63..73 + 0: L_PAREN@63..64 "(" [] [] + 1: LIST@64..71 + 0: JS_REST_PARAMETER@64..71 + 0: DOT2@64..67 "..." [] [] + 1: SINGLE_PATTERN@67..71 + 0: NAME@67..71 + 0: IDENT@67..71 "rest" [] [] + 2: R_PAREN@71..73 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@73..75 + 0: L_CURLY@73..74 "{" [] [] + 1: LIST@74..74 + 2: LIST@74..74 + 3: R_CURLY@74..75 "}" [] [] + 2: R_CURLY@75..77 "}" [Whitespace("\n")] [] 1: (empty) - 3: EOF@82..83 "" [Whitespace("\n")] [] + 3: EOF@77..78 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_setter.js b/crates/rslint_parser/test_data/inline/ok/object_expr_setter.js new file mode 100644 index 00000000000..326052c01da --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_setter.js @@ -0,0 +1,5 @@ +let b = { + set [foo](bar) { + return 5; + } +} diff --git a/crates/rslint_parser/test_data/inline/ok/object_expr_setter.rast b/crates/rslint_parser/test_data/inline/ok/object_expr_setter.rast new file mode 100644 index 00000000000..f5c7f296cb9 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_expr_setter.rast @@ -0,0 +1,42 @@ +0: JS_ROOT@0..47 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..46 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..46 + 0: JS_VARIABLE_DECLARATION@0..46 + 0: LET_KW@0..4 "let" [] [Whitespace(" ")] + 1: LIST@4..46 + 0: JS_VARIABLE_DECLARATOR@4..46 + 0: SINGLE_PATTERN@4..6 + 0: NAME@4..6 + 0: IDENT@4..6 "b" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@6..46 + 0: EQ@6..8 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@8..46 + 0: L_CURLY@8..9 "{" [] [] + 1: LIST@9..44 + 0: JS_SETTER_OBJECT_MEMBER@9..44 + 0: SET_KW@9..15 "set" [Whitespace("\n ")] [Whitespace(" ")] + 1: JS_COMPUTED_MEMBER_NAME@15..20 + 0: L_BRACK@15..16 "[" [] [] + 1: JS_REFERENCE_IDENTIFIER_EXPRESSION@16..19 + 0: IDENT@16..19 "foo" [] [] + 2: R_BRACK@19..20 "]" [] [] + 2: L_PAREN@20..21 "(" [] [] + 3: SINGLE_PATTERN@21..24 + 0: NAME@21..24 + 0: IDENT@21..24 "bar" [] [] + 4: R_PAREN@24..26 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@26..44 + 0: L_CURLY@26..27 "{" [] [] + 1: LIST@27..27 + 2: LIST@27..41 + 0: JS_RETURN_STATEMENT@27..41 + 0: RETURN_KW@27..39 "return" [Whitespace("\n ")] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@39..40 + 0: JS_NUMBER_LITERAL@39..40 "5" [] [] + 2: SEMICOLON@40..41 ";" [] [] + 3: R_CURLY@41..44 "}" [Whitespace("\n ")] [] + 2: R_CURLY@44..46 "}" [Whitespace("\n")] [] + 1: (empty) + 3: EOF@46..47 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/object_member_name.js b/crates/rslint_parser/test_data/inline/ok/object_member_name.js new file mode 100644 index 00000000000..c5dcdbad15d --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_member_name.js @@ -0,0 +1 @@ +let a = {"foo": foo, [6 + 6]: foo, bar: foo, 7: foo} diff --git a/crates/rslint_parser/test_data/inline/ok/object_member_name.rast b/crates/rslint_parser/test_data/inline/ok/object_member_name.rast new file mode 100644 index 00000000000..838953cd03b --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/object_member_name.rast @@ -0,0 +1,54 @@ +0: JS_ROOT@0..53 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..52 + 0: JS_VARIABLE_DECLARATION_STATEMENT@0..52 + 0: JS_VARIABLE_DECLARATION@0..52 + 0: LET_KW@0..4 "let" [] [Whitespace(" ")] + 1: LIST@4..52 + 0: JS_VARIABLE_DECLARATOR@4..52 + 0: SINGLE_PATTERN@4..6 + 0: NAME@4..6 + 0: IDENT@4..6 "a" [] [Whitespace(" ")] + 1: JS_EQUAL_VALUE_CLAUSE@6..52 + 0: EQ@6..8 "=" [] [Whitespace(" ")] + 1: JS_OBJECT_EXPRESSION@8..52 + 0: L_CURLY@8..9 "{" [] [] + 1: LIST@9..51 + 0: JS_PROPERTY_OBJECT_MEMBER@9..19 + 0: JS_LITERAL_MEMBER_NAME@9..14 + 0: JS_STRING_LITERAL@9..14 "\"foo\"" [] [] + 1: COLON@14..16 ":" [] [Whitespace(" ")] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@16..19 + 0: IDENT@16..19 "foo" [] [] + 1: COMMA@19..21 "," [] [Whitespace(" ")] + 2: JS_PROPERTY_OBJECT_MEMBER@21..33 + 0: JS_COMPUTED_MEMBER_NAME@21..28 + 0: L_BRACK@21..22 "[" [] [] + 1: JS_BINARY_EXPRESSION@22..27 + 0: JS_NUMBER_LITERAL_EXPRESSION@22..24 + 0: JS_NUMBER_LITERAL@22..24 "6" [] [Whitespace(" ")] + 1: PLUS@24..26 "+" [] [Whitespace(" ")] + 2: JS_NUMBER_LITERAL_EXPRESSION@26..27 + 0: JS_NUMBER_LITERAL@26..27 "6" [] [] + 2: R_BRACK@27..28 "]" [] [] + 1: COLON@28..30 ":" [] [Whitespace(" ")] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@30..33 + 0: IDENT@30..33 "foo" [] [] + 3: COMMA@33..35 "," [] [Whitespace(" ")] + 4: JS_PROPERTY_OBJECT_MEMBER@35..43 + 0: JS_LITERAL_MEMBER_NAME@35..38 + 0: IDENT@35..38 "bar" [] [] + 1: COLON@38..40 ":" [] [Whitespace(" ")] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@40..43 + 0: IDENT@40..43 "foo" [] [] + 5: COMMA@43..45 "," [] [Whitespace(" ")] + 6: JS_PROPERTY_OBJECT_MEMBER@45..51 + 0: JS_LITERAL_MEMBER_NAME@45..46 + 0: JS_NUMBER_LITERAL@45..46 "7" [] [] + 1: COLON@46..48 ":" [] [Whitespace(" ")] + 2: JS_REFERENCE_IDENTIFIER_EXPRESSION@48..51 + 0: IDENT@48..51 "foo" [] [] + 2: R_CURLY@51..52 "}" [] [] + 1: (empty) + 3: EOF@52..53 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/postfix_expr.js b/crates/rslint_parser/test_data/inline/ok/postfix_expr.js new file mode 100644 index 00000000000..0ff56e1688a --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/postfix_expr.js @@ -0,0 +1,2 @@ +foo++ +foo-- diff --git a/crates/rslint_parser/test_data/inline/ok/postfix_expr.rast b/crates/rslint_parser/test_data/inline/ok/postfix_expr.rast new file mode 100644 index 00000000000..00b52b9c233 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/postfix_expr.rast @@ -0,0 +1,17 @@ +0: JS_ROOT@0..12 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..11 + 0: JS_EXPRESSION_STATEMENT@0..5 + 0: JS_POST_UPDATE_EXPRESSION@0..5 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@0..3 + 0: IDENT@0..3 "foo" [] [] + 1: PLUS2@3..5 "++" [] [] + 1: (empty) + 1: JS_EXPRESSION_STATEMENT@5..11 + 0: JS_POST_UPDATE_EXPRESSION@5..11 + 0: JS_REFERENCE_IDENTIFIER_EXPRESSION@5..9 + 0: IDENT@5..9 "foo" [Whitespace("\n")] [] + 1: MINUS2@9..11 "--" [] [] + 1: (empty) + 3: EOF@11..12 "" [Whitespace("\n")] [] diff --git a/crates/rslint_parser/test_data/inline/ok/setter_class_number.js b/crates/rslint_parser/test_data/inline/ok/setter_class_number.js new file mode 100644 index 00000000000..4ee19e9f0a9 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/setter_class_number.js @@ -0,0 +1,14 @@ +class Setters { + set foo(a) {} + set static(a) {} + static set bar(a) {} + set "baz"(a) {} + set ["a" + "b"](a) {} + set 5(a) {} + set #private(a) {} +} +class NotSetters { + set(a) {} + async set(a) {} + static set(a) {} +} diff --git a/crates/rslint_parser/test_data/inline/ok/setter_class_number.rast b/crates/rslint_parser/test_data/inline/ok/setter_class_number.rast new file mode 100644 index 00000000000..5cc7fe79a98 --- /dev/null +++ b/crates/rslint_parser/test_data/inline/ok/setter_class_number.rast @@ -0,0 +1,173 @@ +0: JS_ROOT@0..213 + 0: (empty) + 1: LIST@0..0 + 2: LIST@0..212 + 0: JS_CLASS_DECLARATION@0..145 + 0: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@6..14 + 0: IDENT@6..14 "Setters" [] [Whitespace(" ")] + 2: L_CURLY@14..15 "{" [] [] + 3: LIST@15..143 + 0: JS_SETTER_CLASS_MEMBER@15..30 + 0: SET_KW@15..21 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@21..24 + 0: IDENT@21..24 "foo" [] [] + 2: L_PAREN@24..25 "(" [] [] + 3: SINGLE_PATTERN@25..26 + 0: NAME@25..26 + 0: IDENT@25..26 "a" [] [] + 4: R_PAREN@26..28 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@28..30 + 0: L_CURLY@28..29 "{" [] [] + 1: LIST@29..29 + 2: LIST@29..29 + 3: R_CURLY@29..30 "}" [] [] + 1: JS_SETTER_CLASS_MEMBER@30..48 + 0: SET_KW@30..36 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@36..42 + 0: IDENT@36..42 "static" [] [] + 2: L_PAREN@42..43 "(" [] [] + 3: SINGLE_PATTERN@43..44 + 0: NAME@43..44 + 0: IDENT@43..44 "a" [] [] + 4: R_PAREN@44..46 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@46..48 + 0: L_CURLY@46..47 "{" [] [] + 1: LIST@47..47 + 2: LIST@47..47 + 3: R_CURLY@47..48 "}" [] [] + 2: JS_SETTER_CLASS_MEMBER@48..70 + 0: STATIC_KW@48..57 "static" [Whitespace("\n\t")] [Whitespace(" ")] + 1: SET_KW@57..61 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@61..64 + 0: IDENT@61..64 "bar" [] [] + 3: L_PAREN@64..65 "(" [] [] + 4: SINGLE_PATTERN@65..66 + 0: NAME@65..66 + 0: IDENT@65..66 "a" [] [] + 5: R_PAREN@66..68 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@68..70 + 0: L_CURLY@68..69 "{" [] [] + 1: LIST@69..69 + 2: LIST@69..69 + 3: R_CURLY@69..70 "}" [] [] + 3: JS_SETTER_CLASS_MEMBER@70..87 + 0: SET_KW@70..76 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@76..81 + 0: JS_STRING_LITERAL@76..81 "\"baz\"" [] [] + 2: L_PAREN@81..82 "(" [] [] + 3: SINGLE_PATTERN@82..83 + 0: NAME@82..83 + 0: IDENT@82..83 "a" [] [] + 4: R_PAREN@83..85 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@85..87 + 0: L_CURLY@85..86 "{" [] [] + 1: LIST@86..86 + 2: LIST@86..86 + 3: R_CURLY@86..87 "}" [] [] + 4: JS_SETTER_CLASS_MEMBER@87..110 + 0: SET_KW@87..93 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_COMPUTED_MEMBER_NAME@93..104 + 0: L_BRACK@93..94 "[" [] [] + 1: JS_BINARY_EXPRESSION@94..103 + 0: JS_STRING_LITERAL_EXPRESSION@94..98 + 0: JS_STRING_LITERAL@94..98 "\"a\"" [] [Whitespace(" ")] + 1: PLUS@98..100 "+" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@100..103 + 0: JS_STRING_LITERAL@100..103 "\"b\"" [] [] + 2: R_BRACK@103..104 "]" [] [] + 2: L_PAREN@104..105 "(" [] [] + 3: SINGLE_PATTERN@105..106 + 0: NAME@105..106 + 0: IDENT@105..106 "a" [] [] + 4: R_PAREN@106..108 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@108..110 + 0: L_CURLY@108..109 "{" [] [] + 1: LIST@109..109 + 2: LIST@109..109 + 3: R_CURLY@109..110 "}" [] [] + 5: JS_SETTER_CLASS_MEMBER@110..123 + 0: SET_KW@110..116 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@116..117 + 0: JS_NUMBER_LITERAL@116..117 "5" [] [] + 2: L_PAREN@117..118 "(" [] [] + 3: SINGLE_PATTERN@118..119 + 0: NAME@118..119 + 0: IDENT@118..119 "a" [] [] + 4: R_PAREN@119..121 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@121..123 + 0: L_CURLY@121..122 "{" [] [] + 1: LIST@122..122 + 2: LIST@122..122 + 3: R_CURLY@122..123 "}" [] [] + 6: JS_SETTER_CLASS_MEMBER@123..143 + 0: SET_KW@123..129 "set" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_PRIVATE_CLASS_MEMBER_NAME@129..137 + 0: HASH@129..130 "#" [] [] + 1: IDENT@130..137 "private" [] [] + 2: L_PAREN@137..138 "(" [] [] + 3: SINGLE_PATTERN@138..139 + 0: NAME@138..139 + 0: IDENT@138..139 "a" [] [] + 4: R_PAREN@139..141 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@141..143 + 0: L_CURLY@141..142 "{" [] [] + 1: LIST@142..142 + 2: LIST@142..142 + 3: R_CURLY@142..143 "}" [] [] + 4: R_CURLY@143..145 "}" [Whitespace("\n")] [] + 1: JS_CLASS_DECLARATION@145..212 + 0: CLASS_KW@145..152 "class" [Whitespace("\n")] [Whitespace(" ")] + 1: JS_IDENTIFIER_BINDING@152..163 + 0: IDENT@152..163 "NotSetters" [] [Whitespace(" ")] + 2: L_CURLY@163..164 "{" [] [] + 3: LIST@164..210 + 0: JS_METHOD_CLASS_MEMBER@164..175 + 0: JS_LITERAL_MEMBER_NAME@164..169 + 0: IDENT@164..169 "set" [Whitespace("\n\t")] [] + 1: JS_PARAMETER_LIST@169..173 + 0: L_PAREN@169..170 "(" [] [] + 1: LIST@170..171 + 0: SINGLE_PATTERN@170..171 + 0: NAME@170..171 + 0: IDENT@170..171 "a" [] [] + 2: R_PAREN@171..173 ")" [] [Whitespace(" ")] + 2: JS_FUNCTION_BODY@173..175 + 0: L_CURLY@173..174 "{" [] [] + 1: LIST@174..174 + 2: LIST@174..174 + 3: R_CURLY@174..175 "}" [] [] + 1: JS_METHOD_CLASS_MEMBER@175..192 + 0: ASYNC_KW@175..183 "async" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@183..186 + 0: IDENT@183..186 "set" [] [] + 2: JS_PARAMETER_LIST@186..190 + 0: L_PAREN@186..187 "(" [] [] + 1: LIST@187..188 + 0: SINGLE_PATTERN@187..188 + 0: NAME@187..188 + 0: IDENT@187..188 "a" [] [] + 2: R_PAREN@188..190 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@190..192 + 0: L_CURLY@190..191 "{" [] [] + 1: LIST@191..191 + 2: LIST@191..191 + 3: R_CURLY@191..192 "}" [] [] + 2: JS_METHOD_CLASS_MEMBER@192..210 + 0: STATIC_KW@192..201 "static" [Whitespace("\n\t")] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@201..204 + 0: IDENT@201..204 "set" [] [] + 2: JS_PARAMETER_LIST@204..208 + 0: L_PAREN@204..205 "(" [] [] + 1: LIST@205..206 + 0: SINGLE_PATTERN@205..206 + 0: NAME@205..206 + 0: IDENT@205..206 "a" [] [] + 2: R_PAREN@206..208 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@208..210 + 0: L_CURLY@208..209 "{" [] [] + 1: LIST@209..209 + 2: LIST@209..209 + 3: R_CURLY@209..210 "}" [] [] + 4: R_CURLY@210..212 "}" [Whitespace("\n")] [] + 3: EOF@212..213 "" [Whitespace("\n")] []