From 6647752e034d1c4ea4ac6fa4531bc54b7eedbcd0 Mon Sep 17 00:00:00 2001 From: Shannon Rothe Date: Thu, 2 Mar 2023 18:52:46 +1100 Subject: [PATCH] refactor(ast): change `Option` to `Vec` for decorators (#84) * remove `Option` from `FormalParameter` * `unwrap` -> `unwrap_or_else` * prefer `AstBuilder` helper * implement `consume_decorators` --- crates/oxc_ast/src/ast/js.rs | 16 ++++++++-------- crates/oxc_ast/src/ast_builder.rs | 4 ++-- crates/oxc_ast/src/visit.rs | 24 ++++++++---------------- crates/oxc_parser/src/js/function.rs | 10 ++++++++-- crates/oxc_parser/src/lib.rs | 2 +- crates/oxc_parser/src/state.rs | 19 ++++++++++++++----- crates/oxc_parser/src/ts/statement.rs | 2 +- 7 files changed, 42 insertions(+), 35 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 98bb51ec3..e534176e0 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1249,8 +1249,8 @@ pub struct FormalParameter<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub accessibility: Option, pub readonly: bool, - #[serde(skip_serializing_if = "Option::is_none")] - pub decorators: Option>>, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub decorators: Vec<'a, Decorator<'a>>, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -1326,8 +1326,8 @@ pub struct Class<'a> { pub super_type_parameters: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub implements: Option>>>, - #[serde(skip_serializing_if = "Option::is_none")] - pub decorators: Option>>, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub decorators: Vec<'a, Decorator<'a>>, /// Valid Modifiers: `export`, `abstract` #[serde(skip_serializing_if = "Modifiers::is_none")] pub modifiers: Modifiers<'a>, @@ -1454,8 +1454,8 @@ pub struct MethodDefinition<'a> { pub optional: bool, #[serde(skip_serializing_if = "Option::is_none")] pub accessibility: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub decorators: Option>>, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub decorators: Vec<'a, Decorator<'a>>, } #[derive(Debug, Serialize, PartialEq, Hash)] @@ -1477,8 +1477,8 @@ pub struct PropertyDefinition<'a> { pub type_annotation: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub accessibility: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub decorators: Option>>, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub decorators: Vec<'a, Decorator<'a>>, } #[derive(Debug, Clone, Copy, Serialize, Eq, PartialEq, Hash)] diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index 35a83763f..8647dd505 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -692,7 +692,7 @@ impl<'a> AstBuilder<'a> { pattern: BindingPattern<'a>, accessibility: Option, readonly: bool, - decorators: Option>>, + decorators: Vec<'a, Decorator<'a>>, ) -> FormalParameter<'a> { FormalParameter { span, pattern, accessibility, readonly, decorators } } @@ -754,7 +754,7 @@ impl<'a> AstBuilder<'a> { type_parameters: Option>>, super_type_parameters: Option>>, implements: Option>>>, - decorators: Option>>, + decorators: Vec<'a, Decorator<'a>>, modifiers: Modifiers<'a>, ) -> Box<'a, Class<'a>> { self.alloc(Class { diff --git a/crates/oxc_ast/src/visit.rs b/crates/oxc_ast/src/visit.rs index e99485565..482236a99 100644 --- a/crates/oxc_ast/src/visit.rs +++ b/crates/oxc_ast/src/visit.rs @@ -339,10 +339,8 @@ pub trait Visit<'a>: Sized { fn visit_formal_parameter(&mut self, param: &'a FormalParameter<'a>) { let kind = AstKind::FormalParameter(param); self.enter_node(kind); - if let Some(decorators) = ¶m.decorators { - for decorator in decorators { - self.visit_decorator(decorator); - } + for decorator in ¶m.decorators { + self.visit_decorator(decorator); } self.visit_pattern(¶m.pattern); self.leave_node(kind); @@ -360,10 +358,8 @@ pub trait Visit<'a>: Sized { fn visit_class(&mut self, class: &'a Class<'a>) { let kind = AstKind::Class(class); self.enter_node(kind); - if let Some(decorators) = &class.decorators { - for decorator in decorators { - self.visit_decorator(decorator); - } + for decorator in &class.decorators { + self.visit_decorator(decorator); } if let Some(id) = &class.id { self.visit_binding_identifier(id); @@ -421,10 +417,8 @@ pub trait Visit<'a>: Sized { fn visit_method_definition(&mut self, def: &'a MethodDefinition<'a>) { let kind = AstKind::MethodDefinition(def); self.enter_node(kind); - if let Some(decorators) = &def.decorators { - for decorator in decorators { - self.visit_decorator(decorator); - } + for decorator in &def.decorators { + self.visit_decorator(decorator); } self.visit_property_key(&def.key); self.visit_function(&def.value); @@ -434,10 +428,8 @@ pub trait Visit<'a>: Sized { fn visit_property_definition(&mut self, def: &'a PropertyDefinition<'a>) { let kind = AstKind::PropertyDefinition(def); self.enter_node(kind); - if let Some(decorators) = &def.decorators { - for decorator in decorators { - self.visit_decorator(decorator); - } + for decorator in &def.decorators { + self.visit_decorator(decorator); } self.visit_property_key(&def.key); if let Some(value) = &def.value { diff --git a/crates/oxc_parser/src/js/function.rs b/crates/oxc_parser/src/js/function.rs index 2663ce21b..b734d812b 100644 --- a/crates/oxc_parser/src/js/function.rs +++ b/crates/oxc_parser/src/js/function.rs @@ -2,7 +2,7 @@ use oxc_allocator::Box; use oxc_ast::{ ast::*, context::{Context, StatementContext}, - GetSpan, Span, + AstBuilder, GetSpan, Span, }; use oxc_diagnostics::Result; @@ -235,7 +235,13 @@ impl<'a> Parser<'a> { let ident = self.ast.binding_identifier(param); let pattern = self.ast.binding_pattern(ident, None, false); let params_span = self.end_span(params_span); - let formal_parameter = self.ast.formal_parameter(params_span, pattern, None, false, None); + let formal_parameter = self.ast.formal_parameter( + params_span, + pattern, + None, + false, + AstBuilder::new_vec(&self.ast), + ); let params = self.ast.formal_parameters( params_span, FormalParameterKind::ArrowFormalParameters, diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index b20eb5970..ba868876b 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -71,7 +71,7 @@ impl<'a> Parser<'a> { errors, token: Token::default(), prev_token_end: 0, - state: ParserState::default(), + state: ParserState::new(allocator), ctx: source_type.default_context(), ast: AstBuilder::new(allocator), } diff --git a/crates/oxc_parser/src/state.rs b/crates/oxc_parser/src/state.rs index 3121b7239..5ec8f0f30 100644 --- a/crates/oxc_parser/src/state.rs +++ b/crates/oxc_parser/src/state.rs @@ -1,17 +1,26 @@ use std::collections::HashSet; -use oxc_allocator::Vec; +use oxc_allocator::{Allocator, Vec}; use oxc_ast::ast::Decorator; -#[derive(Default)] pub struct ParserState<'a> { + allocator: &'a Allocator, + pub not_parenthesized_arrow: HashSet, - pub decorators: Option>>, + pub decorators: Vec<'a, Decorator<'a>>, } impl<'a> ParserState<'a> { - pub fn consume_decorators(&mut self) -> Option>> { - self.decorators.take() + pub fn new(allocator: &'a Allocator) -> Self { + Self { + allocator, + not_parenthesized_arrow: HashSet::new(), + decorators: Vec::new_in(allocator), + } + } + + pub fn consume_decorators(&mut self) -> Vec<'a, Decorator<'a>> { + std::mem::replace(&mut self.decorators, Vec::new_in(self.allocator)) } } diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index aa392129e..9804db4f1 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -492,7 +492,7 @@ impl<'a> Parser<'a> { self.ctx = self.ctx.and_decorator(in_decorator); - self.state.decorators = Some(decorators); + self.state.decorators = decorators; Ok(()) }