refactor(parser): simplify Context passing (#3266)

This commit is contained in:
Boshen 2024-05-14 12:22:27 +08:00 committed by GitHub
parent c4ccf9f4d8
commit b27a905958
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 84 additions and 121 deletions

View file

@ -294,31 +294,16 @@ impl<'a> ParserImpl<'a> {
answer answer
} }
pub(crate) fn without_context<F, T>(&mut self, flags: Context, cb: F) -> T #[allow(clippy::inline_always)]
#[inline(always)] // inline because this is always on a hot path
pub(crate) fn context<F, T>(&mut self, add_flags: Context, remove_flags: Context, cb: F) -> T
where where
F: FnOnce(&mut Self) -> T, F: FnOnce(&mut Self) -> T,
{ {
let context_flags_to_clear = flags & self.ctx; let ctx = self.ctx;
if !context_flags_to_clear.is_empty() { self.ctx = ctx.difference(remove_flags).union(add_flags);
self.ctx &= !context_flags_to_clear; let result = cb(self);
let result = cb(self); self.ctx = ctx;
self.ctx |= context_flags_to_clear; result
return result;
}
cb(self)
}
pub(crate) fn with_context<F, T>(&mut self, flags: Context, cb: F) -> T
where
F: FnOnce(&mut Self) -> T,
{
let context_flags_to_set = flags & !self.ctx;
if !context_flags_to_set.is_empty() {
self.ctx |= context_flags_to_set;
let result = cb(self);
self.ctx &= !context_flags_to_set;
return result;
}
cb(self)
} }
} }

View file

@ -13,7 +13,7 @@ impl<'a> ParserImpl<'a> {
pub(super) fn parse_binding_pattern_with_initializer(&mut self) -> Result<BindingPattern<'a>> { pub(super) fn parse_binding_pattern_with_initializer(&mut self) -> Result<BindingPattern<'a>> {
let span = self.start_span(); let span = self.start_span();
let pattern = self.parse_binding_pattern(true)?; let pattern = self.parse_binding_pattern(true)?;
self.with_context(Context::In, |p| p.parse_initializer(span, pattern)) self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, pattern))
} }
pub(super) fn parse_binding_pattern( pub(super) fn parse_binding_pattern(
@ -74,8 +74,8 @@ impl<'a> ParserImpl<'a> {
let type_annotation = self.parse_ts_type_annotation()?; let type_annotation = self.parse_ts_type_annotation()?;
let pattern = self.ast.binding_pattern(kind, type_annotation, false); let pattern = self.ast.binding_pattern(kind, type_annotation, false);
// Rest element does not allow `= initializer`, . // Rest element does not allow `= initializer`, .
let argument = let argument = self
self.with_context(Context::In, |p| p.parse_initializer(init_span, pattern))?; .context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?;
let span = self.end_span(span); let span = self.end_span(span);
if self.at(Kind::Comma) { if self.at(Kind::Comma) {
@ -110,7 +110,7 @@ impl<'a> ParserImpl<'a> {
let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone()); let binding_identifier = BindingIdentifier::new(ident.span, ident.name.clone());
let identifier = self.ast.binding_pattern_identifier(binding_identifier); let identifier = self.ast.binding_pattern_identifier(binding_identifier);
let left = self.ast.binding_pattern(identifier, None, false); let left = self.ast.binding_pattern(identifier, None, false);
self.with_context(Context::In, |p| p.parse_initializer(span, left))? self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left))?
} else { } else {
return Err(self.unexpected()); return Err(self.unexpected());
} }

View file

@ -4,7 +4,7 @@ use oxc_diagnostics::Result;
use oxc_span::{GetSpan, Span}; use oxc_span::{GetSpan, Span};
use super::list::ClassElements; use super::list::ClassElements;
use crate::{diagnostics, lexer::Kind, list::NormalList, ParserImpl, StatementContext}; use crate::{diagnostics, lexer::Kind, list::NormalList, Context, ParserImpl, StatementContext};
type Extends<'a> = type Extends<'a> =
Vec<'a, (Expression<'a>, Option<Box<'a, TSTypeParameterInstantiation<'a>>>, Span)>; Vec<'a, (Expression<'a>, Option<Box<'a, TSTypeParameterInstantiation<'a>>>, Span)>;
@ -452,12 +452,8 @@ impl<'a> ParserImpl<'a> {
/// `ClassStaticBlockStatementList` : /// `ClassStaticBlockStatementList` :
/// `StatementList`[~Yield, +Await, ~Return] /// `StatementList`[~Yield, +Await, ~Return]
fn parse_class_static_block(&mut self, span: Span) -> Result<ClassElement<'a>> { fn parse_class_static_block(&mut self, span: Span) -> Result<ClassElement<'a>> {
let has_await = self.ctx.has_await(); let block =
let has_yield = self.ctx.has_yield(); self.context(Context::Await, Context::Yield | Context::Return, Self::parse_block)?;
let has_return = self.ctx.has_return();
self.ctx = self.ctx.and_await(true).and_yield(false).and_return(false);
let block = self.parse_block()?;
self.ctx = self.ctx.and_await(has_await).and_yield(has_yield).and_return(has_return);
Ok(self.ast.static_block(self.end_span(span), block.unbox().body)) Ok(self.ast.static_block(self.end_span(span), block.unbox().body))
} }

