From c01df484dbaad75c72093b0dd9c895d63f1be840 Mon Sep 17 00:00:00 2001 From: Boshen Date: Mon, 29 May 2023 12:34:49 +0800 Subject: [PATCH] refactor(hir,syntax): define Precedence for hir expressions --- crates/oxc_hir/src/hir.rs | 67 ----------- crates/oxc_hir/src/lib.rs | 1 + crates/oxc_hir/src/precedence.rs | 128 ++++++++++++++++++++++ crates/oxc_minifier/src/compressor/mod.rs | 1 + crates/oxc_parser/src/js/operator.rs | 6 +- crates/oxc_syntax/src/precedence.rs | 48 ++++---- 6 files changed, 160 insertions(+), 91 deletions(-) create mode 100644 crates/oxc_hir/src/precedence.rs diff --git a/crates/oxc_hir/src/hir.rs b/crates/oxc_hir/src/hir.rs index d91d6c068..843482d9f 100644 --- a/crates/oxc_hir/src/hir.rs +++ b/crates/oxc_hir/src/hir.rs @@ -208,23 +208,6 @@ impl<'a> Expression<'a> { _ => false, } } - - // - pub fn precedence(&self) -> u8 { - match self { - Self::SequenceExpression(_) => 0, - Self::AssignmentExpression(_) => 1, - Self::YieldExpression(_) => 2, - Self::ConditionalExpression(_) => 3, - Self::LogicalExpression(expr) => expr.precedence(), // 4 - 6 - Self::BinaryExpression(expr) => expr.precedence(), // 7 - 15 - Self::UnaryExpression(expr) => expr.precedence(), // 16, - Self::UpdateExpression(expr) => expr.precedence(), // 16 - Self::AwaitExpression(_) | Self::NewExpression(_) => 16, - Self::ParenthesizedExpression(_) => 19, - _ => 18, - } - } } #[derive(Debug, Clone, Hash)] @@ -755,12 +738,6 @@ pub struct UpdateExpression<'a> { pub argument: SimpleAssignmentTarget<'a>, } -impl<'a> UpdateExpression<'a> { - pub fn precedence(&self) -> u8 { - 17 - } -} - /// Unary Expression #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] @@ -771,12 +748,6 @@ pub struct UnaryExpression<'a> { pub argument: Expression<'a>, } -impl<'a> UnaryExpression<'a> { - pub fn precedence(&self) -> u8 { - 16 - } -} - /// Binary Expression #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] @@ -788,34 +759,6 @@ pub struct BinaryExpression<'a> { pub right: Expression<'a>, } -impl<'a> BinaryExpression<'a> { - pub fn precedence(&self) -> u8 { - match self.operator { - BinaryOperator::BitwiseOR => 7, - BinaryOperator::BitwiseXOR => 8, - BinaryOperator::BitwiseAnd => 9, - BinaryOperator::Equality - | BinaryOperator::Inequality - | BinaryOperator::StrictEquality - | BinaryOperator::StrictInequality => 10, - BinaryOperator::LessThan - | BinaryOperator::LessEqualThan - | BinaryOperator::GreaterThan - | BinaryOperator::GreaterEqualThan - | BinaryOperator::Instanceof - | BinaryOperator::In => 11, - BinaryOperator::ShiftLeft - | BinaryOperator::ShiftRight - | BinaryOperator::ShiftRightZeroFill => 12, - BinaryOperator::Subtraction | BinaryOperator::Addition => 13, - BinaryOperator::Multiplication - | BinaryOperator::Remainder - | BinaryOperator::Division => 14, - BinaryOperator::Exponential => 15, - } - } -} - /// Private Identifier in Shift Expression #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] @@ -837,16 +780,6 @@ pub struct LogicalExpression<'a> { pub right: Expression<'a>, } -impl<'a> LogicalExpression<'a> { - pub fn precedence(&self) -> u8 { - match self.operator { - LogicalOperator::Or => 4, - LogicalOperator::And => 5, - LogicalOperator::Coalesce => 6, - } - } -} - /// Conditional Expression #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] diff --git a/crates/oxc_hir/src/lib.rs b/crates/oxc_hir/src/lib.rs index b10fce15d..d33ba9041 100644 --- a/crates/oxc_hir/src/lib.rs +++ b/crates/oxc_hir/src/lib.rs @@ -5,6 +5,7 @@ mod serialize; pub mod hir; mod hir_builder; +pub mod precedence; mod visit_mut; use oxc_index::define_index_type; diff --git a/crates/oxc_hir/src/precedence.rs b/crates/oxc_hir/src/precedence.rs new file mode 100644 index 000000000..7275cf5fe --- /dev/null +++ b/crates/oxc_hir/src/precedence.rs @@ -0,0 +1,128 @@ +use oxc_syntax::{ + operator::{BinaryOperator, LogicalOperator}, + precedence::{GetPrecedence, Precedence}, +}; + +use crate::hir::{ + AssignmentExpression, AwaitExpression, BinaryExpression, CallExpression, ConditionalExpression, + Expression, LogicalExpression, MemberExpression, NewExpression, SequenceExpression, + UnaryExpression, UpdateExpression, YieldExpression, +}; + +impl<'a> GetPrecedence for Expression<'a> { + fn precedence(&self) -> Precedence { + match self { + Self::SequenceExpression(expr) => expr.precedence(), + Self::AssignmentExpression(expr) => expr.precedence(), + Self::YieldExpression(expr) => expr.precedence(), + Self::ConditionalExpression(expr) => expr.precedence(), + Self::LogicalExpression(expr) => expr.precedence(), + Self::BinaryExpression(expr) => expr.precedence(), + Self::UnaryExpression(expr) => expr.precedence(), + Self::UpdateExpression(expr) => expr.precedence(), + Self::AwaitExpression(expr) => expr.precedence(), + Self::NewExpression(expr) => expr.precedence(), + Self::CallExpression(expr) => expr.precedence(), + Self::MemberExpression(expr) => expr.precedence(), + _ => Precedence::Lowest, + } + } +} + +impl<'a> GetPrecedence for SequenceExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Comma + } +} + +impl<'a> GetPrecedence for YieldExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Yield + } +} + +impl<'a> GetPrecedence for AssignmentExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Assign + } +} + +impl<'a> GetPrecedence for ConditionalExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Compare + } +} + +impl<'a> GetPrecedence for LogicalExpression<'a> { + fn precedence(&self) -> Precedence { + match self.operator { + LogicalOperator::Or => Precedence::LogicalOr, + LogicalOperator::And => Precedence::LogicalAnd, + LogicalOperator::Coalesce => Precedence::Coalesce, + } + } +} + +impl<'a> GetPrecedence for BinaryExpression<'a> { + fn precedence(&self) -> Precedence { + match self.operator { + BinaryOperator::BitwiseOR => Precedence::BitwiseOr, + BinaryOperator::BitwiseXOR => Precedence::BitwiseXor, + BinaryOperator::BitwiseAnd => Precedence::BitwiseAnd, + BinaryOperator::Equality + | BinaryOperator::Inequality + | BinaryOperator::StrictEquality + | BinaryOperator::StrictInequality => Precedence::Equality, + BinaryOperator::LessThan + | BinaryOperator::LessEqualThan + | BinaryOperator::GreaterThan + | BinaryOperator::GreaterEqualThan + | BinaryOperator::Instanceof + | BinaryOperator::In => Precedence::Compare, + BinaryOperator::ShiftLeft + | BinaryOperator::ShiftRight + | BinaryOperator::ShiftRightZeroFill => Precedence::Shift, + BinaryOperator::Subtraction | BinaryOperator::Addition => Precedence::Add, + BinaryOperator::Multiplication + | BinaryOperator::Remainder + | BinaryOperator::Division => Precedence::Multiply, + BinaryOperator::Exponential => Precedence::Exponential, + } + } +} + +impl<'a> GetPrecedence for UnaryExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Prefix + } +} + +impl<'a> GetPrecedence for AwaitExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Prefix + } +} + +impl<'a> GetPrecedence for UpdateExpression<'a> { + fn precedence(&self) -> Precedence { + if self.prefix { Precedence::Prefix } else { Precedence::Postfix } + } +} + +impl<'a> GetPrecedence for CallExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Call + } +} + +impl<'a> GetPrecedence for NewExpression<'a> { + fn precedence(&self) -> Precedence { + if self.arguments.is_empty() { Precedence::New } else { Precedence::Call } + } +} + +impl<'a> GetPrecedence for MemberExpression<'a> { + fn precedence(&self) -> Precedence { + Precedence::Member + } +} diff --git a/crates/oxc_minifier/src/compressor/mod.rs b/crates/oxc_minifier/src/compressor/mod.rs index 3d349ec6d..19d34417d 100644 --- a/crates/oxc_minifier/src/compressor/mod.rs +++ b/crates/oxc_minifier/src/compressor/mod.rs @@ -9,6 +9,7 @@ use oxc_semantic2::Semantic; use oxc_span::Span; use oxc_syntax::{ operator::{BinaryOperator, UnaryOperator}, + precedence::GetPrecedence, NumberBase, }; diff --git a/crates/oxc_parser/src/js/operator.rs b/crates/oxc_parser/src/js/operator.rs index 4907d34ff..ae362ec67 100644 --- a/crates/oxc_parser/src/js/operator.rs +++ b/crates/oxc_parser/src/js/operator.rs @@ -23,10 +23,10 @@ pub fn kind_to_precedence(kind: Kind) -> Option { | Kind::Instanceof | Kind::In | Kind::As - | Kind::Satisfies => Some(Precedence::Relational), + | Kind::Satisfies => Some(Precedence::Compare), Kind::ShiftLeft | Kind::ShiftRight | Kind::ShiftRight3 => Some(Precedence::Shift), - Kind::Plus | Kind::Minus => Some(Precedence::Additive), - Kind::Star | Kind::Slash | Kind::Percent => Some(Precedence::Multiplicative), + Kind::Plus | Kind::Minus => Some(Precedence::Add), + Kind::Star | Kind::Slash | Kind::Percent => Some(Precedence::Multiply), Kind::Star2 => Some(Precedence::Exponential), _ => None, } diff --git a/crates/oxc_syntax/src/precedence.rs b/crates/oxc_syntax/src/precedence.rs index 99a87ff64..129ec802d 100644 --- a/crates/oxc_syntax/src/precedence.rs +++ b/crates/oxc_syntax/src/precedence.rs @@ -2,27 +2,29 @@ #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] #[repr(u8)] pub enum Precedence { - Comma = 0, - // Yield = 1, - // Assignment = 2, - // Conditional = 3, - Coalesce = 4, - LogicalOr = 5, - LogicalAnd = 6, - BitwiseOr = 7, - BitwiseXor = 8, - BitwiseAnd = 9, - Equality = 10, - Relational = 11, - Shift = 12, - Additive = 13, - Multiplicative = 14, - Exponential = 15, - // Unary = 16, - // Update = 17, - // LeftHandSide = 18, - // Member = 19, - // Primary = 20, + Lowest = 0, + Comma, + Spread, + Yield, + Assign, + Conditional, + Coalesce, + LogicalOr, + LogicalAnd, + BitwiseOr, + BitwiseXor, + BitwiseAnd, + Equality, + Compare, + Shift, + Add, + Multiply, + Exponential, + Prefix, + Postfix, + New, + Call, + Member, } impl Precedence { @@ -34,3 +36,7 @@ impl Precedence { right == Self::Exponential } } + +pub trait GetPrecedence { + fn precedence(&self) -> Precedence; +}