Skip to content

Commit

Permalink
perf(parser): precompute is_typescript (#6443)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Oct 11, 2024
1 parent b1bf12c commit 4d8bc8c
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 52 deletions.
2 changes: 1 addition & 1 deletion crates/oxc_parser/src/js/arrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<'a> ParserImpl<'a> {
Kind::RParen => {
let third = self.nth_kind(offset + 2);
return match third {
Kind::Colon if self.ts_enabled() => Tristate::Maybe,
Kind::Colon if self.is_ts => Tristate::Maybe,
Kind::Arrow | Kind::LCurly => Tristate::True,
_ => Tristate::False,
};
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_parser/src/js/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ impl<'a> ParserImpl<'a> {
allow_question: bool,
) -> Result<BindingPattern<'a>> {
let mut kind = self.parse_binding_pattern_kind()?;
let optional =
if allow_question && self.ts_enabled() { self.eat(Kind::Question) } else { false };
let optional = if allow_question && self.is_ts { self.eat(Kind::Question) } else { false };
let type_annotation = self.parse_ts_type_annotation()?;
if let Some(type_annotation) = &type_annotation {
Self::extend_binding_pattern_span_end(type_annotation.span, &mut kind);
Expand Down Expand Up @@ -111,7 +110,7 @@ impl<'a> ParserImpl<'a> {

let kind = self.parse_binding_pattern_kind()?;
// Rest element does not allow `?`, checked in checker/typescript.rs
if self.at(Kind::Question) && self.ts_enabled() {
if self.at(Kind::Question) && self.is_ts {
let span = self.cur_token().span();
self.bump_any();
self.error(diagnostics::a_rest_parameter_cannot_be_optional(span));
Expand Down
11 changes: 4 additions & 7 deletions crates/oxc_parser/src/js/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ impl<'a> ParserImpl<'a> {
None
};

let type_parameters =
if self.ts_enabled() { self.parse_ts_type_parameters()? } else { None };
let type_parameters = if self.is_ts { self.parse_ts_type_parameters()? } else { None };
let (extends, implements) = self.parse_heritage_clause()?;
let mut super_class = None;
let mut super_type_parameters = None;
Expand Down Expand Up @@ -283,7 +282,7 @@ impl<'a> ParserImpl<'a> {

if let PropertyKey::PrivateIdentifier(private_ident) = &key {
// `private #foo`, etc. is illegal
if self.ts_enabled() {
if self.is_ts {
self.verify_modifiers(
&modifiers,
ModifierFlags::all() - ModifierFlags::ACCESSIBILITY,
Expand Down Expand Up @@ -457,8 +456,7 @@ impl<'a> ParserImpl<'a> {
optional: bool,
definite: bool,
) -> Result<ClassElement<'a>> {
let type_annotation =
if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None };
let type_annotation = if self.is_ts { self.parse_ts_type_annotation()? } else { None };
let decorators = self.consume_decorators();
let value = if self.eat(Kind::Eq) { Some(self.parse_expr()?) } else { None };
self.asi()?;
Expand Down Expand Up @@ -506,8 +504,7 @@ impl<'a> ParserImpl<'a> {
definite: bool,
accessibility: Option<TSAccessibility>,
) -> Result<ClassElement<'a>> {
let type_annotation =
if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None };
let type_annotation = if self.is_ts { self.parse_ts_type_annotation()? } else { None };
let value =
self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()).transpose()?;
let r#type = if r#abstract {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_parser/src/js/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl<'a> ParserImpl<'a> {

let mut binding_kind = self.parse_binding_pattern_kind()?;

let (id, definite) = if self.ts_enabled() {
let (id, definite) = if self.is_ts {
// const x!: number = 1
// ^ definite
let mut definite = false;
Expand Down
9 changes: 4 additions & 5 deletions crates/oxc_parser/src/js/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ impl<'a> ParserImpl<'a> {
_ => break,
}
}
Kind::Bang if !self.cur_token().is_on_new_line && self.ts_enabled() => {
Kind::Bang if !self.cur_token().is_on_new_line && self.is_ts => {
self.bump_any();
self.ast.expression_ts_non_null(self.end_span(lhs_span), lhs)
}
Expand Down Expand Up @@ -905,7 +905,7 @@ impl<'a> ParserImpl<'a> {
if self.source_type.is_jsx() {
return self.parse_jsx_expression();
}
if self.ts_enabled() {
if self.is_ts {
return self.parse_ts_type_assertion();
}
Err(self.unexpected())
Expand Down Expand Up @@ -951,13 +951,12 @@ impl<'a> ParserImpl<'a> {
// Pratt Parsing Algorithm
// <https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html>
let mut lhs = lhs;
let is_ts = self.ts_enabled();
loop {
// re-lex for `>=` `>>` `>>>`
// This is need for jsx `<div>=</div>` case
let kind = self.re_lex_right_angle();

let Some(left_precedence) = kind_to_precedence(kind, is_ts) else { break };
let Some(left_precedence) = kind_to_precedence(kind, self.is_ts) else { break };

let stop = if left_precedence.is_right_associative() {
left_precedence < min_precedence
Expand All @@ -976,7 +975,7 @@ impl<'a> ParserImpl<'a> {
break;
}

if self.ts_enabled() && matches!(kind, Kind::As | Kind::Satisfies) {
if self.is_ts && matches!(kind, Kind::As | Kind::Satisfies) {
if self.cur_token().is_on_new_line {
break;
}
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_parser/src/js/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl<'a> ParserImpl<'a> {
) -> Result<(Option<TSThisParameter<'a>>, Box<'a, FormalParameters<'a>>)> {
let span = self.start_span();
self.expect(Kind::LParen)?;
let this_param = if self.ts_enabled() && self.at(Kind::This) {
let this_param = if self.is_ts && self.at(Kind::This) {
let param = self.parse_ts_this_parameter()?;
if !self.at(Kind::RParen) {
self.expect(Kind::Comma)?;
Expand Down Expand Up @@ -135,7 +135,7 @@ impl<'a> ParserImpl<'a> {
self.ctx =
self.ctx.and_in(ctx.has_in()).and_await(ctx.has_await()).and_yield(ctx.has_yield());

if !self.ts_enabled() && body.is_none() {
if !self.is_ts && body.is_none() {
return Err(self.unexpected());
}

Expand Down
28 changes: 11 additions & 17 deletions crates/oxc_parser/src/js/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl<'a> ParserImpl<'a> {

self.bump_any(); // advance `import`

if self.ts_enabled()
if self.is_ts
&& ((self.cur_kind().is_binding_identifier() && self.peek_at(Kind::Eq))
|| (self.at(Kind::Type)
&& self.peek_kind().is_binding_identifier()
Expand Down Expand Up @@ -208,10 +208,10 @@ impl<'a> ParserImpl<'a> {
self.bump_any(); // advance `export`

let decl = match self.cur_kind() {
Kind::Eq if self.ts_enabled() => self
Kind::Eq if self.is_ts => self
.parse_ts_export_assignment_declaration(span)
.map(ModuleDeclaration::TSExportAssignment),
Kind::As if self.peek_at(Kind::Namespace) && self.ts_enabled() => self
Kind::As if self.peek_at(Kind::Namespace) && self.is_ts => self
.parse_ts_export_namespace()
.map(ModuleDeclaration::TSNamespaceExportDeclaration),
Kind::Default => self
Expand All @@ -223,7 +223,7 @@ impl<'a> ParserImpl<'a> {
Kind::LCurly => self
.parse_export_named_specifiers(span)
.map(ModuleDeclaration::ExportNamedDeclaration),
Kind::Type if self.peek_at(Kind::LCurly) && self.ts_enabled() => self
Kind::Type if self.peek_at(Kind::LCurly) && self.is_ts => self
.parse_export_named_specifiers(span)
.map(ModuleDeclaration::ExportNamedDeclaration),
Kind::Type if self.peek_at(Kind::Star) => {
Expand Down Expand Up @@ -328,11 +328,8 @@ impl<'a> ParserImpl<'a> {
// For tc39/proposal-decorators
// For more information, please refer to <https://babeljs.io/docs/babel-plugin-proposal-decorators#decoratorsbeforeexport>
self.eat_decorators()?;
let modifiers = if self.ts_enabled() {
self.eat_modifiers_before_declaration()?
} else {
Modifiers::empty()
};
let modifiers =
if self.is_ts { self.eat_modifiers_before_declaration()? } else { Modifiers::empty() };

let declaration = self.parse_declaration(decl_span, &modifiers)?;
let span = self.end_span(span);
Expand Down Expand Up @@ -362,16 +359,13 @@ impl<'a> ParserImpl<'a> {
Kind::Class => self
.parse_class_declaration(decl_span, /* modifiers */ &Modifiers::empty())
.map(ExportDefaultDeclarationKind::ClassDeclaration)?,
_ if self.at(Kind::Abstract) && self.peek_at(Kind::Class) && self.ts_enabled() => {
_ if self.at(Kind::Abstract) && self.peek_at(Kind::Class) && self.is_ts => {
// eat the abstract modifier
let modifiers = self.eat_modifiers_before_declaration()?;
self.parse_class_declaration(decl_span, &modifiers)
.map(ExportDefaultDeclarationKind::ClassDeclaration)?
}
_ if self.at(Kind::Interface)
&& !self.peek_token().is_on_new_line
&& self.ts_enabled() =>
{
_ if self.at(Kind::Interface) && !self.peek_token().is_on_new_line && self.is_ts => {
self.parse_ts_interface_declaration(decl_span, &Modifiers::empty()).map(|decl| {
match decl {
Declaration::TSInterfaceDeclaration(decl) => {
Expand Down Expand Up @@ -424,7 +418,7 @@ impl<'a> ParserImpl<'a> {
let specifier_span = self.start_span();
let peek_kind = self.peek_kind();
let mut import_kind = ImportOrExportKind::Value;
if self.ts_enabled() && self.at(Kind::Type) {
if self.is_ts && self.at(Kind::Type) {
if self.peek_at(Kind::As) {
if self.nth_at(2, Kind::As) {
if self.nth_kind(3).is_identifier_name() {
Expand Down Expand Up @@ -477,7 +471,7 @@ impl<'a> ParserImpl<'a> {
}

fn parse_import_or_export_kind(&mut self) -> ImportOrExportKind {
if !self.ts_enabled() {
if !self.is_ts {
return ImportOrExportKind::Value;
}
// OK
Expand Down Expand Up @@ -521,7 +515,7 @@ impl<'a> ParserImpl<'a> {
// export { type as as } // name: `type` type-export: `false` (aliased to `as`)
// export { type as as as } // name: `as` type-export: `true`, aliased to `as`
let mut export_kind = ImportOrExportKind::Value;
if self.ts_enabled() && self.at(Kind::Type) {
if self.is_ts && self.at(Kind::Type) {
if self.peek_at(Kind::As) {
if self.nth_at(2, Kind::As) {
if self.nth_at(3, Kind::Str) || self.nth_kind(3).is_identifier_name() {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_parser/src/js/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<'a> ParserImpl<'a> {
// Report and handle illegal modifiers
// e.g. const x = { public foo() {} }
modifier_kind
if self.ts_enabled()
if self.is_ts
&& modifier_kind.is_modifier_kind()
&& peek_kind.is_identifier_or_keyword() =>
{
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_parser/src/js/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<'a> ParserImpl<'a> {
// [+Return] ReturnStatement[?Yield, ?Await]
Kind::Return => self.parse_return_statement(),
Kind::Var => self.parse_variable_statement(stmt_ctx),
Kind::Const if !(self.ts_enabled() && self.is_at_enum_declaration()) => {
Kind::Const if !(self.is_ts && self.is_at_enum_declaration()) => {
self.parse_variable_statement(stmt_ctx)
}
Kind::Let if !self.cur_token().escaped() => self.parse_let(stmt_ctx),
Expand All @@ -116,7 +116,7 @@ impl<'a> ParserImpl<'a> {
}
Kind::Using if self.peek_kind().is_binding_identifier() => self.parse_using(),
_ if self.at_function_with_async() => self.parse_function_declaration(stmt_ctx),
_ if self.ts_enabled() && self.at_start_of_ts_declaration() => {
_ if self.is_ts && self.at_start_of_ts_declaration() => {
self.parse_ts_declaration_statement(start_span)
}
_ => self.parse_expression_or_labeled_statement(),
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_parser/src/jsx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ impl<'a> ParserImpl<'a> {
self.expect(Kind::LAngle)?;
let name = self.parse_jsx_element_name()?;
// <Component<TsType> for tsx
let type_parameters =
if self.ts_enabled() { self.try_parse_type_arguments()? } else { None };
let type_parameters = if self.is_ts { self.try_parse_type_arguments()? } else { None };
let attributes = self.parse_jsx_attributes()?;
let self_closing = self.eat(Kind::Slash);
if !self_closing || in_jsx_child {
Expand Down
10 changes: 5 additions & 5 deletions crates/oxc_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,11 @@ struct ParserImpl<'a> {
/// Parsing context
ctx: Context,

/// Ast builder for creating AST spans
/// Ast builder for creating AST nodes
ast: AstBuilder<'a>,

/// Precomputed typescript detection
is_ts: bool,
}

impl<'a> ParserImpl<'a> {
Expand All @@ -384,6 +387,7 @@ impl<'a> ParserImpl<'a> {
state: ParserState::default(),
ctx: Self::default_context(source_type, options),
ast: AstBuilder::new(allocator),
is_ts: source_type.is_typescript(),
}
}

Expand Down Expand Up @@ -508,10 +512,6 @@ impl<'a> ParserImpl<'a> {
self.errors.len() + self.lexer.errors.len()
}

fn ts_enabled(&self) -> bool {
self.source_type.is_typescript()
}

fn set_source_type_to_module_if_unambiguous(&mut self) {
if self.source_type.is_unambiguous() {
self.source_type = self.source_type.with_module(true);
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_parser/src/ts/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn parse_ts_type_annotation(
&mut self,
) -> Result<Option<Box<'a, TSTypeAnnotation<'a>>>> {
if !self.ts_enabled() {
if !self.is_ts {
return Ok(None);
}
if !self.at(Kind::Colon) {
Expand Down Expand Up @@ -398,7 +398,7 @@ impl<'a> ParserImpl<'a> {
if declare {
self.parse_ts_declare_function(start_span, modifiers)
.map(Declaration::FunctionDeclaration)
} else if self.ts_enabled() {
} else if self.is_ts {
self.parse_ts_function_impl(start_span, FunctionKind::Declaration, modifiers)
.map(Declaration::FunctionDeclaration)
} else {
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_parser/src/ts/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn parse_ts_type_parameters(
&mut self,
) -> Result<Option<Box<'a, TSTypeParameterDeclaration<'a>>>> {
if !self.ts_enabled() {
if !self.is_ts {
return Ok(None);
}
if !self.at(Kind::LAngle) {
Expand Down Expand Up @@ -811,7 +811,7 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn parse_type_arguments_in_expression(
&mut self,
) -> Result<Option<Box<'a, TSTypeParameterInstantiation<'a>>>> {
if !self.ts_enabled() {
if !self.is_ts {
return Ok(None);
}
let span = self.start_span();
Expand Down Expand Up @@ -1049,7 +1049,7 @@ impl<'a> ParserImpl<'a> {
kind: Kind,
is_type: bool,
) -> Result<Option<Box<'a, TSTypeAnnotation<'a>>>> {
if !self.ts_enabled() {
if !self.is_ts {
return Ok(None);
}
if !self.at(Kind::Colon) {
Expand Down Expand Up @@ -1315,7 +1315,7 @@ impl<'a> ParserImpl<'a> {
&mut self,
is_constructor_parameter: bool,
) -> Modifiers<'a> {
if !self.ts_enabled() {
if !self.is_ts {
return Modifiers::empty();
}

Expand Down

0 comments on commit 4d8bc8c

Please sign in to comment.