mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
refactor(parser): simplify Context passing (#3266)
This commit is contained in:
parent
c4ccf9f4d8
commit
b27a905958
10 changed files with 84 additions and 121 deletions
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()?)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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` :
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue