Skip to content

Commit

Permalink
refactor(codegen): add GetSpan requirement to Gen trait (#5772)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Sep 14, 2024
1 parent 4abfa76 commit 7caae5b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 115 deletions.
10 changes: 10 additions & 0 deletions crates/oxc_ast/src/ast_impl/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@ impl<'a> TSModuleDeclaration<'a> {
}
}

impl TSModuleDeclarationKind {
pub fn as_str(&self) -> &str {
match self {
Self::Global => "global",
Self::Module => "module",
Self::Namespace => "namespace",
}
}
}

impl<'a> TSModuleDeclarationName<'a> {
pub fn is_string_literal(&self) -> bool {
matches!(self, Self::StringLiteral(_))
Expand Down
29 changes: 20 additions & 9 deletions crates/oxc_codegen/src/binary_expr_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ use oxc_syntax::{
precedence::{GetPrecedence, Precedence},
};

use crate::{
gen::{Gen, GenExpr},
Codegen, Context,
};
use crate::{gen::GenExpr, Codegen, Context, Operator};

#[derive(Clone, Copy)]
pub enum Binaryish<'a> {
Expand Down Expand Up @@ -49,11 +46,25 @@ pub enum BinaryishOperator {
Logical(LogicalOperator),
}

impl Gen for BinaryishOperator {
fn gen(&self, p: &mut Codegen, ctx: Context) {
fn print_binary_operator(op: BinaryOperator, p: &mut Codegen) {
let operator = op.as_str();
if op.is_keyword() {
p.print_space_before_identifier();
p.print_str(operator);
} else {
let op: Operator = op.into();
p.print_space_before_operator(op);
p.print_str(operator);
p.prev_op = Some(op);
p.prev_op_end = p.code().len();
}
}

impl BinaryishOperator {
fn gen(self, p: &mut Codegen) {
match self {
Self::Binary(op) => op.gen(p, ctx),
Self::Logical(op) => op.gen(p, ctx),
Self::Binary(op) => print_binary_operator(op, p),
Self::Logical(op) => p.print_str(op.as_str()),
}
}
}
Expand Down Expand Up @@ -185,7 +196,7 @@ impl<'a> BinaryExpressionVisitor<'a> {

pub fn visit_right_and_finish(&self, p: &mut Codegen) {
p.print_soft_space();
self.operator.gen(p, Context::empty());
self.operator.gen(p);
p.print_soft_space();
self.e.right().gen_expr(p, self.right_precedence, self.ctx & Context::FORBID_IN);
if self.wrap {
Expand Down
149 changes: 45 additions & 104 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::{borrow::Cow, ops::Not};

use cow_utils::CowUtils;
use oxc_allocator::{Box, Vec};
#[allow(clippy::wildcard_imports)]
use oxc_ast::ast::*;
use oxc_span::GetSpan;
use oxc_syntax::{
identifier::{LS, PS},
keyword::is_reserved_keyword_or_global_object,
operator::{BinaryOperator, LogicalOperator, UnaryOperator},
operator::UnaryOperator,
precedence::{GetPrecedence, Precedence},
};

Expand All @@ -18,32 +17,12 @@ use crate::{
Codegen, Context, Operator,
};

pub trait Gen {
#[allow(unused_variables)]
fn gen(&self, p: &mut Codegen, ctx: Context) {}
pub trait Gen: GetSpan {
fn gen(&self, p: &mut Codegen, ctx: Context);
}

pub trait GenExpr {
#[allow(unused_variables)]
fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context) {}
}

impl<'a, T> Gen for Box<'a, T>
where
T: Gen,
{
fn gen(&self, p: &mut Codegen, ctx: Context) {
(**self).gen(p, ctx);
}
}

impl<'a, T> GenExpr for Box<'a, T>
where
T: GenExpr,
{
fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context) {
(**self).gen_expr(p, precedence, ctx);
}
pub trait GenExpr: GetSpan {
fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context);
}

impl<'a> Gen for Program<'a> {
Expand Down Expand Up @@ -679,9 +658,13 @@ impl<'a> Gen for FunctionBody<'a> {

impl<'a> Gen for FormalParameter<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
self.decorators.gen(p, ctx);
for decorator in &self.decorators {
decorator.gen(p, ctx);
p.print_hard_space();
}
if let Some(accessibility) = self.accessibility {
accessibility.gen(p, ctx);
p.print_str(accessibility.as_str());
p.print_hard_space();
}
if self.readonly {
p.print_str("readonly ");
Expand Down Expand Up @@ -1716,28 +1699,6 @@ impl<'a> GenExpr for BinaryExpression<'a> {
}
}

impl Gen for LogicalOperator {
fn gen(&self, p: &mut Codegen, _ctx: Context) {
p.print_str(self.as_str());
}
}

impl Gen for BinaryOperator {
fn gen(&self, p: &mut Codegen, _ctx: Context) {
let operator = self.as_str();
if self.is_keyword() {
p.print_space_before_identifier();
p.print_str(operator);
} else {
let op: Operator = (*self).into();
p.print_space_before_operator(op);
p.print_str(operator);
p.prev_op = Some(op);
p.prev_op_end = p.code().len();
}
}
}

impl<'a> GenExpr for PrivateInExpression<'a> {
fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context) {
p.wrap(precedence >= Precedence::Compare, |p| {
Expand Down Expand Up @@ -1868,7 +1829,15 @@ impl<'a> Gen for ArrayAssignmentTarget<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span.start);
p.print_char(b'[');
p.print_list(&self.elements, ctx);
for (index, item) in self.elements.iter().enumerate() {
if index != 0 {
p.print_comma();
p.print_soft_space();
}
if let Some(item) = item {
item.gen(p, ctx);
}
}
if let Some(target) = &self.rest {
if !self.elements.is_empty() {
p.print_comma();
Expand All @@ -1884,14 +1853,6 @@ impl<'a> Gen for ArrayAssignmentTarget<'a> {
}
}

impl<'a> Gen for Option<AssignmentTargetMaybeDefault<'a>> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
if let Some(arg) = self {
arg.gen(p, ctx);
}
}
}

impl<'a> Gen for ObjectAssignmentTarget<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span.start);
Expand Down Expand Up @@ -2166,7 +2127,10 @@ impl<'a> Gen for Class<'a> {
let n = p.code_len();
let wrap = self.is_expression() && (p.start_of_stmt == n || p.start_of_default_export == n);
p.wrap(wrap, |p| {
self.decorators.gen(p, ctx);
for decorator in &self.decorators {
decorator.gen(p, ctx);
p.print_hard_space();
}
if self.declare {
p.print_str("declare ");
}
Expand Down Expand Up @@ -2469,10 +2433,14 @@ impl<'a> Gen for StaticBlock<'a> {
impl<'a> Gen for MethodDefinition<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span.start);
self.decorators.gen(p, ctx);
for decorator in &self.decorators {
decorator.gen(p, ctx);
p.print_hard_space();
}

if let Some(accessibility) = &self.accessibility {
accessibility.gen(p, ctx);
p.print_str(accessibility.as_str());
p.print_hard_space();
}
if self.r#type == MethodDefinitionType::TSAbstractMethodDefinition {
p.print_str("abstract ");
Expand Down Expand Up @@ -2532,12 +2500,16 @@ impl<'a> Gen for MethodDefinition<'a> {
impl<'a> Gen for PropertyDefinition<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span.start);
self.decorators.gen(p, ctx);
for decorator in &self.decorators {
decorator.gen(p, ctx);
p.print_hard_space();
}
if self.declare {
p.print_str("declare ");
}
if let Some(accessibility) = &self.accessibility {
accessibility.gen(p, ctx);
if let Some(accessibility) = self.accessibility {
p.print_str(accessibility.as_str());
p.print_hard_space();
}
if self.r#type == PropertyDefinitionType::TSAbstractPropertyDefinition {
p.print_str("abstract ");
Expand Down Expand Up @@ -2575,12 +2547,16 @@ impl<'a> Gen for PropertyDefinition<'a> {
impl<'a> Gen for AccessorProperty<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span.start);
self.decorators.gen(p, ctx);
for decorator in &self.decorators {
decorator.gen(p, ctx);
p.print_hard_space();
}
if self.r#type.is_abstract() {
p.print_str("abstract ");
}
if let Some(accessibility) = &self.accessibility {
accessibility.gen(p, ctx);
if let Some(accessibility) = self.accessibility {
p.print_str(accessibility.as_str());
p.print_hard_space();
}
if self.r#static {
p.print_str("static ");
Expand Down Expand Up @@ -2740,15 +2716,6 @@ impl<'a> Gen for AssignmentPattern<'a> {
}
}

impl<'a> Gen for Vec<'a, Decorator<'a>> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
for decorator in self {
decorator.gen(p, ctx);
p.print_hard_space();
}
}
}

impl<'a> Gen for Decorator<'a> {
fn gen(&self, p: &mut Codegen, _ctx: Context) {
fn need_wrap(expr: &Expression) -> bool {
Expand Down Expand Up @@ -3427,7 +3394,7 @@ impl<'a> Gen for TSModuleDeclaration<'a> {
if self.declare {
p.print_str("declare ");
}
self.kind.gen(p, ctx);
p.print_str(self.kind.as_str());
// If the kind is global, then the id is also `global`, so we don't need to print it
if !self.kind.is_global() {
p.print_space_before_identifier();
Expand Down Expand Up @@ -3459,22 +3426,6 @@ impl<'a> Gen for TSModuleDeclaration<'a> {
}
}

impl Gen for TSModuleDeclarationKind {
fn gen(&self, p: &mut Codegen, _: Context) {
match self {
TSModuleDeclarationKind::Global => {
p.print_str("global");
}
TSModuleDeclarationKind::Module => {
p.print_str("module");
}
TSModuleDeclarationKind::Namespace => {
p.print_str("namespace");
}
}
}
}

impl<'a> Gen for TSModuleDeclarationName<'a> {
fn gen(&self, p: &mut Codegen, ctx: Context) {
match self {
Expand Down Expand Up @@ -3639,13 +3590,3 @@ impl<'a> Gen for TSModuleReference<'a> {
}
}
}

impl Gen for TSAccessibility {
fn gen(&self, p: &mut Codegen, _ctx: Context) {
match self {
Self::Public => p.print_str("public "),
Self::Private => p.print_str("private "),
Self::Protected => p.print_str("protected "),
}
}
}
5 changes: 3 additions & 2 deletions crates/oxc_linter/src/rules/eslint/no_unsafe_negation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ impl NoUnsafeNegation {
/// Precondition:
/// expr.left is `UnaryExpression` whose operator is '!'
fn report_with_fix<'a>(expr: &BinaryExpression, ctx: &LintContext<'a>) {
use oxc_codegen::{Context, Gen};
// Diagnostic points at the unexpected negation
let diagnostic = no_unsafe_negation_diagnostic(expr.operator.as_str(), expr.left.span());

Expand All @@ -88,7 +87,9 @@ impl NoUnsafeNegation {
let Expression::UnaryExpression(left) = &expr.left else { unreachable!() };
codegen.print_char(b'(');
codegen.print_expression(&left.argument);
expr.operator.gen(&mut codegen, Context::default());
codegen.print_char(b' ');
codegen.print_str(expr.operator.as_str());
codegen.print_char(b' ');
codegen.print_expression(&expr.right);
codegen.print_char(b')');
codegen.into_source_text()
Expand Down

0 comments on commit 7caae5b

Please sign in to comment.