Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(codegen): add GetSpan requirement to Gen trait #5772

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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