mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(parser): use AstBuilder (#5743)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
bd48dfbf8b
commit
a4b55bf00e
8 changed files with 61 additions and 83 deletions
|
|
@ -421,20 +421,19 @@ impl<'a> ParserImpl<'a> {
|
|||
} else {
|
||||
MethodDefinitionType::MethodDefinition
|
||||
};
|
||||
let method_definition = MethodDefinition {
|
||||
Ok(self.ast.class_element_method_definition(
|
||||
r#type,
|
||||
span: self.end_span(span),
|
||||
self.end_span(span),
|
||||
decorators,
|
||||
key,
|
||||
value,
|
||||
kind,
|
||||
computed,
|
||||
r#static,
|
||||
r#override,
|
||||
accessibility,
|
||||
optional,
|
||||
decorators,
|
||||
};
|
||||
Ok(ClassElement::MethodDefinition(self.ast.alloc(method_definition)))
|
||||
accessibility,
|
||||
))
|
||||
}
|
||||
|
||||
/// `FieldDefinition`[?Yield, ?Await] ;
|
||||
|
|
@ -464,23 +463,22 @@ impl<'a> ParserImpl<'a> {
|
|||
} else {
|
||||
PropertyDefinitionType::PropertyDefinition
|
||||
};
|
||||
let property_definition = PropertyDefinition {
|
||||
Ok(self.ast.class_element_property_definition(
|
||||
r#type,
|
||||
span: self.end_span(span),
|
||||
self.end_span(span),
|
||||
decorators,
|
||||
key,
|
||||
value,
|
||||
computed,
|
||||
r#static,
|
||||
declare,
|
||||
r#override,
|
||||
optional,
|
||||
definite,
|
||||
readonly,
|
||||
type_annotation,
|
||||
accessibility,
|
||||
optional,
|
||||
definite,
|
||||
decorators,
|
||||
};
|
||||
Ok(ClassElement::PropertyDefinition(self.ast.alloc(property_definition)))
|
||||
))
|
||||
}
|
||||
|
||||
/// `ClassStaticBlockStatementList` :
|
||||
|
|
|
|||
|
|
@ -338,13 +338,11 @@ impl<'a> ParserImpl<'a> {
|
|||
|
||||
pub(crate) fn parse_literal_regexp(&mut self) -> Result<RegExpLiteral<'a>> {
|
||||
let span = self.start_span();
|
||||
|
||||
// split out pattern
|
||||
let (pattern_end, flags) = self.read_regex()?;
|
||||
let pattern_start = self.cur_token().start + 1; // +1 to exclude `/`
|
||||
let pattern_text = &self.source_text[pattern_start as usize..pattern_end as usize];
|
||||
self.bump_any();
|
||||
|
||||
let pattern = self
|
||||
.options
|
||||
.parse_regular_expression
|
||||
|
|
@ -356,7 +354,6 @@ impl<'a> ParserImpl<'a> {
|
|||
pat.map_or_else(|| RegExpPattern::Invalid(pattern_text), RegExpPattern::Pattern)
|
||||
},
|
||||
);
|
||||
|
||||
Ok(self.ast.reg_exp_literal(self.end_span(span), EmptyObject, RegExp { pattern, flags }))
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +468,7 @@ impl<'a> ParserImpl<'a> {
|
|||
}
|
||||
_ => unreachable!("parse_template_literal"),
|
||||
}
|
||||
Ok(TemplateLiteral { span: self.end_span(span), quasis, expressions })
|
||||
Ok(self.ast.template_literal(self.end_span(span), quasis, expressions))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_template_literal_expression(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::Box;
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_diagnostics::Result;
|
||||
|
|
@ -332,7 +330,7 @@ impl<'a> ParserImpl<'a> {
|
|||
let id = self.cur_kind().is_binding_identifier().then(|| {
|
||||
let (span, name) = self.parse_identifier_kind(Kind::Ident);
|
||||
self.check_identifier(span, &name);
|
||||
BindingIdentifier { span, name, symbol_id: Cell::default() }
|
||||
self.ast.binding_identifier(span, name)
|
||||
});
|
||||
self.ctx = ctx;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> {
|
|||
}
|
||||
ArrayExpressionElement::SpreadElement(elem) => {
|
||||
if i == len - 1 {
|
||||
rest = Some(AssignmentTargetRest {
|
||||
span: elem.span,
|
||||
target: AssignmentTarget::cover(elem.unbox().argument, p)?,
|
||||
});
|
||||
rest = Some(p.ast.assignment_target_rest(
|
||||
elem.span,
|
||||
AssignmentTarget::cover(elem.unbox().argument, p)?,
|
||||
));
|
||||
if let Some(span) = expr.trailing_comma {
|
||||
p.error(diagnostics::binding_rest_element_trailing_comma(span));
|
||||
}
|
||||
|
|
@ -94,12 +94,7 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(ArrayAssignmentTarget {
|
||||
span: expr.span,
|
||||
elements,
|
||||
rest,
|
||||
trailing_comma: expr.trailing_comma,
|
||||
})
|
||||
Ok(p.ast.array_assignment_target(expr.span, elements, rest, expr.trailing_comma))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +114,8 @@ impl<'a> CoverGrammar<'a, Expression<'a>> for AssignmentTargetMaybeDefault<'a> {
|
|||
}
|
||||
|
||||
impl<'a> CoverGrammar<'a, AssignmentExpression<'a>> for AssignmentTargetWithDefault<'a> {
|
||||
fn cover(expr: AssignmentExpression<'a>, _p: &mut ParserImpl<'a>) -> Result<Self> {
|
||||
Ok(Self { span: expr.span, binding: expr.left, init: expr.right })
|
||||
fn cover(expr: AssignmentExpression<'a>, p: &mut ParserImpl<'a>) -> Result<Self> {
|
||||
Ok(p.ast.assignment_target_with_default(expr.span, expr.left, expr.right))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,10 +133,10 @@ impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> {
|
|||
}
|
||||
ObjectPropertyKind::SpreadProperty(spread) => {
|
||||
if i == len - 1 {
|
||||
rest = Some(AssignmentTargetRest {
|
||||
span: spread.span,
|
||||
target: AssignmentTarget::cover(spread.unbox().argument, p)?,
|
||||
});
|
||||
rest = Some(p.ast.assignment_target_rest(
|
||||
spread.span,
|
||||
AssignmentTarget::cover(spread.unbox().argument, p)?,
|
||||
));
|
||||
} else {
|
||||
return Err(diagnostics::spread_last_element(spread.span));
|
||||
}
|
||||
|
|
@ -149,7 +144,7 @@ impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(Self { span: expr.span, properties, rest })
|
||||
Ok(p.ast.object_assignment_target(expr.span, properties, rest))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,16 +165,18 @@ impl<'a> CoverGrammar<'a, ObjectProperty<'a>> for AssignmentTargetProperty<'a> {
|
|||
}
|
||||
_ => None,
|
||||
};
|
||||
let target = AssignmentTargetPropertyIdentifier { span: property.span, binding, init };
|
||||
Ok(AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(p.ast.alloc(target)))
|
||||
Ok(p.ast.assignment_target_property_assignment_target_property_identifier(
|
||||
property.span,
|
||||
binding,
|
||||
init,
|
||||
))
|
||||
} else {
|
||||
let binding = AssignmentTargetMaybeDefault::cover(property.value, p)?;
|
||||
let target = AssignmentTargetPropertyProperty {
|
||||
span: property.span,
|
||||
name: property.key,
|
||||
Ok(p.ast.assignment_target_property_assignment_target_property_property(
|
||||
property.span,
|
||||
property.key,
|
||||
binding,
|
||||
};
|
||||
Ok(AssignmentTargetProperty::AssignmentTargetPropertyProperty(p.ast.alloc(target)))
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,9 +107,8 @@ impl<'a> ParserImpl<'a> {
|
|||
fn parse_import_default_specifier(&mut self) -> Result<ImportDeclarationSpecifier<'a>> {
|
||||
let span = self.start_span();
|
||||
let local = self.parse_binding_identifier()?;
|
||||
Ok(ImportDeclarationSpecifier::ImportDefaultSpecifier(
|
||||
self.ast.alloc(ImportDefaultSpecifier { span: self.end_span(span), local }),
|
||||
))
|
||||
let span = self.end_span(span);
|
||||
Ok(self.ast.import_declaration_specifier_import_default_specifier(span, local))
|
||||
}
|
||||
|
||||
// import * as name from "module-name"
|
||||
|
|
@ -118,9 +117,8 @@ impl<'a> ParserImpl<'a> {
|
|||
self.bump_any(); // advance `*`
|
||||
self.expect(Kind::As)?;
|
||||
let local = self.parse_binding_identifier()?;
|
||||
Ok(ImportDeclarationSpecifier::ImportNamespaceSpecifier(
|
||||
self.ast.alloc(ImportNamespaceSpecifier { span: self.end_span(span), local }),
|
||||
))
|
||||
let span = self.end_span(span);
|
||||
Ok(self.ast.import_declaration_specifier_import_namespace_specifier(span, local))
|
||||
}
|
||||
|
||||
// import { export1 , export2 as alias2 , [...] } from "module-name";
|
||||
|
|
@ -168,7 +166,7 @@ impl<'a> ParserImpl<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(Some(WithClause { span: self.end_span(span), attributes_keyword, with_entries }))
|
||||
Ok(Some(self.ast.with_clause(self.end_span(span), attributes_keyword, with_entries)))
|
||||
}
|
||||
|
||||
fn parse_import_attribute(&mut self) -> Result<ImportAttribute<'a>> {
|
||||
|
|
@ -179,7 +177,7 @@ impl<'a> ParserImpl<'a> {
|
|||
};
|
||||
self.expect(Kind::Colon)?;
|
||||
let value = self.parse_literal_string()?;
|
||||
Ok(ImportAttribute { span: self.end_span(span), key, value })
|
||||
Ok(self.ast.import_attribute(self.end_span(span), key, value))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_ts_export_assignment_declaration(
|
||||
|
|
@ -187,11 +185,9 @@ impl<'a> ParserImpl<'a> {
|
|||
start_span: Span,
|
||||
) -> Result<Box<'a, TSExportAssignment<'a>>> {
|
||||
self.expect(Kind::Eq)?;
|
||||
|
||||
let expression = self.parse_assignment_expression_or_higher()?;
|
||||
self.asi()?;
|
||||
|
||||
Ok(self.ast.alloc(TSExportAssignment { span: self.end_span(start_span), expression }))
|
||||
Ok(self.ast.alloc_ts_export_assignment(self.end_span(start_span), expression))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_ts_export_namespace(
|
||||
|
|
@ -200,11 +196,9 @@ impl<'a> ParserImpl<'a> {
|
|||
let span = self.start_span();
|
||||
self.expect(Kind::As)?;
|
||||
self.expect(Kind::Namespace)?;
|
||||
|
||||
let id = self.parse_identifier_name()?;
|
||||
self.asi()?;
|
||||
|
||||
Ok(self.ast.alloc(TSNamespaceExportDeclaration { span: self.end_span(span), id }))
|
||||
Ok(self.ast.alloc_ts_namespace_export_declaration(self.end_span(span), id))
|
||||
}
|
||||
|
||||
/// [Exports](https://tc39.es/ecma262/#sec-exports)
|
||||
|
|
@ -453,15 +447,14 @@ impl<'a> ParserImpl<'a> {
|
|||
(imported, local)
|
||||
} else {
|
||||
let local = self.parse_binding_identifier()?;
|
||||
let imported = IdentifierName { span: local.span, name: local.name.clone() };
|
||||
(ModuleExportName::IdentifierName(imported), local)
|
||||
(self.ast.module_export_name_identifier_name(local.span, local.name.clone()), local)
|
||||
};
|
||||
Ok(ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc(ImportSpecifier {
|
||||
span: self.end_span(specifier_span),
|
||||
Ok(self.ast.import_declaration_specifier_import_specifier(
|
||||
self.end_span(specifier_span),
|
||||
imported,
|
||||
local,
|
||||
import_kind,
|
||||
})))
|
||||
))
|
||||
}
|
||||
|
||||
// ModuleExportName :
|
||||
|
|
@ -548,6 +541,6 @@ impl<'a> ParserImpl<'a> {
|
|||
let local = self.parse_module_export_name()?;
|
||||
let exported =
|
||||
if self.eat(Kind::As) { self.parse_module_export_name()? } else { local.clone() };
|
||||
Ok(ExportSpecifier { span: self.end_span(specifier_span), local, exported, export_kind })
|
||||
Ok(self.ast.export_specifier(self.end_span(specifier_span), local, exported, export_kind))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,8 +134,7 @@ impl<'a> ParserImpl<'a> {
|
|||
fn parse_property_definition_shorthand(&mut self) -> Result<Box<'a, ObjectProperty<'a>>> {
|
||||
let span = self.start_span();
|
||||
let identifier = self.parse_identifier_reference()?;
|
||||
let key =
|
||||
self.ast.alloc(IdentifierName { span: identifier.span, name: identifier.name.clone() });
|
||||
let key = self.ast.alloc_identifier_name(identifier.span, identifier.name.clone());
|
||||
// IdentifierReference ({ foo })
|
||||
let value = Expression::Identifier(self.ast.alloc(identifier.clone()));
|
||||
// CoverInitializedName ({ foo = bar })
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ impl<'a> ParserImpl<'a> {
|
|||
// Section 14.13 Labelled Statement
|
||||
// Avoids lookahead for a labeled statement, which is on a hot path
|
||||
if self.eat(Kind::Colon) {
|
||||
let label = LabelIdentifier { span: ident.span, name: ident.name.clone() };
|
||||
let label = self.ast.label_identifier(ident.span, ident.name.clone());
|
||||
let body = self.parse_statement_list_item(StatementContext::Label)?;
|
||||
return Ok(self.ast.statement_labeled(self.end_span(span), label, body));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ impl<'a> ParserImpl<'a> {
|
|||
Kind::This => {
|
||||
let span = self.start_span();
|
||||
self.bump_any(); // bump `this`
|
||||
let this_type = TSThisType { span: self.end_span(span) };
|
||||
let this_type = self.ast.ts_this_type(self.end_span(span));
|
||||
if self.peek_at(Kind::Is) && !self.peek_token().is_on_new_line {
|
||||
return self.parse_this_type_predicate(this_type);
|
||||
}
|
||||
|
|
@ -664,7 +664,7 @@ impl<'a> ParserImpl<'a> {
|
|||
fn parse_this_type_node(&mut self) -> TSThisType {
|
||||
let span = self.start_span();
|
||||
self.bump_any(); // bump `this`
|
||||
TSThisType { span: self.end_span(span) }
|
||||
self.ast.ts_this_type(self.end_span(span))
|
||||
}
|
||||
|
||||
fn parse_ts_type_constraint(&mut self) -> Result<Option<TSType<'a>>> {
|
||||
|
|
@ -877,17 +877,15 @@ impl<'a> ParserImpl<'a> {
|
|||
let element_type = self.parse_tuple_element_type()?;
|
||||
let span = self.end_span(span);
|
||||
return Ok(if dotdotdot {
|
||||
TSTupleElement::TSRestType(self.ast.alloc(TSRestType {
|
||||
span,
|
||||
type_annotation: self.ast.ts_type_named_tuple_member(
|
||||
self.end_span(member_span),
|
||||
element_type,
|
||||
label,
|
||||
// TODO: A tuple member cannot be both optional and rest. (TS5085)
|
||||
// See typescript suite <conformance/types/tuple/restTupleElements1.ts>
|
||||
optional,
|
||||
),
|
||||
}))
|
||||
let type_annotation = self.ast.ts_type_named_tuple_member(
|
||||
self.end_span(member_span),
|
||||
element_type,
|
||||
label,
|
||||
// TODO: A tuple member cannot be both optional and rest. (TS5085)
|
||||
// See typescript suite <conformance/types/tuple/restTupleElements1.ts>
|
||||
optional,
|
||||
);
|
||||
self.ast.ts_tuple_element_rest_type(span, type_annotation)
|
||||
} else {
|
||||
TSTupleElement::from(self.ast.ts_type_named_tuple_member(
|
||||
span,
|
||||
|
|
@ -920,9 +918,7 @@ impl<'a> ParserImpl<'a> {
|
|||
let span = self.start_span();
|
||||
if self.eat(Kind::Dot3) {
|
||||
let ty = self.parse_ts_type()?;
|
||||
return Ok(TSTupleElement::TSRestType(
|
||||
self.ast.alloc(TSRestType { span: self.end_span(span), type_annotation: ty }),
|
||||
));
|
||||
return Ok(self.ast.ts_tuple_element_rest_type(self.end_span(span), ty));
|
||||
}
|
||||
let ty = self.parse_ts_type()?;
|
||||
if let TSType::JSDocNullableType(ty) = ty {
|
||||
|
|
|
|||
Loading…
Reference in a new issue