View file

@ -204,11 +204,7 @@ impl<'a> ParserImpl<'a> {
} }
fn parse_parenthesized_expression(&mut self, span: Span) -> Result<Expression<'a>> { fn parse_parenthesized_expression(&mut self, span: Span) -> Result<Expression<'a>> {
let has_in = self.ctx.has_in(); let list = self.context(Context::In, Context::Decorator, SequenceExpressionList::parse)?;
let has_decorator = self.ctx.has_decorator();
self.ctx = self.ctx.and_in(true).and_decorator(false);
let list = SequenceExpressionList::parse(self)?;
self.ctx = self.ctx.and_in(has_in).and_decorator(has_decorator);
let mut expressions = list.elements; let mut expressions = list.elements;
let paren_span = self.end_span(span); let paren_span = self.end_span(span);
@ -361,10 +357,7 @@ impl<'a> ParserImpl<'a> {
/// [ `ElementList`[?Yield, ?Await] , Elisionopt ] /// [ `ElementList`[?Yield, ?Await] , Elisionopt ]
pub(crate) fn parse_array_expression(&mut self) -> Result<Expression<'a>> { pub(crate) fn parse_array_expression(&mut self) -> Result<Expression<'a>> {
let span = self.start_span(); let span = self.start_span();
let has_in = self.ctx.has_in(); let list = self.context(Context::In, Context::empty(), ArrayExpressionList::parse)?;
self.ctx = self.ctx.and_in(true);
let list = ArrayExpressionList::parse(self)?;
self.ctx = self.ctx.and_in(has_in);
Ok(self.ast.array_expression(self.end_span(span), list.elements, list.trailing_comma)) Ok(self.ast.array_expression(self.end_span(span), list.elements, list.trailing_comma))
} }
@ -390,7 +383,7 @@ impl<'a> ParserImpl<'a> {
Kind::TemplateHead => { Kind::TemplateHead => {
quasis.push(self.parse_template_element(tagged)); quasis.push(self.parse_template_element(tagged));
// TemplateHead Expression[+In, ?Yield, ?Await] // TemplateHead Expression[+In, ?Yield, ?Await]
let expr = self.with_context(Context::In, Self::parse_expression)?; let expr = self.context(Context::In, Context::empty(), Self::parse_expression)?;
expressions.push(expr); expressions.push(expr);
self.re_lex_template_substitution_tail(); self.re_lex_template_substitution_tail();
loop { loop {
@ -405,7 +398,11 @@ impl<'a> ParserImpl<'a> {
} }
_ => { _ => {
// TemplateMiddle Expression[+In, ?Yield, ?Await] // TemplateMiddle Expression[+In, ?Yield, ?Await]
let expr = self.with_context(Context::In, Self::parse_expression)?; let expr = self.context(
Context::In,
Context::empty(),
Self::parse_expression,
)?;
expressions.push(expr); expressions.push(expr);
self.re_lex_template_substitution_tail(); self.re_lex_template_substitution_tail();
} }
@ -652,10 +649,7 @@ impl<'a> ParserImpl<'a> {
optional: bool, optional: bool,
) -> Result<Expression<'a>> { ) -> Result<Expression<'a>> {
self.bump_any(); // advance `[` self.bump_any(); // advance `[`
let has_in = self.ctx.has_in(); let property = self.context(Context::In, Context::empty(), Self::parse_expression)?;
self.ctx = self.ctx.and_in(true);
let property = self.parse_expression()?;
self.ctx = self.ctx.and_in(has_in);
self.expect(Kind::RBrack)?; self.expect(Kind::RBrack)?;
Ok(self.ast.computed_member_expression(self.end_span(lhs_span), lhs, property, optional)) Ok(self.ast.computed_member_expression(self.end_span(lhs_span), lhs, property, optional))
} }
@ -683,7 +677,7 @@ impl<'a> ParserImpl<'a> {
let arguments = if self.at(Kind::LParen) { let arguments = if self.at(Kind::LParen) {
// ArgumentList[Yield, Await] : // ArgumentList[Yield, Await] :
// AssignmentExpression[+In, ?Yield, ?Await] // AssignmentExpression[+In, ?Yield, ?Await]
self.with_context(Context::In, CallArguments::parse)?.elements self.context(Context::In, Context::empty(), CallArguments::parse)?.elements
} else { } else {
self.ast.new_vec() self.ast.new_vec()
}; };
@ -750,10 +744,7 @@ impl<'a> ParserImpl<'a> {
) -> Result<Expression<'a>> { ) -> Result<Expression<'a>> {
// ArgumentList[Yield, Await] : // ArgumentList[Yield, Await] :
// AssignmentExpression[+In, ?Yield, ?Await] // AssignmentExpression[+In, ?Yield, ?Await]
let ctx = self.ctx; let call_arguments = self.context(Context::In, Context::Decorator, CallArguments::parse)?;
self.ctx = ctx.and_in(true).and_decorator(false);
let call_arguments = CallArguments::parse(self)?;
self.ctx = ctx;
Ok(self.ast.call_expression( Ok(self.ast.call_expression(
self.end_span(lhs_span), self.end_span(lhs_span),
lhs, lhs,
@ -928,12 +919,8 @@ impl<'a> ParserImpl<'a> {
if !self.eat(Kind::Question) { if !self.eat(Kind::Question) {
return Ok(lhs); return Ok(lhs);
} }
let consequent =
let has_in = self.ctx.has_in(); self.context(Context::In, Context::empty(), Self::parse_assignment_expression_base)?;
self.ctx = self.ctx.and_in(true);
let consequent = self.parse_assignment_expression_base()?;
self.ctx = self.ctx.and_in(has_in);
self.expect(Kind::Colon)?; self.expect(Kind::Colon)?;
let alternate = self.parse_assignment_expression_base()?; let alternate = self.parse_assignment_expression_base()?;
Ok(self.ast.conditional_expression(self.end_span(span), lhs, consequent, alternate)) Ok(self.ast.conditional_expression(self.end_span(span), lhs, consequent, alternate))
@ -1047,9 +1034,9 @@ impl<'a> ParserImpl<'a> {
if !has_await { if !has_await {
self.error(diagnostics::await_expression(Span::new(span.start, span.start + 5))); self.error(diagnostics::await_expression(Span::new(span.start, span.start + 5)));
} }
self.ctx = self.ctx.and_await(true); let argument = self.context(Context::Await, Context::empty(), |p| {
let argument = self.parse_unary_expression_base(lhs_span)?; p.parse_unary_expression_base(lhs_span)
self.ctx = self.ctx.and_await(has_await); })?;
Ok(self.ast.await_expression(self.end_span(span), argument)) Ok(self.ast.await_expression(self.end_span(span), argument))
} }
@ -1060,7 +1047,8 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn parse_decorator(&mut self) -> Result<Decorator<'a>> { pub(crate) fn parse_decorator(&mut self) -> Result<Decorator<'a>> {
let span = self.start_span(); let span = self.start_span();
self.bump_any(); // bump @ self.bump_any(); // bump @
let expr = self.with_context(Context::Decorator, Self::parse_lhs_expression)?; let expr =
self.context(Context::Decorator, Context::empty(), Self::parse_lhs_expression)?;
Ok(self.ast.decorator(self.end_span(span), expr)) Ok(self.ast.decorator(self.end_span(span), expr))
} }

View file

@ -57,7 +57,7 @@ impl<'a> ParserImpl<'a> {
let span = self.start_span(); let span = self.start_span();
self.expect(Kind::LCurly)?; self.expect(Kind::LCurly)?;
let (directives, statements) = self.with_context(Context::Return, |p| { let (directives, statements) = self.context(Context::Return, Context::empty(), |p| {
p.parse_directives_and_statements(/* is_top_level */ false) p.parse_directives_and_statements(/* is_top_level */ false)
})?; })?;

View file

@ -125,11 +125,8 @@ impl<'a> ParserImpl<'a> {
// import { export1 , export2 as alias2 , [...] } from "module-name"; // import { export1 , export2 as alias2 , [...] } from "module-name";
fn parse_import_specifiers(&mut self) -> Result<Vec<'a, ImportDeclarationSpecifier<'a>>> { fn parse_import_specifiers(&mut self) -> Result<Vec<'a, ImportDeclarationSpecifier<'a>>> {
let ctx = self.ctx; self.context(Context::empty(), self.ctx, ImportSpecifierList::parse)
self.ctx = Context::default(); .map(|x| x.import_specifiers)
let specifiers = ImportSpecifierList::parse(self)?.import_specifiers;
self.ctx = ctx;
Ok(specifiers)
} }
/// [Import Attributes](https://tc39.es/proposal-import-attributes) /// [Import Attributes](https://tc39.es/proposal-import-attributes)
@ -142,11 +139,7 @@ impl<'a> ParserImpl<'a> {
} }
}; };
let span = self.start_span(); let span = self.start_span();
let ctx = self.ctx; let with_entries = self.context(Context::empty(), self.ctx, AssertEntries::parse)?.elements;
self.ctx = Context::default();
let with_entries = AssertEntries::parse(self)?.elements;
self.ctx = ctx;
Ok(Some(WithClause { span: self.end_span(span), attributes_keyword, with_entries })) Ok(Some(WithClause { span: self.end_span(span), attributes_keyword, with_entries }))
} }
@ -225,12 +218,8 @@ impl<'a> ParserImpl<'a> {
span: Span, span: Span,
) -> Result<Box<'a, ExportNamedDeclaration<'a>>> { ) -> Result<Box<'a, ExportNamedDeclaration<'a>>> {
let export_kind = self.parse_import_or_export_kind(); let export_kind = self.parse_import_or_export_kind();
let specifiers =
let ctx = self.ctx; self.context(Context::empty(), self.ctx, ExportNamedSpecifiers::parse)?.elements;
self.ctx = Context::default();
let specifiers = ExportNamedSpecifiers::parse(self)?.elements;
self.ctx = ctx;
let (source, with_clause) = if self.eat(Kind::From) && self.cur_kind().is_literal() { let (source, with_clause) = if self.eat(Kind::From) && self.cur_kind().is_literal() {
let source = self.parse_literal_string()?; let source = self.parse_literal_string()?;
(Some(source), self.parse_import_attributes()?) (Some(source), self.parse_import_attributes()?)

View file

@ -5,7 +5,7 @@ use oxc_span::Span;
use oxc_syntax::operator::AssignmentOperator; use oxc_syntax::operator::AssignmentOperator;
use super::list::ObjectExpressionProperties; use super::list::ObjectExpressionProperties;
use crate::{lexer::Kind, list::SeparatedList, ParserImpl}; use crate::{lexer::Kind, list::SeparatedList, Context, ParserImpl};
impl<'a> ParserImpl<'a> { impl<'a> ParserImpl<'a> {
/// [Object Expression](https://tc39.es/ecma262/#sec-object-initializer) /// [Object Expression](https://tc39.es/ecma262/#sec-object-initializer)
@ -15,12 +15,8 @@ impl<'a> ParserImpl<'a> {
/// { `PropertyDefinitionList`[?Yield, ?Await] , } /// { `PropertyDefinitionList`[?Yield, ?Await] , }
pub(crate) fn parse_object_expression(&mut self) -> Result<Expression<'a>> { pub(crate) fn parse_object_expression(&mut self) -> Result<Expression<'a>> {
let span = self.start_span(); let span = self.start_span();
let object_expression_properties =
let has_in = self.ctx.has_in(); self.context(Context::In, Context::empty(), ObjectExpressionProperties::parse)?;
self.ctx = self.ctx.and_in(true);
let object_expression_properties = ObjectExpressionProperties::parse(self)?;
self.ctx = self.ctx.and_in(has_in);
Ok(self.ast.object_expression( Ok(self.ast.object_expression(
self.end_span(span), self.end_span(span),
object_expression_properties.elements, object_expression_properties.elements,
@ -176,10 +172,8 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn parse_computed_property_name(&mut self) -> Result<Expression<'a>> { pub(crate) fn parse_computed_property_name(&mut self) -> Result<Expression<'a>> {
self.bump_any(); // advance `[` self.bump_any(); // advance `[`
let has_in = self.ctx.has_in(); let expression =
self.ctx = self.ctx.and_in(true); self.context(Context::In, Context::empty(), Self::parse_assignment_expression_base)?;
let expression = self.parse_assignment_expression_base()?;
self.ctx = self.ctx.and_in(has_in);
self.expect(Kind::RBrack)?; self.expect(Kind::RBrack)?;
Ok(expression) Ok(expression)

View file

@ -283,7 +283,8 @@ impl<'a> ParserImpl<'a> {
return self.parse_for_loop(span, None, r#await); return self.parse_for_loop(span, None, r#await);
} }
let init_expression = self.without_context(Context::In, ParserImpl::parse_expression)?; let init_expression =
self.context(Context::empty(), Context::In, ParserImpl::parse_expression)?;
// for (a.b in ...), for ([a] in ..), for ({a} in ..) // for (a.b in ...), for ([a] in ..), for ({a} in ..)
if self.at(Kind::In) || self.at(Kind::Of) { if self.at(Kind::In) || self.at(Kind::Of) {
@ -308,7 +309,7 @@ impl<'a> ParserImpl<'a> {
r#await: bool, r#await: bool,
) -> Result<Statement<'a>> { ) -> Result<Statement<'a>> {
let start_span = self.start_span(); let start_span = self.start_span();
let init_declaration = self.without_context(Context::In, |p| { let init_declaration = self.context(Context::empty(), Context::In, |p| {
let decl_ctx = VariableDeclarationContext::new(VariableDeclarationParent::For); let decl_ctx = VariableDeclarationContext::new(VariableDeclarationParent::For);
p.parse_variable_declaration(start_span, decl_ctx, Modifiers::empty()) p.parse_variable_declaration(start_span, decl_ctx, Modifiers::empty())
})?; })?;
@ -359,7 +360,7 @@ impl<'a> ParserImpl<'a> {
) -> Result<Statement<'a>> { ) -> Result<Statement<'a>> {
self.expect(Kind::Semicolon)?; self.expect(Kind::Semicolon)?;
let test = if !self.at(Kind::Semicolon) && !self.at(Kind::RParen) { let test = if !self.at(Kind::Semicolon) && !self.at(Kind::RParen) {
Some(self.with_context(Context::In, ParserImpl::parse_expression)?) Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expression)?)
} else { } else {
None None
}; };
@ -367,7 +368,7 @@ impl<'a> ParserImpl<'a> {
let update = if self.at(Kind::RParen) { let update = if self.at(Kind::RParen) {
None None
} else { } else {
Some(self.with_context(Context::In, ParserImpl::parse_expression)?) Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expression)?)
}; };
self.expect(Kind::RParen)?; self.expect(Kind::RParen)?;
if r#await { if r#await {
@ -433,7 +434,7 @@ impl<'a> ParserImpl<'a> {
let argument = if self.eat(Kind::Semicolon) || self.can_insert_semicolon() { let argument = if self.eat(Kind::Semicolon) || self.can_insert_semicolon() {
None None
} else { } else {
let expr = self.with_context(Context::In, ParserImpl::parse_expression)?; let expr = self.context(Context::In, Context::empty(), ParserImpl::parse_expression)?;
self.asi()?; self.asi()?;
Some(expr) Some(expr)
}; };

View file

@ -79,11 +79,7 @@ impl<'a> ParserImpl<'a> {
let name = self.parse_jsx_element_name()?; let name = self.parse_jsx_element_name()?;
// <Component<TsType> for tsx // <Component<TsType> for tsx
let type_parameters = if self.ts_enabled() { let type_parameters = if self.ts_enabled() {
let ctx = self.ctx; self.context(Context::default(), self.ctx, Self::parse_ts_type_arguments)?
self.ctx = Context::default();
let args = self.parse_ts_type_arguments()?;
self.ctx = ctx;
args
} else { } else {
None None
}; };
@ -258,14 +254,13 @@ impl<'a> ParserImpl<'a> {
} }
fn parse_jsx_assignment_expression(&mut self) -> Result<Expression<'a>> { fn parse_jsx_assignment_expression(&mut self) -> Result<Expression<'a>> {
let ctx = self.ctx; self.context(Context::default().and_await(self.ctx.has_await()), self.ctx, |p| {
self.ctx = Context::default().and_await(ctx.has_await()); let expr = p.parse_expression();
let expr = self.parse_expression(); if let Ok(Expression::SequenceExpression(seq)) = &expr {
if let Ok(Expression::SequenceExpression(seq)) = &expr { return Err(diagnostics::jsx_expressions_may_not_use_the_comma_operator(seq.span));
return Err(diagnostics::jsx_expressions_may_not_use_the_comma_operator(seq.span)); }
} expr
self.ctx = ctx; })
expr
} }
/// `JSXChildExpression` : /// `JSXChildExpression` :

View file

@ -218,18 +218,27 @@ impl<'a> ParserImpl<'a> {
&& !self.cur_token().is_on_new_line && !self.cur_token().is_on_new_line
&& self.eat(Kind::Extends) && self.eat(Kind::Extends)
{ {
let extends_type = let extends_type = self.context(
self.with_context(Context::DisallowConditionalTypes, Self::parse_ts_type)?; Context::DisallowConditionalTypes,
Context::empty(),
Self::parse_ts_type,
)?;
self.expect(Kind::Question)?; self.expect(Kind::Question)?;
let true_type = let true_type = self.context(
self.without_context(Context::DisallowConditionalTypes, Self::parse_ts_type)?; Context::empty(),
Context::DisallowConditionalTypes,
Self::parse_ts_type,
)?;
self.expect(Kind::Colon)?; self.expect(Kind::Colon)?;
let false_type = let false_type = self.context(
self.without_context(Context::DisallowConditionalTypes, Self::parse_ts_type)?; Context::empty(),
Context::DisallowConditionalTypes,
Self::parse_ts_type,
)?;
return Ok(self.ast.ts_conditional_type( return Ok(self.ast.ts_conditional_type(
self.end_span(left_span), self.end_span(left_span),
@ -327,8 +336,11 @@ impl<'a> ParserImpl<'a> {
)); ));
} }
let mut left = self let mut left = self.context(
.without_context(Context::DisallowConditionalTypes, ParserImpl::parse_ts_basic_type)?; Context::empty(),
Context::DisallowConditionalTypes,
ParserImpl::parse_ts_basic_type,
)?;
while !self.cur_token().is_on_new_line && self.eat(Kind::LBrack) { while !self.cur_token().is_on_new_line && self.eat(Kind::LBrack) {
if self.eat(Kind::RBrack) { if self.eat(Kind::RBrack) {
@ -871,8 +883,11 @@ impl<'a> ParserImpl<'a> {
fn parse_constraint_of_infer_type(&mut self) -> Result<Option<TSType<'a>>> { fn parse_constraint_of_infer_type(&mut self) -> Result<Option<TSType<'a>>> {
if self.eat(Kind::Extends) { if self.eat(Kind::Extends) {
let constraint = let constraint = self.context(
self.with_context(Context::DisallowConditionalTypes, Self::parse_ts_type)?; Context::DisallowConditionalTypes,
Context::empty(),
Self::parse_ts_type,
)?;
if self.ctx.has_disallow_conditional_types() || !self.at(Kind::Question) { if self.ctx.has_disallow_conditional_types() || !self.at(Kind::Question) {
return Ok(Some(constraint)); return Ok(Some(constraint));
} }
@ -940,7 +955,7 @@ impl<'a> ParserImpl<'a> {
if !self.peek_token().is_on_new_line && (asserts || is_predicate) { if !self.peek_token().is_on_new_line && (asserts || is_predicate) {
self.parse_ts_type_predicate() self.parse_ts_type_predicate()
} else { } else {
self.without_context(Context::DisallowConditionalTypes, Self::parse_ts_type) self.context(Context::empty(), Context::DisallowConditionalTypes, Self::parse_ts_type)
} }
} }