diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index 7f9d23c8d..b88097408 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -1770,6 +1770,20 @@ impl<'a> AstBuilder<'a> { })) } + #[inline] + pub fn ts_instantiation_expression( + &self, + span: Span, + expression: Expression<'a>, + type_parameters: Box<'a, TSTypeParameterInstantiation<'a>>, + ) -> Expression<'a> { + Expression::TSInstantiationExpression(self.alloc(TSInstantiationExpression { + span, + expression, + type_parameters, + })) + } + #[inline] pub fn ts_non_null_expression(&self, span: Span, expression: Expression<'a>) -> Expression<'a> { Expression::TSNonNullExpression(self.alloc(TSNonNullExpression { span, expression })) diff --git a/crates/oxc_parser/src/js/arrow.rs b/crates/oxc_parser/src/js/arrow.rs index 57b95fa43..7c034da51 100644 --- a/crates/oxc_parser/src/js/arrow.rs +++ b/crates/oxc_parser/src/js/arrow.rs @@ -2,8 +2,9 @@ use oxc_allocator::Box; use oxc_ast::ast::*; use oxc_diagnostics::Result; use oxc_span::{GetSpan, Span}; +use oxc_syntax::precedence::Precedence; -use crate::{diagnostics, lexer::Kind, AstBuilder, ParserImpl}; +use crate::{diagnostics, lexer::Kind, ParserImpl}; use super::Tristate; @@ -34,8 +35,9 @@ impl<'a> ParserImpl<'a> { { let span = self.start_span(); self.bump_any(); // bump `async` + let expr = self.parse_binary_expression_or_higher(Precedence::lowest())?; return self - .parse_simple_arrow_function_expression(span, /* is_async */ true) + .parse_simple_arrow_function_expression(span, expr, /* async */ true) .map(Some); } Ok(None) @@ -186,7 +188,7 @@ impl<'a> ParserImpl<'a> { } // Check for un-parenthesized AsyncArrowFunction if first.is_binding_identifier() { - // Arrow before newline is checkedin `parse_simple_arrow_function_expression` + // Arrow before newline is checked in `parse_simple_arrow_function_expression` if self.nth_at(2, Kind::Arrow) { return Tristate::True; } @@ -198,24 +200,24 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_simple_arrow_function_expression( &mut self, span: Span, + ident: Expression<'a>, r#async: bool, ) -> Result> { let has_await = self.ctx.has_await(); self.ctx = self.ctx.union_await_if(r#async); let params = { - let params_span = self.start_span(); - let param = self.parse_binding_identifier()?; - let ident = self.ast.binding_pattern_identifier(param); - let params_span = self.end_span(params_span); - let formal_parameter = self.ast.formal_parameter( - params_span, - self.ast.binding_pattern(ident, None, false), - None, - false, - false, - AstBuilder::new_vec(&self.ast), - ); + let ident = match ident { + Expression::Identifier(ident) => { + let name = ident.name.clone(); + BindingIdentifier::new(ident.span, name) + } + _ => unreachable!(), + }; + let params_span = self.end_span(ident.span); + let ident = self.ast.binding_pattern_identifier(ident); + let pattern = self.ast.binding_pattern(ident, None, false); + let formal_parameter = self.ast.plain_formal_parameter(params_span, pattern); self.ast.formal_parameters( params_span, FormalParameterKind::ArrowFormalParameters, diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index a8628798c..dd40975e6 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -122,7 +122,7 @@ impl<'a> ParserImpl<'a> { let mut extends = self.ast.new_vec(); let span = self.start_span(); - let mut first_extends = self.parse_lhs_expression()?; + let mut first_extends = self.parse_lhs_expression_or_higher()?; let first_type_argument; if let Expression::TSInstantiationExpression(expr) = first_extends { let expr = expr.unbox(); @@ -135,7 +135,7 @@ impl<'a> ParserImpl<'a> { while self.eat(Kind::Comma) { let span = self.start_span(); - let mut extend = self.parse_lhs_expression()?; + let mut extend = self.parse_lhs_expression_or_higher()?; let type_argument; if let Expression::TSInstantiationExpression(expr) = extend { let expr = expr.unbox(); diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 1e7f2c2bf..6228b82f0 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -115,11 +115,11 @@ impl<'a> ParserImpl<'a> { pub(crate) fn check_identifier(&mut self, span: Span, name: &Atom) { // It is a Syntax Error if this production has an [Await] parameter. - if self.ctx.has_await() && *name == "await" { + if self.ctx.has_await() && name.as_str() == "await" { self.error(diagnostics::identifier_async("await", span)); } // It is a Syntax Error if this production has a [Yield] parameter. - if self.ctx.has_yield() && *name == "yield" { + if self.ctx.has_yield() && name.as_str() == "yield" { self.error(diagnostics::identifier_generator("yield", span)); } } @@ -498,11 +498,11 @@ impl<'a> ParserImpl<'a> { } /// Section 13.3 Left-Hand-Side Expression - pub(crate) fn parse_lhs_expression(&mut self) -> Result> { + pub(crate) fn parse_lhs_expression_or_higher(&mut self) -> Result> { let span = self.start_span(); let mut in_optional_chain = false; - let lhs = self.parse_member_expression_base(&mut in_optional_chain)?; - let lhs = self.parse_call_expression(span, lhs, &mut in_optional_chain)?; + let lhs = self.parse_member_expression_or_higher(&mut in_optional_chain)?; + let lhs = self.parse_call_expression_rest(span, lhs, &mut in_optional_chain)?; if in_optional_chain { let span = self.end_span(span); Ok(self.map_to_chain_expression(span, lhs)) @@ -525,13 +525,13 @@ impl<'a> ParserImpl<'a> { } /// Section 13.3 Member Expression - fn parse_member_expression_base( + fn parse_member_expression_or_higher( &mut self, in_optional_chain: &mut bool, ) -> Result> { let span = self.start_span(); self.parse_primary_expression() - .and_then(|lhs| self.parse_member_expression_rhs(span, lhs, in_optional_chain)) + .and_then(|lhs| self.parse_member_expression_rest(span, lhs, in_optional_chain)) } /// Section 13.3 Super Call @@ -554,7 +554,7 @@ impl<'a> ParserImpl<'a> { } /// parse rhs of a member expression, starting from lhs - fn parse_member_expression_rhs( + fn parse_member_expression_rest( &mut self, lhs_span: Span, lhs: Expression<'a>, @@ -600,15 +600,15 @@ impl<'a> ParserImpl<'a> { }; self.parse_tagged_template(lhs_span, expr, *in_optional_chain, type_parameters)? } - Kind::LAngle | Kind::ShiftLeft if self.ts_enabled() => { - if let Some(arguments) = self.parse_ts_type_arguments_in_expression() { - lhs = Expression::TSInstantiationExpression(self.ast.alloc( - TSInstantiationExpression { - span: self.end_span(lhs_span), - expression: lhs, - type_parameters: arguments, - }, - )); + Kind::LAngle | Kind::ShiftLeft => { + if let Ok(Some(arguments)) = + self.try_parse(Self::parse_ts_type_arguments_in_expression) + { + lhs = self.ast.ts_instantiation_expression( + self.end_span(lhs_span), + lhs, + arguments, + ); continue; } break; @@ -667,7 +667,7 @@ impl<'a> ParserImpl<'a> { let rhs_span = self.start_span(); let mut optional = false; - let mut callee = self.parse_member_expression_base(&mut optional)?; + let mut callee = self.parse_member_expression_or_higher(&mut optional)?; let mut type_parameter = None; if let Expression::TSInstantiationExpression(instantiation_expr) = callee { @@ -699,7 +699,7 @@ impl<'a> ParserImpl<'a> { } /// Section 13.3 Call Expression - fn parse_call_expression( + fn parse_call_expression_rest( &mut self, lhs_span: Span, lhs: Expression<'a>, @@ -708,12 +708,15 @@ impl<'a> ParserImpl<'a> { let mut lhs = lhs; loop { let mut type_arguments = None; - lhs = self.parse_member_expression_rhs(lhs_span, lhs, in_optional_chain)?; + lhs = self.parse_member_expression_rest(lhs_span, lhs, in_optional_chain)?; let optional_call = self.eat(Kind::QuestionDot); *in_optional_chain = if optional_call { true } else { *in_optional_chain }; if optional_call { - type_arguments = self.parse_ts_type_arguments_in_expression(); + if let Ok(Some(args)) = self.try_parse(Self::parse_ts_type_arguments_in_expression) + { + type_arguments = Some(args); + } if self.cur_kind().is_template_start_of_tagged_template() { lhs = self.parse_tagged_template(lhs_span, lhs, optional_call, type_arguments)?; @@ -758,9 +761,31 @@ impl<'a> ParserImpl<'a> { } /// Section 13.4 Update Expression - fn parse_update_expression(&mut self) -> Result> { + fn parse_update_expression(&mut self, lhs_span: Span) -> Result> { + let kind = self.cur_kind(); + // ++ -- prefix update expressions + if kind.is_update_operator() { + let operator = map_update_operator(kind); + self.bump_any(); + let argument = self.parse_unary_expression_or_higher(lhs_span)?; + let argument = SimpleAssignmentTarget::cover(argument, self)?; + return Ok(self.ast.update_expression( + self.end_span(lhs_span), + operator, + true, + argument, + )); + } + + if self.source_type.is_jsx() + && kind == Kind::LAngle + && self.peek_kind().is_identifier_name() + { + return self.parse_jsx_expression(); + } + let span = self.start_span(); - let lhs = self.parse_lhs_expression()?; + let lhs = self.parse_lhs_expression_or_higher()?; // ++ -- postfix update expressions if self.cur_kind().is_update_operator() && !self.cur_token().is_on_new_line { let operator = map_update_operator(self.cur_kind()); @@ -772,50 +797,46 @@ impl<'a> ParserImpl<'a> { } /// Section 13.5 Unary Expression - pub(crate) fn parse_unary_expression_base(&mut self, lhs_span: Span) -> Result> { - // [+Await] AwaitExpression - if self.is_await_expression() { - return self.parse_await_expression(lhs_span); - } - - if (self.at(Kind::LAngle) || self.at(Kind::ShiftLeft)) - && !self.source_type.is_jsx() - && self.ts_enabled() - { - return self.parse_ts_type_assertion(); - } - + pub(crate) fn parse_unary_expression_or_higher( + &mut self, + lhs_span: Span, + ) -> Result> { // ++ -- prefix update expressions - if self.cur_kind().is_update_operator() { - let operator = map_update_operator(self.cur_kind()); - self.bump_any(); - let argument = self.parse_unary_expression_base(lhs_span)?; - let argument = SimpleAssignmentTarget::cover(argument, self)?; - return Ok(self.ast.update_expression( - self.end_span(lhs_span), - operator, - true, - argument, - )); + if self.is_update_expression() { + return self.parse_update_expression(lhs_span); } + self.parse_simple_unary_expression(lhs_span) + } - // delete void typeof + - ~ ! prefix unary expressions - if self.cur_kind().is_unary_operator() { - return self.parse_unary_expression(); + pub(crate) fn parse_simple_unary_expression( + &mut self, + lhs_span: Span, + ) -> Result> { + match self.cur_kind() { + kind if kind.is_unary_operator() => self.parse_unary_expression(), + Kind::LAngle => { + if self.source_type.is_jsx() { + return self.parse_jsx_expression(); + } + if self.ts_enabled() { + return self.parse_ts_type_assertion(); + } + Err(self.unexpected()) + } + Kind::Await if self.is_await_expression() => self.parse_await_expression(lhs_span), + _ => self.parse_update_expression(lhs_span), } - - self.parse_update_expression() } fn parse_unary_expression(&mut self) -> Result> { let span = self.start_span(); let operator = map_unary_operator(self.cur_kind()); self.bump_any(); - let argument = self.parse_unary_expression_base(span)?; + let argument = self.parse_simple_unary_expression(span)?; Ok(self.ast.unary_expression(self.end_span(span), operator, argument)) } - fn parse_binary_or_logical_expression_base( + pub(crate) fn parse_binary_expression_or_higher( &mut self, lhs_precedence: Precedence, ) -> Result> { @@ -824,7 +845,7 @@ impl<'a> ParserImpl<'a> { let lhs = if self.ctx.has_in() && self.at(Kind::PrivateIdentifier) { let left = self.parse_private_identifier(); self.expect(Kind::In)?; - let right = self.parse_unary_expression_base(lhs_span)?; + let right = self.parse_unary_expression_or_higher(lhs_span)?; Expression::PrivateInExpression(self.ast.alloc(PrivateInExpression { span: self.end_span(lhs_span), left, @@ -832,14 +853,14 @@ impl<'a> ParserImpl<'a> { right, })) } else { - self.parse_unary_expression_base(lhs_span)? + self.parse_unary_expression_or_higher(lhs_span)? }; - self.parse_binary_or_logical_expression_recursive(lhs_span, lhs, lhs_precedence) + self.parse_binary_expression_rest(lhs_span, lhs, lhs_precedence) } /// Section 13.6 - 13.13 Binary Expression - fn parse_binary_or_logical_expression_recursive( + fn parse_binary_expression_rest( &mut self, lhs_span: Span, lhs: Expression<'a>, @@ -888,7 +909,7 @@ impl<'a> ParserImpl<'a> { } self.bump_any(); // bump operator - let rhs = self.parse_binary_or_logical_expression_base(left_precedence)?; + let rhs = self.parse_binary_expression_or_higher(left_precedence)?; lhs = if kind.is_logical_operator() { self.ast.logical_expression( @@ -916,9 +937,11 @@ impl<'a> ParserImpl<'a> { /// `ConditionalExpression`[In, Yield, Await] : /// `ShortCircuitExpression`[?In, ?Yield, ?Await] /// `ShortCircuitExpression`[?In, ?Yield, ?Await] ? `AssignmentExpression`[+In, ?Yield, ?Await] : `AssignmentExpression`[?In, ?Yield, ?Await] - fn parse_conditional_expression(&mut self) -> Result> { - let span = self.start_span(); - let lhs = self.parse_binary_or_logical_expression_base(Precedence::lowest())?; + fn parse_conditional_expression_rest( + &mut self, + lhs_span: Span, + lhs: Expression<'a>, + ) -> Result> { if !self.eat(Kind::Question) { return Ok(lhs); } @@ -929,7 +952,7 @@ impl<'a> ParserImpl<'a> { )?; self.expect(Kind::Colon)?; let alternate = self.parse_assignment_expression_or_higher()?; - Ok(self.ast.conditional_expression(self.end_span(span), lhs, consequent, alternate)) + Ok(self.ast.conditional_expression(self.end_span(lhs_span), lhs, consequent, alternate)) } /// `AssignmentExpression`[In, Yield, Await] : @@ -946,13 +969,21 @@ impl<'a> ParserImpl<'a> { if let Some(arrow_expr) = self.try_parse_async_simple_arrow_function_expression()? { return Ok(arrow_expr); } + let span = self.start_span(); + let lhs = self.parse_binary_expression_or_higher(Precedence::lowest())?; + let kind = self.cur_kind(); + // `x => {}` - if self.cur_kind().is_binding_identifier() && self.peek_at(Kind::Arrow) { - return self.parse_simple_arrow_function_expression(span, /* r#async */ false); + if lhs.is_identifier_reference() && kind == Kind::Arrow { + return self.parse_simple_arrow_function_expression(span, lhs, /* async */ false); } - let lhs = self.parse_conditional_expression()?; - self.parse_assignment_expression_recursive(span, lhs) + + if kind.is_assignment_operator() { + return self.parse_assignment_expression_recursive(span, lhs); + } + + self.parse_conditional_expression_rest(span, lhs) } fn parse_assignment_expression_recursive( @@ -960,12 +991,7 @@ impl<'a> ParserImpl<'a> { span: Span, lhs: Expression<'a>, ) -> Result> { - if !self.cur_kind().is_assignment_operator() { - return Ok(lhs); - } - let operator = map_assignment_operator(self.cur_kind()); - // 13.15.5 Destructuring Assignment // LeftHandSideExpression = AssignmentExpression // is converted to @@ -973,9 +999,7 @@ impl<'a> ParserImpl<'a> { // ObjectAssignmentPattern // ArrayAssignmentPattern let left = AssignmentTarget::cover(lhs, self)?; - self.bump_any(); - let right = self.parse_assignment_expression_or_higher()?; Ok(self.ast.assignment_expression(self.end_span(span), operator, left, right)) } @@ -1004,7 +1028,7 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::await_expression(Span::new(span.start, span.start + 5))); } let argument = self.context(Context::Await, Context::empty(), |p| { - p.parse_unary_expression_base(lhs_span) + p.parse_simple_unary_expression(lhs_span) })?; Ok(self.ast.await_expression(self.end_span(span), argument)) } @@ -1016,18 +1040,38 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_decorator(&mut self) -> Result> { let span = self.start_span(); self.bump_any(); // bump @ - let expr = - self.context(Context::Decorator, Context::empty(), Self::parse_lhs_expression)?; + let expr = self.context( + Context::Decorator, + Context::empty(), + Self::parse_lhs_expression_or_higher, + )?; Ok(self.ast.decorator(self.end_span(span), expr)) } + fn is_update_expression(&self) -> bool { + match self.cur_kind() { + kind if kind.is_unary_operator() => false, + Kind::Await => false, + Kind::LAngle => { + if !self.source_type.is_jsx() { + return false; + } + true + } + _ => true, + } + } + fn is_await_expression(&mut self) -> bool { if self.at(Kind::Await) { + let peek_token = self.peek_token(); + // Allow arrow expression `await => {}` + if peek_token.kind == Kind::Arrow { + return false; + } if self.ctx.has_await() { return true; } - - let peek_token = self.peek_token(); // The following expressions are ambiguous // await + 0, await - 0, await ( 0 ), await [ 0 ], await / 0 /u, await ``, await of [] if matches!( @@ -1037,7 +1081,7 @@ impl<'a> ParserImpl<'a> { return false; } - return peek_token.kind.is_after_await_or_yield() && !peek_token.is_on_new_line; + return !peek_token.is_on_new_line && peek_token.kind.is_after_await_or_yield(); } false } @@ -1045,13 +1089,14 @@ impl<'a> ParserImpl<'a> { fn is_yield_expression(&mut self) -> bool { if self.at(Kind::Yield) { let peek_token = self.peek_token(); + // Allow arrow expression `yield => {}` if peek_token.kind == Kind::Arrow { return false; } if self.ctx.has_yield() { return true; } - return peek_token.kind.is_after_await_or_yield() && !peek_token.is_on_new_line; + return !peek_token.is_on_new_line && peek_token.kind.is_after_await_or_yield(); } false } diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 5f17d1351..f454e969c 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -359,7 +359,7 @@ impl<'a> ParserImpl<'a> { let type_annotation = self.parse_ts_type()?; self.expect(Kind::RAngle)?; let lhs_span = self.start_span(); - let expression = self.parse_unary_expression_base(lhs_span)?; + let expression = self.parse_simple_unary_expression(lhs_span)?; Ok(self.ast.ts_type_assertion(self.end_span(span), type_annotation, expression)) } diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index 21d4a461a..a08c0b13c 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -532,25 +532,26 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_ts_type_arguments_in_expression( &mut self, - ) -> Option>> { - if !matches!(self.cur_kind(), Kind::LAngle | Kind::ShiftLeft) { - return None; + ) -> Result>>> { + if !self.ts_enabled() { + return Ok(None); } + let span = self.start_span(); + self.re_lex_ts_l_angle(); + if !self.at(Kind::LAngle) { + return Ok(None); + } - self.try_parse(|p| { - p.re_lex_ts_l_angle(); + let params = TSTypeArgumentList::parse(self, /* in_expression */ true)?.params; - let params = TSTypeArgumentList::parse(p, true)?.params; - let token = p.cur_token(); - if token.is_on_new_line || token.kind.can_follow_type_arguments_in_expr() { - Ok(params) - } else { - Err(p.unexpected()) - } - }) - .ok() - .map(|types| self.ast.ts_type_arguments(self.end_span(span), types)) + let token = self.cur_token(); + + if token.is_on_new_line || token.kind.can_follow_type_arguments_in_expr() { + return Ok(Some(self.ast.ts_type_arguments(self.end_span(span), params))); + } + + Err(self.unexpected()) } fn parse_ts_tuple_type(&mut self) -> Result> { diff --git a/tasks/coverage/parser_babel.snap b/tasks/coverage/parser_babel.snap index eb3223105..45959e372 100644 --- a/tasks/coverage/parser_babel.snap +++ b/tasks/coverage/parser_babel.snap @@ -3,7 +3,7 @@ commit: 4bd1b2c2 parser_babel Summary: AST Parsed : 2093/2099 (99.71%) Positive Passed: 2086/2099 (99.38%) -Negative Passed: 1363/1501 (90.81%) +Negative Passed: 1362/1501 (90.74%) Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js" @@ -25,6 +25,7 @@ Expect Syntax Error: "es2015/for-of/invalid-let-as-identifier/input.js" Expect Syntax Error: "es2015/object/disallow-duplicate-method-params/input.js" Expect Syntax Error: "es2015/uncategorised/297/input.js" Expect Syntax Error: "es2015/uncategorised/335/input.js" +Expect Syntax Error: "es2017/async-functions/async-await-as-arrow-binding-identifier/input.js" Expect Syntax Error: "es2017/async-functions/await-binding-inside-arrow-params-inside-async-arrow-params/input.js" Expect Syntax Error: "es2017/trailing-function-commas/7/input.js" Expect Syntax Error: "es2018/object-rest-spread/24/input.js" @@ -4842,12 +4843,6 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts" 3 │ } ╰──── - × Cannot use `await` as an identifier in an async context - ╭─[es2017/async-functions/async-await-as-arrow-binding-identifier/input.js:1:7] - 1 │ async await => {} - · ───── - ╰──── - × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[es2017/async-functions/async-function-and-non-bmp-character/input.js:1:6] 1 │ async function𝐬 f() {} diff --git a/tasks/coverage/parser_typescript.snap b/tasks/coverage/parser_typescript.snap index f57a532e7..e0e35cdeb 100644 --- a/tasks/coverage/parser_typescript.snap +++ b/tasks/coverage/parser_typescript.snap @@ -3,7 +3,7 @@ commit: 64d2eeea parser_typescript Summary: AST Parsed : 5240/5243 (99.94%) Positive Passed: 5233/5243 (99.81%) -Negative Passed: 1064/4879 (21.81%) +Negative Passed: 1065/4879 (21.83%) Expect Syntax Error: "compiler/ClassDeclaration10.ts" Expect Syntax Error: "compiler/ClassDeclaration11.ts" Expect Syntax Error: "compiler/ClassDeclaration13.ts" @@ -58,7 +58,6 @@ Expect Syntax Error: "compiler/ambientExternalModuleWithRelativeModuleName.ts" Expect Syntax Error: "compiler/ambientGetters.ts" Expect Syntax Error: "compiler/ambientPropertyDeclarationInJs.ts" Expect Syntax Error: "compiler/ambientStatement1.ts" -Expect Syntax Error: "compiler/ambiguousGenericAssertion1.ts" Expect Syntax Error: "compiler/ambiguousOverload.ts" Expect Syntax Error: "compiler/amdDependencyComment1.ts" Expect Syntax Error: "compiler/amdDependencyComment2.ts" @@ -4123,6 +4122,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 26 │ } ╰──── + × Unexpected token + ╭─[compiler/ambiguousGenericAssertion1.ts:4:10] + 3 │ var r2 = < (x: T) => T>f; // valid + 4 │ var r3 = <(x: T) => T>f; // ambiguous, appears to the parser as a << operation + · ── + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[compiler/anonymousModules.ts:1:7] 1 │ module { @@ -5365,10 +5371,10 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── × Unexpected token - ╭─[compiler/conflictMarkerDiff3Trivia2.ts:3:2] + ╭─[compiler/conflictMarkerDiff3Trivia2.ts:3:1] 2 │ foo() { 3 │ <<<<<<< B - · ── + · ── 4 │ a(); ╰──── @@ -5381,10 +5387,10 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── × Unexpected token - ╭─[compiler/conflictMarkerTrivia2.ts:3:2] + ╭─[compiler/conflictMarkerTrivia2.ts:3:1] 2 │ foo() { 3 │ <<<<<<< B - · ── + · ── 4 │ a(); ╰──── @@ -5396,10 +5402,10 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── × Unexpected token - ╭─[compiler/conflictMarkerTrivia4.ts:2:2] + ╭─[compiler/conflictMarkerTrivia4.ts:2:1] 1 │ const x =
2 │ <<<<<<< HEAD - · ── + · ── ╰──── × Identifier `y` has already been declared