mirror of
https://github.com/danbulant/oxc
synced 2026-05-20 12:48:38 +00:00
refactor(formatter,linter,codegen): remove oxc_formatter (#1968)
closes #1941
This commit is contained in:
parent
b5f4f1eb68
commit
a6717db423
28 changed files with 73 additions and 2345 deletions
1
.github/codecov.yml
vendored
1
.github/codecov.yml
vendored
|
|
@ -24,6 +24,5 @@ ignore:
|
||||||
- "crates/oxc_type_synthesis"
|
- "crates/oxc_type_synthesis"
|
||||||
- "crates/oxc_query" # Not aiming for test coverage right now with @u9g
|
- "crates/oxc_query" # Not aiming for test coverage right now with @u9g
|
||||||
- "crates/oxc_linter_plugin"
|
- "crates/oxc_linter_plugin"
|
||||||
- "crates/oxc_formatter" # The formatter is not being actively worked on
|
|
||||||
- "crates/oxc_transformer" # not ready
|
- "crates/oxc_transformer" # not ready
|
||||||
- "crates/oxc_js_regex" # not ready
|
- "crates/oxc_js_regex" # not ready
|
||||||
|
|
|
||||||
2
.github/workflows/conformance.yml
vendored
2
.github/workflows/conformance.yml
vendored
|
|
@ -12,7 +12,6 @@ on:
|
||||||
- 'website/**'
|
- 'website/**'
|
||||||
- 'crates/oxc/**'
|
- 'crates/oxc/**'
|
||||||
- 'crates/oxc_cli/**'
|
- 'crates/oxc_cli/**'
|
||||||
- 'crates/oxc_formatter/**'
|
|
||||||
- 'crates/oxc_linter/**'
|
- 'crates/oxc_linter/**'
|
||||||
- 'crates/oxc_query/**'
|
- 'crates/oxc_query/**'
|
||||||
- 'crates/oxc_type_synthesis/**'
|
- 'crates/oxc_type_synthesis/**'
|
||||||
|
|
@ -30,7 +29,6 @@ on:
|
||||||
- 'website/**'
|
- 'website/**'
|
||||||
- 'crates/oxc/**'
|
- 'crates/oxc/**'
|
||||||
- 'crates/oxc_cli/**'
|
- 'crates/oxc_cli/**'
|
||||||
- 'crates/oxc_formatter/**'
|
|
||||||
- 'crates/oxc_linter/**'
|
- 'crates/oxc_linter/**'
|
||||||
- 'crates/oxc_query/**'
|
- 'crates/oxc_query/**'
|
||||||
- 'crates/oxc_type_synthesis/**'
|
- 'crates/oxc_type_synthesis/**'
|
||||||
|
|
|
||||||
15
Cargo.lock
generated
15
Cargo.lock
generated
|
|
@ -1530,7 +1530,6 @@ dependencies = [
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
"oxc_codegen",
|
"oxc_codegen",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_formatter",
|
|
||||||
"oxc_index",
|
"oxc_index",
|
||||||
"oxc_minifier",
|
"oxc_minifier",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
|
|
@ -1665,17 +1664,6 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "oxc_formatter"
|
|
||||||
version = "0.4.0"
|
|
||||||
dependencies = [
|
|
||||||
"oxc_allocator",
|
|
||||||
"oxc_ast",
|
|
||||||
"oxc_parser",
|
|
||||||
"oxc_span",
|
|
||||||
"oxc_syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxc_index"
|
name = "oxc_index"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
@ -1706,7 +1694,6 @@ dependencies = [
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_linter",
|
"oxc_linter",
|
||||||
"oxc_linter_plugin",
|
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
"oxc_semantic",
|
"oxc_semantic",
|
||||||
"oxc_span",
|
"oxc_span",
|
||||||
|
|
@ -1734,8 +1721,8 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
|
"oxc_codegen",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_formatter",
|
|
||||||
"oxc_index",
|
"oxc_index",
|
||||||
"oxc_macros",
|
"oxc_macros",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@ oxc_allocator = { version = "0.4.0", path = "crates/oxc_allocator" }
|
||||||
oxc_ast = { version = "0.4.0", path = "crates/oxc_ast" }
|
oxc_ast = { version = "0.4.0", path = "crates/oxc_ast" }
|
||||||
oxc_codegen = { version = "0.4.0", path = "crates/oxc_codegen" }
|
oxc_codegen = { version = "0.4.0", path = "crates/oxc_codegen" }
|
||||||
oxc_diagnostics = { version = "0.4.0", path = "crates/oxc_diagnostics" }
|
oxc_diagnostics = { version = "0.4.0", path = "crates/oxc_diagnostics" }
|
||||||
oxc_formatter = { version = "0.4.0", path = "crates/oxc_formatter" }
|
|
||||||
oxc_index = { version = "0.4.0", path = "crates/oxc_index" }
|
oxc_index = { version = "0.4.0", path = "crates/oxc_index" }
|
||||||
oxc_minifier = { version = "0.4.0", path = "crates/oxc_minifier" }
|
oxc_minifier = { version = "0.4.0", path = "crates/oxc_minifier" }
|
||||||
oxc_parser = { version = "0.4.0", path = "crates/oxc_parser" }
|
oxc_parser = { version = "0.4.0", path = "crates/oxc_parser" }
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ sed -i '' 's/0.3.0/0.4.0/' crates/oxc_allocator/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_ast/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_ast/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_codegen/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_codegen/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_diagnostics/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_diagnostics/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_formatter/Cargo.toml
|
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_index/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_index/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_minifier/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_minifier/Cargo.toml
|
||||||
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_parser/Cargo.toml
|
sed -i '' 's/0.3.0/0.4.0/' crates/oxc_parser/Cargo.toml
|
||||||
|
|
@ -60,7 +59,6 @@ cargo publish -p oxc_ast
|
||||||
cargo publish -p oxc_diagnostics
|
cargo publish -p oxc_diagnostics
|
||||||
cargo publish -p oxc_parser
|
cargo publish -p oxc_parser
|
||||||
cargo publish -p oxc_semantic
|
cargo publish -p oxc_semantic
|
||||||
cargo publish -p oxc_formatter
|
|
||||||
cargo publish -p oxc_transformer
|
cargo publish -p oxc_transformer
|
||||||
cargo publish -p oxc_codegen
|
cargo publish -p oxc_codegen
|
||||||
cargo publish -p oxc_minifier
|
cargo publish -p oxc_minifier
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ oxc_parser = { workspace = true }
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
oxc_syntax = { workspace = true }
|
oxc_syntax = { workspace = true }
|
||||||
oxc_semantic = { workspace = true, optional = true }
|
oxc_semantic = { workspace = true, optional = true }
|
||||||
oxc_formatter = { workspace = true, optional = true }
|
|
||||||
oxc_transformer = { workspace = true, optional = true }
|
oxc_transformer = { workspace = true, optional = true }
|
||||||
oxc_minifier = { workspace = true, optional = true }
|
oxc_minifier = { workspace = true, optional = true }
|
||||||
oxc_codegen = { workspace = true, optional = true }
|
oxc_codegen = { workspace = true, optional = true }
|
||||||
|
|
@ -36,7 +35,6 @@ oxc_codegen = { workspace = true, optional = true }
|
||||||
[features]
|
[features]
|
||||||
serde = ["oxc_ast/serde", "oxc_semantic/serde"]
|
serde = ["oxc_ast/serde", "oxc_semantic/serde"]
|
||||||
semantic = ["oxc_semantic"]
|
semantic = ["oxc_semantic"]
|
||||||
formatter = ["oxc_formatter"]
|
|
||||||
transformer = ["oxc_transformer"]
|
transformer = ["oxc_transformer"]
|
||||||
minifier = ["oxc_minifier"]
|
minifier = ["oxc_minifier"]
|
||||||
codegen = ["oxc_codegen"]
|
codegen = ["oxc_codegen"]
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,6 @@ pub mod semantic {
|
||||||
pub use oxc_semantic::*;
|
pub use oxc_semantic::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "formatter")]
|
|
||||||
pub mod formatter {
|
|
||||||
#[doc(inline)]
|
|
||||||
pub use oxc_formatter::*;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "transformer")]
|
#[cfg(feature = "transformer")]
|
||||||
pub mod transformer {
|
pub mod transformer {
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
pub fn and_in(self, include: bool) -> Self {
|
pub fn and_in(self, include: bool) -> Self {
|
||||||
self.and(Self::In, include)
|
self.and(Self::In, include)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ExpressionStatement<'a> {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
||||||
p.print_indent();
|
p.print_indent();
|
||||||
p.start_of_stmt = p.code_len();
|
p.start_of_stmt = p.code_len();
|
||||||
self.expression.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.expression);
|
||||||
if self.expression.is_specific_id("let") {
|
if self.expression.is_specific_id("let") {
|
||||||
p.print_semicolon();
|
p.print_semicolon();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -153,7 +153,7 @@ fn print_if<const MINIFY: bool>(
|
||||||
p.print_str(b"if");
|
p.print_str(b"if");
|
||||||
p.print_soft_space();
|
p.print_soft_space();
|
||||||
p.print(b'(');
|
p.print(b'(');
|
||||||
if_stmt.test.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&if_stmt.test);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
p.print_soft_space();
|
p.print_soft_space();
|
||||||
|
|
||||||
|
|
@ -251,14 +251,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForStatement<'a> {
|
||||||
p.print_soft_space();
|
p.print_soft_space();
|
||||||
|
|
||||||
if let Some(test) = self.test.as_ref() {
|
if let Some(test) = self.test.as_ref() {
|
||||||
test.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.print_semicolon();
|
p.print_semicolon();
|
||||||
p.print_soft_space();
|
p.print_soft_space();
|
||||||
|
|
||||||
if let Some(update) = self.update.as_ref() {
|
if let Some(update) = self.update.as_ref() {
|
||||||
update.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
|
|
@ -277,7 +277,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForInStatement<'a> {
|
||||||
p.print_space_before_identifier();
|
p.print_space_before_identifier();
|
||||||
p.print_str(b"in");
|
p.print_str(b"in");
|
||||||
p.print_hard_space();
|
p.print_hard_space();
|
||||||
self.right.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.right);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
p.print_soft_space();
|
p.print_soft_space();
|
||||||
self.body.gen(p, ctx);
|
self.body.gen(p, ctx);
|
||||||
|
|
@ -320,7 +320,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WhileStatement<'a> {
|
||||||
p.print_indent();
|
p.print_indent();
|
||||||
p.print_str(b"while");
|
p.print_str(b"while");
|
||||||
p.print(b'(');
|
p.print(b'(');
|
||||||
self.test.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.test);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
self.body.gen(p, ctx);
|
self.body.gen(p, ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -342,7 +342,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for DoWhileStatement<'a> {
|
||||||
}
|
}
|
||||||
p.print_str(b"while");
|
p.print_str(b"while");
|
||||||
p.print(b'(');
|
p.print(b'(');
|
||||||
self.test.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.test);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
p.print_semicolon_after_statement();
|
p.print_semicolon_after_statement();
|
||||||
}
|
}
|
||||||
|
|
@ -384,7 +384,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for SwitchStatement<'a> {
|
||||||
p.print_indent();
|
p.print_indent();
|
||||||
p.print_str(b"switch");
|
p.print_str(b"switch");
|
||||||
p.print(b'(');
|
p.print(b'(');
|
||||||
self.discriminant.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.discriminant);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
p.print_block_start();
|
p.print_block_start();
|
||||||
for case in &self.cases {
|
for case in &self.cases {
|
||||||
|
|
@ -404,7 +404,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for SwitchCase<'a> {
|
||||||
Some(test) => {
|
Some(test) => {
|
||||||
p.print_str(b"case");
|
p.print_str(b"case");
|
||||||
p.print_hard_space();
|
p.print_hard_space();
|
||||||
test.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(test);
|
||||||
}
|
}
|
||||||
None => p.print_str(b"default"),
|
None => p.print_str(b"default"),
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +425,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ReturnStatement<'a> {
|
||||||
p.print_str(b"return");
|
p.print_str(b"return");
|
||||||
if let Some(arg) = &self.argument {
|
if let Some(arg) = &self.argument {
|
||||||
p.print_hard_space();
|
p.print_hard_space();
|
||||||
arg.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(arg);
|
||||||
}
|
}
|
||||||
p.print_semicolon_after_statement();
|
p.print_semicolon_after_statement();
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +465,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ThrowStatement<'a> {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
||||||
p.print_indent();
|
p.print_indent();
|
||||||
p.print_str(b"throw ");
|
p.print_str(b"throw ");
|
||||||
self.argument.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.argument);
|
||||||
p.print_semicolon_after_statement();
|
p.print_semicolon_after_statement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -475,7 +475,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WithStatement<'a> {
|
||||||
p.print_indent();
|
p.print_indent();
|
||||||
p.print_str(b"with");
|
p.print_str(b"with");
|
||||||
p.print(b'(');
|
p.print(b'(');
|
||||||
self.object.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.object);
|
||||||
p.print(b')');
|
p.print(b')');
|
||||||
self.body.gen(p, ctx);
|
self.body.gen(p, ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -1645,7 +1645,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TemplateLiteral<'a> {
|
||||||
|
|
||||||
if let Some(expr) = expressions.next() {
|
if let Some(expr) = expressions.next() {
|
||||||
p.print_str(b"${");
|
p.print_str(b"${");
|
||||||
expr.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(expr);
|
||||||
p.print(b'}');
|
p.print(b'}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1825,7 +1825,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for JSXEmptyExpression {
|
||||||
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXExpression<'a> {
|
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXExpression<'a> {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
|
||||||
match self {
|
match self {
|
||||||
Self::Expression(expr) => expr.gen_expr(p, Precedence::lowest(), Context::default()),
|
Self::Expression(expr) => p.print_expression(expr),
|
||||||
Self::EmptyExpression(expr) => expr.gen(p, ctx),
|
Self::EmptyExpression(expr) => expr.gen(p, ctx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1853,7 +1853,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttributeValue<'a> {
|
||||||
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXSpreadAttribute<'a> {
|
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXSpreadAttribute<'a> {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
||||||
p.print_str(b"{...");
|
p.print_str(b"{...");
|
||||||
self.argument.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.argument);
|
||||||
p.print(b'}');
|
p.print(b'}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1924,7 +1924,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for JSXText {
|
||||||
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXSpreadChild<'a> {
|
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXSpreadChild<'a> {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
||||||
p.print_str(b"...");
|
p.print_str(b"...");
|
||||||
self.expression.gen_expr(p, Precedence::lowest(), Context::default());
|
p.print_expression(&self.expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1933,9 +1933,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXChild<'a> {
|
||||||
match self {
|
match self {
|
||||||
Self::Fragment(fragment) => fragment.gen(p, ctx),
|
Self::Fragment(fragment) => fragment.gen(p, ctx),
|
||||||
Self::Element(el) => el.gen(p, ctx),
|
Self::Element(el) => el.gen(p, ctx),
|
||||||
Self::Spread(spread) => {
|
Self::Spread(spread) => p.print_expression(&spread.expression),
|
||||||
spread.expression.gen_expr(p, Precedence::lowest(), Context::default());
|
|
||||||
}
|
|
||||||
Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx),
|
Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx),
|
||||||
Self::Text(text) => text.gen(p, ctx),
|
Self::Text(text) => text.gen(p, ctx),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use oxc_syntax::{
|
||||||
symbol::SymbolId,
|
symbol::SymbolId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{
|
pub use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
gen::{Gen, GenExpr},
|
gen::{Gen, GenExpr},
|
||||||
operator::Operator,
|
operator::Operator,
|
||||||
|
|
@ -111,12 +111,12 @@ impl<const MINIFY: bool> Codegen<MINIFY> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a single character into the buffer
|
/// Push a single character into the buffer
|
||||||
fn print(&mut self, ch: u8) {
|
pub fn print(&mut self, ch: u8) {
|
||||||
self.code.push(ch);
|
self.code.push(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a string into the buffer
|
/// Push a string into the buffer
|
||||||
fn print_str(&mut self, s: &[u8]) {
|
pub fn print_str(&mut self, s: &[u8]) {
|
||||||
self.code.extend_from_slice(s);
|
self.code.extend_from_slice(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ impl<const MINIFY: bool> Codegen<MINIFY> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_hard_space(&mut self) {
|
pub fn print_hard_space(&mut self) {
|
||||||
self.print(b' ');
|
self.print(b' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,7 +197,7 @@ impl<const MINIFY: bool> Codegen<MINIFY> {
|
||||||
self.print_str(b"...");
|
self.print_str(b"...");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_colon(&mut self) {
|
pub fn print_colon(&mut self) {
|
||||||
self.print(b':');
|
self.print(b':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,6 +256,10 @@ impl<const MINIFY: bool> Codegen<MINIFY> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_expression(&mut self, expr: &Expression<'_>) {
|
||||||
|
expr.gen_expr(self, Precedence::lowest(), Context::default());
|
||||||
|
}
|
||||||
|
|
||||||
fn print_expressions<T: GenExpr<MINIFY>>(
|
fn print_expressions<T: GenExpr<MINIFY>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
items: &[T],
|
items: &[T],
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "oxc_formatter"
|
|
||||||
version = "0.4.0"
|
|
||||||
authors.workspace = true
|
|
||||||
description.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
homepage.workspace = true
|
|
||||||
keywords.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
rust-version.workspace = true
|
|
||||||
categories.workspace = true
|
|
||||||
|
|
||||||
[lints]
|
|
||||||
workspace = true
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
doctest = false
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
oxc_allocator = { workspace = true }
|
|
||||||
oxc_ast = { workspace = true }
|
|
||||||
oxc_span = { workspace = true }
|
|
||||||
oxc_syntax = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
oxc_parser = { workspace = true }
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Formatter (Prettier)
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
use std::{env, path::Path};
|
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
|
||||||
use oxc_formatter::{Formatter, FormatterOptions};
|
|
||||||
use oxc_parser::Parser;
|
|
||||||
use oxc_span::SourceType;
|
|
||||||
|
|
||||||
// Instruction:
|
|
||||||
// create a `test.js`,
|
|
||||||
// run `cargo run -p oxc_formatter --example formatter`
|
|
||||||
// or `cargo watch -x "run -p oxc_formatter --example formatter"`
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string());
|
|
||||||
let path = Path::new(&name);
|
|
||||||
let source_text = std::fs::read_to_string(path).expect("{name} not found");
|
|
||||||
let allocator = Allocator::default();
|
|
||||||
let source_type = SourceType::from_path(path).unwrap();
|
|
||||||
let ret = Parser::new(&allocator, &source_text, source_type).parse();
|
|
||||||
|
|
||||||
if !ret.errors.is_empty() {
|
|
||||||
for error in ret.errors {
|
|
||||||
let error = error.with_source_code(source_text.clone());
|
|
||||||
println!("{error:?}");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let formatter_options = FormatterOptions::default();
|
|
||||||
let printed = Formatter::new(source_text.len(), formatter_options).build(&ret.program);
|
|
||||||
println!("{printed}");
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,323 +0,0 @@
|
||||||
//! Prettier
|
|
||||||
//!
|
|
||||||
//! This crate is intended to be [prettier](https://prettier.io).
|
|
||||||
//! Please use the `oxc_codegen ` for code generation.
|
|
||||||
|
|
||||||
mod gen;
|
|
||||||
|
|
||||||
#[allow(clippy::wildcard_imports)]
|
|
||||||
use oxc_ast::ast::*;
|
|
||||||
|
|
||||||
pub use crate::gen::Gen;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
||||||
/// @see [prettier](https://prettier.io/docs/en/options.html#end-of-line)
|
|
||||||
pub enum EndOfLine {
|
|
||||||
/// Line Feed only (`\n`), common on Linux and macOS as well as inside git repos
|
|
||||||
LF,
|
|
||||||
/// Carriage Return + Line Feed characters (`\r\n`), common on Windows
|
|
||||||
CRLF,
|
|
||||||
/// Carriage Return character only (`\r`), used very rarely
|
|
||||||
CR,
|
|
||||||
/// Maintain existing line endings (mixed values within one file are normalised by looking at what’s used after the first line)
|
|
||||||
Auto(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EndOfLine {
|
|
||||||
pub fn get_final_end_of_line(&self) -> FinalEndOfLine {
|
|
||||||
match self {
|
|
||||||
Self::Auto(raw_input) => Self::auto_detect_end_of_line(raw_input),
|
|
||||||
Self::LF => FinalEndOfLine::LF,
|
|
||||||
Self::CRLF => FinalEndOfLine::CRLF,
|
|
||||||
Self::CR => FinalEndOfLine::CR,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn auto_detect_end_of_line(raw_input_text: &str) -> FinalEndOfLine {
|
|
||||||
let first_line_feed_pos = raw_input_text.chars().position(|ch| ch == '\n');
|
|
||||||
first_line_feed_pos.map_or(FinalEndOfLine::CR, |first_line_feed_pos| {
|
|
||||||
let char_before_line_feed_pos = first_line_feed_pos.saturating_sub(1);
|
|
||||||
let char_before_line_feed = raw_input_text.chars().nth(char_before_line_feed_pos);
|
|
||||||
match char_before_line_feed {
|
|
||||||
Some('\r') => FinalEndOfLine::CRLF,
|
|
||||||
_ => FinalEndOfLine::LF,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum FinalEndOfLine {
|
|
||||||
LF,
|
|
||||||
CRLF,
|
|
||||||
CR,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct FormatterOptions {
|
|
||||||
pub indentation: u8,
|
|
||||||
// <https://prettier.io/docs/en/options#quotes>
|
|
||||||
pub single_quote: bool,
|
|
||||||
pub end_of_line: EndOfLine,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for FormatterOptions {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { indentation: 4, single_quote: false, end_of_line: EndOfLine::LF }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
/// processed and reserved for internal use
|
|
||||||
pub struct InnerOptions {
|
|
||||||
pub indentation: u8,
|
|
||||||
pub end_of_line: FinalEndOfLine,
|
|
||||||
pub single_quote: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<FormatterOptions> for InnerOptions {
|
|
||||||
fn from(options: FormatterOptions) -> Self {
|
|
||||||
Self {
|
|
||||||
indentation: options.indentation,
|
|
||||||
single_quote: options.single_quote,
|
|
||||||
end_of_line: options.end_of_line.get_final_end_of_line(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Formatter {
|
|
||||||
options: InnerOptions,
|
|
||||||
|
|
||||||
/// Output Code
|
|
||||||
code: Vec<u8>,
|
|
||||||
|
|
||||||
/// Current indentation tracking
|
|
||||||
indentation: u8,
|
|
||||||
|
|
||||||
// states
|
|
||||||
needs_semicolon: bool,
|
|
||||||
|
|
||||||
// Quote property with double quotes
|
|
||||||
quote_property_with_double_quotes: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Separator {
|
|
||||||
Comma,
|
|
||||||
Semicolon,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Codegen interface for pretty print or minification
|
|
||||||
impl Formatter {
|
|
||||||
pub fn new(source_len: usize, options: FormatterOptions) -> Self {
|
|
||||||
Self {
|
|
||||||
options: options.into(),
|
|
||||||
code: Vec::with_capacity(source_len),
|
|
||||||
indentation: 0,
|
|
||||||
needs_semicolon: false,
|
|
||||||
quote_property_with_double_quotes: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(mut self, program: &Program<'_>) -> String {
|
|
||||||
program.gen(&mut self);
|
|
||||||
self.into_code()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn into_code(self) -> String {
|
|
||||||
// SAFETY: criteria of `from_utf8_unchecked`.are met.
|
|
||||||
unsafe { String::from_utf8_unchecked(self.code) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn code(&self) -> &Vec<u8> {
|
|
||||||
&self.code
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Push a single character into the buffer
|
|
||||||
#[inline]
|
|
||||||
pub fn print(&mut self, ch: u8) {
|
|
||||||
self.code.push(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Push a string into the buffer
|
|
||||||
#[inline]
|
|
||||||
pub fn print_str(&mut self, s: &[u8]) {
|
|
||||||
self.code.extend_from_slice(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_space(&mut self) {
|
|
||||||
self.code.push(b' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_newline(&mut self) {
|
|
||||||
match self.options.end_of_line {
|
|
||||||
FinalEndOfLine::LF => {
|
|
||||||
self.code.push(b'\n');
|
|
||||||
}
|
|
||||||
FinalEndOfLine::CRLF => {
|
|
||||||
self.code.push(b'\r');
|
|
||||||
self.code.push(b'\n');
|
|
||||||
}
|
|
||||||
FinalEndOfLine::CR => {
|
|
||||||
self.code.push(b'\r');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn indent(&mut self) {
|
|
||||||
self.indentation += self.options.indentation;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn dedent(&mut self) {
|
|
||||||
self.indentation -= self.options.indentation;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_semicolon(&mut self) {
|
|
||||||
self.print(b';');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_comma(&mut self) {
|
|
||||||
self.print(b',');
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_semicolon_after_statement(&mut self) {
|
|
||||||
self.print_semicolon();
|
|
||||||
self.print_newline();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_semicolon_if_needed(&mut self) {
|
|
||||||
if self.needs_semicolon {
|
|
||||||
self.print_semicolon();
|
|
||||||
self.needs_semicolon = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_ellipsis(&mut self) {
|
|
||||||
self.print_str(b"...");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_colon(&mut self) {
|
|
||||||
self.print(b':');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_equal(&mut self) {
|
|
||||||
self.print(b'=');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_quote(&mut self) {
|
|
||||||
self.print(if self.options.single_quote { b'\'' } else { b'"' });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_indent(&mut self) {
|
|
||||||
for _ in 0..self.indentation {
|
|
||||||
self.print(b' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_sequence<T: Gen>(&mut self, items: &[T], separator: Separator) {
|
|
||||||
let len = items.len();
|
|
||||||
for (index, item) in items.iter().enumerate() {
|
|
||||||
item.gen(self);
|
|
||||||
match separator {
|
|
||||||
Separator::Semicolon => self.print_semicolon(),
|
|
||||||
Separator::Comma => self.print(b','),
|
|
||||||
Separator::None => {}
|
|
||||||
}
|
|
||||||
if index != len - 1 {
|
|
||||||
self.print_newline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_body(&mut self, stmt: &Statement<'_>) {
|
|
||||||
if let Statement::BlockStatement(block) = stmt {
|
|
||||||
self.print_space();
|
|
||||||
self.print_block1(block);
|
|
||||||
self.print_newline();
|
|
||||||
} else {
|
|
||||||
self.print_newline();
|
|
||||||
self.indent();
|
|
||||||
stmt.gen(self);
|
|
||||||
self.dedent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_block1(&mut self, stmt: &BlockStatement<'_>) {
|
|
||||||
self.print(b'{');
|
|
||||||
self.print_newline();
|
|
||||||
self.indent();
|
|
||||||
for item in &stmt.body {
|
|
||||||
self.print_semicolon_if_needed();
|
|
||||||
item.gen(self);
|
|
||||||
}
|
|
||||||
self.dedent();
|
|
||||||
self.needs_semicolon = false;
|
|
||||||
self.print_indent();
|
|
||||||
self.print(b'}');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_block<T: Gen>(&mut self, items: &[T], separator: Separator) {
|
|
||||||
self.print(b'{');
|
|
||||||
self.indent();
|
|
||||||
if !items.is_empty() {
|
|
||||||
self.print_newline();
|
|
||||||
}
|
|
||||||
self.print_sequence(items, separator);
|
|
||||||
self.dedent();
|
|
||||||
if !items.is_empty() {
|
|
||||||
self.print_newline();
|
|
||||||
}
|
|
||||||
self.print(b'}');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn print_list<T: Gen>(&mut self, items: &[T]) {
|
|
||||||
for (index, item) in items.iter().enumerate() {
|
|
||||||
if index != 0 {
|
|
||||||
self.print_comma();
|
|
||||||
self.print_space();
|
|
||||||
}
|
|
||||||
item.gen(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last_char(&self) -> Option<&u8> {
|
|
||||||
self.code.last()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn auto_detects_lf() {
|
|
||||||
assert_eq!(FinalEndOfLine::LF, EndOfLine::auto_detect_end_of_line("One\nTwo\nThree"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn auto_detects_crlf() {
|
|
||||||
assert_eq!(FinalEndOfLine::CRLF, EndOfLine::auto_detect_end_of_line("One\r\nTwo\r\nThree"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn auto_detects_cr() {
|
|
||||||
assert_eq!(FinalEndOfLine::CR, EndOfLine::auto_detect_end_of_line("One\rTwo\rThree"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -26,7 +26,6 @@ oxc_linter = { workspace = true }
|
||||||
oxc_parser = { workspace = true }
|
oxc_parser = { workspace = true }
|
||||||
oxc_semantic = { workspace = true }
|
oxc_semantic = { workspace = true }
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
oxc_linter_plugin = { workspace = true }
|
|
||||||
dashmap = { workspace = true }
|
dashmap = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ oxc_diagnostics = { workspace = true }
|
||||||
oxc_macros = { workspace = true }
|
oxc_macros = { workspace = true }
|
||||||
oxc_semantic = { workspace = true }
|
oxc_semantic = { workspace = true }
|
||||||
oxc_syntax = { workspace = true }
|
oxc_syntax = { workspace = true }
|
||||||
oxc_formatter = { workspace = true }
|
oxc_codegen = { workspace = true }
|
||||||
oxc_index = { workspace = true }
|
oxc_index = { workspace = true }
|
||||||
oxc_resolver = { version = "1.2.0" }
|
oxc_resolver = { version = "1.2.0" }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{cell::RefCell, path::Path, rc::Rc};
|
use std::{cell::RefCell, path::Path, rc::Rc};
|
||||||
|
|
||||||
|
use oxc_codegen::{Codegen, CodegenOptions};
|
||||||
use oxc_diagnostics::Error;
|
use oxc_diagnostics::Error;
|
||||||
use oxc_formatter::{Formatter, FormatterOptions};
|
|
||||||
use oxc_semantic::{AstNodes, JSDocComment, ScopeTree, Semantic, SymbolTable};
|
use oxc_semantic::{AstNodes, JSDocComment, ScopeTree, Semantic, SymbolTable};
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
|
|
||||||
|
|
@ -119,8 +119,8 @@ impl<'a> LintContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
pub fn formatter(&self) -> Formatter {
|
pub fn codegen(&self) -> Codegen<false> {
|
||||||
Formatter::new(0, FormatterOptions::default())
|
Codegen::<false>::new(0, CodegenOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* JSDoc */
|
/* JSDoc */
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use oxc_diagnostics::{
|
||||||
miette::{self, Diagnostic},
|
miette::{self, Diagnostic},
|
||||||
thiserror::{self, Error},
|
thiserror::{self, Error},
|
||||||
};
|
};
|
||||||
use oxc_formatter::Gen;
|
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
use oxc_span::{GetSpan, Span};
|
use oxc_span::{GetSpan, Span};
|
||||||
use oxc_syntax::operator::{BinaryOperator, UnaryOperator};
|
use oxc_syntax::operator::{BinaryOperator, UnaryOperator};
|
||||||
|
|
@ -83,21 +82,22 @@ impl NoUnsafeNegation {
|
||||||
/// Precondition:
|
/// Precondition:
|
||||||
/// expr.left is `UnaryExpression` whose operator is '!'
|
/// expr.left is `UnaryExpression` whose operator is '!'
|
||||||
fn report_with_fix(expr: &BinaryExpression, ctx: &LintContext<'_>) {
|
fn report_with_fix(expr: &BinaryExpression, ctx: &LintContext<'_>) {
|
||||||
|
use oxc_codegen::{Context, Gen};
|
||||||
// Diagnostic points at the unexpected negation
|
// Diagnostic points at the unexpected negation
|
||||||
let diagnostic = NoUnsafeNegationDiagnostic(expr.operator.as_str(), expr.left.span());
|
let diagnostic = NoUnsafeNegationDiagnostic(expr.operator.as_str(), expr.left.span());
|
||||||
|
|
||||||
let fix_producer = || {
|
let fix_producer = || {
|
||||||
// modify `!a instance of B` to `!(a instanceof B)`
|
// modify `!a instance of B` to `!(a instanceof B)`
|
||||||
let modified_code = {
|
let modified_code = {
|
||||||
let mut formatter = ctx.formatter();
|
let mut codegen = ctx.codegen();
|
||||||
formatter.print(b'!');
|
codegen.print(b'!');
|
||||||
let Expression::UnaryExpression(left) = &expr.left else { unreachable!() };
|
let Expression::UnaryExpression(left) = &expr.left else { unreachable!() };
|
||||||
formatter.print(b'(');
|
codegen.print(b'(');
|
||||||
left.argument.gen(&mut formatter);
|
codegen.print_expression(&left.argument);
|
||||||
expr.operator.gen(&mut formatter);
|
expr.operator.gen(&mut codegen, Context::default());
|
||||||
expr.right.gen(&mut formatter);
|
codegen.print_expression(&expr.right);
|
||||||
formatter.print(b')');
|
codegen.print(b')');
|
||||||
formatter.into_code()
|
codegen.into_code()
|
||||||
};
|
};
|
||||||
Fix::new(modified_code, expr.span)
|
Fix::new(modified_code, expr.span)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ fn get_fix_content<'a>(expr: &'a CallExpression<'a>) -> (&'a str, Span) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_code(expr: &CallExpression, ctx: &LintContext) -> (String, Span) {
|
fn build_code(expr: &CallExpression, ctx: &LintContext) -> (String, Span) {
|
||||||
let mut formatter = ctx.formatter();
|
let mut formatter = ctx.codegen();
|
||||||
|
|
||||||
if let Expression::Identifier(ident) = &expr.callee {
|
if let Expression::Identifier(ident) = &expr.callee {
|
||||||
formatter.print_str(ident.name.as_bytes());
|
formatter.print_str(ident.name.as_bytes());
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@ use oxc_diagnostics::{
|
||||||
miette::{self, Diagnostic},
|
miette::{self, Diagnostic},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
use oxc_formatter::Gen;
|
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
use oxc_span::Span;
|
use oxc_span::{GetSpan, Span};
|
||||||
use oxc_syntax::operator::BinaryOperator;
|
use oxc_syntax::operator::BinaryOperator;
|
||||||
|
|
||||||
use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode};
|
use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode};
|
||||||
|
|
@ -46,11 +45,11 @@ impl Rule for NoInstanceofArray {
|
||||||
Expression::Identifier(identifier) if identifier.name == "Array" => {
|
Expression::Identifier(identifier) if identifier.name == "Array" => {
|
||||||
ctx.diagnostic_with_fix(NoInstanceofArrayDiagnostic(expr.span), || {
|
ctx.diagnostic_with_fix(NoInstanceofArrayDiagnostic(expr.span), || {
|
||||||
let modified_code = {
|
let modified_code = {
|
||||||
let mut formatter = ctx.formatter();
|
let mut codegen = String::new();
|
||||||
formatter.print_str(b"Array.isArray(");
|
codegen.push_str("Array.isArray(");
|
||||||
expr.left.gen(&mut formatter);
|
codegen.push_str(expr.left.span().source_text(ctx.source_text()));
|
||||||
formatter.print(b')');
|
codegen.push(')');
|
||||||
formatter.into_code()
|
codegen
|
||||||
};
|
};
|
||||||
Fix::new(modified_code, expr.span)
|
Fix::new(modified_code, expr.span)
|
||||||
});
|
});
|
||||||
|
|
@ -90,7 +89,7 @@ fn test() {
|
||||||
let fix = vec![
|
let fix = vec![
|
||||||
("arr instanceof Array", "Array.isArray(arr)", None),
|
("arr instanceof Array", "Array.isArray(arr)", None),
|
||||||
("[] instanceof Array", "Array.isArray([])", None),
|
("[] instanceof Array", "Array.isArray([])", None),
|
||||||
("[1,2,3] instanceof Array === true", "Array.isArray([1, 2, 3]) === true", None),
|
("[1,2,3] instanceof Array === true", "Array.isArray([1,2,3]) === true", None),
|
||||||
("fun.call(1, 2, 3) instanceof Array", "Array.isArray(fun.call(1, 2, 3))", None),
|
("fun.call(1, 2, 3) instanceof Array", "Array.isArray(fun.call(1, 2, 3))", None),
|
||||||
("obj.arr instanceof Array", "Array.isArray(obj.arr)", None),
|
("obj.arr instanceof Array", "Array.isArray(obj.arr)", None),
|
||||||
("foo.bar[2] instanceof Array", "Array.isArray(foo.bar[2])", None),
|
("foo.bar[2] instanceof Array", "Array.isArray(foo.bar[2])", None),
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@ use oxc_diagnostics::{
|
||||||
miette::{self, Diagnostic},
|
miette::{self, Diagnostic},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
use oxc_formatter::Gen;
|
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
use oxc_span::Span;
|
use oxc_span::{GetSpan, Span};
|
||||||
|
|
||||||
use crate::{context::LintContext, rule::Rule, AstNode, Fix};
|
use crate::{context::LintContext, rule::Rule, AstNode, Fix};
|
||||||
|
|
||||||
|
|
@ -64,9 +63,9 @@ impl Rule for NoUnnecessaryAwait {
|
||||||
ctx.diagnostic_with_fix(
|
ctx.diagnostic_with_fix(
|
||||||
NoUnnecessaryAwaitDiagnostic(Span::new(expr.span.start, expr.span.start + 5)),
|
NoUnnecessaryAwaitDiagnostic(Span::new(expr.span.start, expr.span.start + 5)),
|
||||||
|| {
|
|| {
|
||||||
let mut formatter = ctx.formatter();
|
let mut codegen = String::new();
|
||||||
expr.argument.gen(&mut formatter);
|
codegen.push_str(expr.argument.span().source_text(ctx.source_text()));
|
||||||
Fix::new(formatter.into_code(), expr.span)
|
Fix::new(codegen, expr.span)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -158,8 +157,8 @@ fn test() {
|
||||||
let fix = vec![
|
let fix = vec![
|
||||||
("await []", "[]", None),
|
("await []", "[]", None),
|
||||||
("await (a == b)", "(a == b)", None),
|
("await (a == b)", "(a == b)", None),
|
||||||
("+await -1", "+ -1", None),
|
("+await -1", "+-1", None),
|
||||||
("-await +1", "- +1", None),
|
("-await +1", "-+1", None),
|
||||||
("await function() {}", "await function() {}", None), // no autofix
|
("await function() {}", "await function() {}", None), // no autofix
|
||||||
("await class {}", "await class {}", None), // no autofix
|
("await class {}", "await class {}", None), // no autofix
|
||||||
("+await +1", "+await +1", None), // no autofix
|
("+await +1", "+await +1", None), // no autofix
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ impl Rule for RequireNumberToFixedDigitsArgument {
|
||||||
RequireNumberToFixedDigitsArgumentDiagnostic(parenthesis_span),
|
RequireNumberToFixedDigitsArgumentDiagnostic(parenthesis_span),
|
||||||
|| {
|
|| {
|
||||||
let modified_code = {
|
let modified_code = {
|
||||||
let mut formatter = ctx.formatter();
|
let mut formatter = ctx.codegen();
|
||||||
|
|
||||||
let mut parenthesis_span_without_right_one = parenthesis_span;
|
let mut parenthesis_span_without_right_one = parenthesis_span;
|
||||||
parenthesis_span_without_right_one.end -= 1;
|
parenthesis_span_without_right_one.end -= 1;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ use oxc_diagnostics::{
|
||||||
miette::{self, Diagnostic},
|
miette::{self, Diagnostic},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
use oxc_formatter::Gen;
|
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
use oxc_span::{GetSpan, Span};
|
use oxc_span::{GetSpan, Span};
|
||||||
|
|
||||||
|
|
@ -76,20 +75,23 @@ impl Rule for SwitchCaseBraces {
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.diagnostic_with_fix(SwitchCaseBracesDiagnostic(case_body_span), || {
|
ctx.diagnostic_with_fix(SwitchCaseBracesDiagnostic(case_body_span), || {
|
||||||
|
use oxc_codegen::{Context, Gen};
|
||||||
let modified_code = {
|
let modified_code = {
|
||||||
let mut formatter = ctx.formatter();
|
let mut formatter = ctx.codegen();
|
||||||
|
|
||||||
if let Some(case_test) = &case.test {
|
if let Some(case_test) = &case.test {
|
||||||
formatter.print_str(b"case ");
|
formatter.print_str(b"case ");
|
||||||
case_test.gen(&mut formatter);
|
formatter.print_expression(case_test);
|
||||||
} else {
|
} else {
|
||||||
formatter.print_str(b"default");
|
formatter.print_str(b"default");
|
||||||
}
|
}
|
||||||
|
|
||||||
formatter.print_colon();
|
formatter.print_colon();
|
||||||
formatter.print_space();
|
formatter.print_hard_space();
|
||||||
formatter.print(b'{');
|
formatter.print(b'{');
|
||||||
case.consequent.iter().for_each(|x| x.gen(&mut formatter));
|
case.consequent
|
||||||
|
.iter()
|
||||||
|
.for_each(|x| x.gen(&mut formatter, Context::default()));
|
||||||
formatter.print(b'}');
|
formatter.print(b'}');
|
||||||
|
|
||||||
formatter.into_code()
|
formatter.into_code()
|
||||||
|
|
@ -140,7 +142,7 @@ fn test() {
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"switch(something) { case 1: {} case 2: console.log('something'); break;}",
|
"switch(something) { case 1: {} case 2: console.log('something'); break;}",
|
||||||
"switch(something) { case 1: case 2: {console.log(\"something\");\nbreak;\n}}",
|
"switch(something) { case 1: case 2: {console.log('something');\nbreak;\n}}",
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ doctest = false
|
||||||
default = ["console_error_panic_hook"]
|
default = ["console_error_panic_hook"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
oxc = { workspace = true, features = ["serde", "semantic", "formatter", "transformer", "minifier", "codegen"] }
|
oxc = { workspace = true, features = ["serde", "semantic", "transformer", "minifier", "codegen"] }
|
||||||
|
|
||||||
oxc_linter = { workspace = true }
|
oxc_linter = { workspace = true }
|
||||||
oxc_prettier = { workspace = true }
|
oxc_prettier = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use oxc::{
|
||||||
allocator::Allocator,
|
allocator::Allocator,
|
||||||
codegen::{Codegen, CodegenOptions},
|
codegen::{Codegen, CodegenOptions},
|
||||||
diagnostics::Error,
|
diagnostics::Error,
|
||||||
formatter::{Formatter, FormatterOptions},
|
|
||||||
minifier::{CompressOptions, Minifier, MinifierOptions},
|
minifier::{CompressOptions, Minifier, MinifierOptions},
|
||||||
parser::{Parser, ParserReturn},
|
parser::{Parser, ParserReturn},
|
||||||
semantic::{ScopeId, Semantic, SemanticBuilder, SemanticBuilderReturn},
|
semantic::{ScopeId, Semantic, SemanticBuilder, SemanticBuilderReturn},
|
||||||
|
|
@ -22,7 +21,7 @@ use trustfall::{execute_query, TransparentValue};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use crate::options::{
|
use crate::options::{
|
||||||
OxcFormatterOptions, OxcLinterOptions, OxcMinifierOptions, OxcParserOptions, OxcRunOptions,
|
OxcCodegenOptions, OxcLinterOptions, OxcMinifierOptions, OxcParserOptions, OxcRunOptions,
|
||||||
OxcTypeCheckingOptions,
|
OxcTypeCheckingOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -182,7 +181,7 @@ impl Oxc {
|
||||||
run_options: &OxcRunOptions,
|
run_options: &OxcRunOptions,
|
||||||
parser_options: &OxcParserOptions,
|
parser_options: &OxcParserOptions,
|
||||||
_linter_options: &OxcLinterOptions,
|
_linter_options: &OxcLinterOptions,
|
||||||
formatter_options: &OxcFormatterOptions,
|
_codegen_options: &OxcCodegenOptions,
|
||||||
minifier_options: &OxcMinifierOptions,
|
minifier_options: &OxcMinifierOptions,
|
||||||
_type_checking_options: &OxcTypeCheckingOptions,
|
_type_checking_options: &OxcTypeCheckingOptions,
|
||||||
) -> Result<(), serde_wasm_bindgen::Error> {
|
) -> Result<(), serde_wasm_bindgen::Error> {
|
||||||
|
|
@ -226,15 +225,6 @@ impl Oxc {
|
||||||
self.save_diagnostics(diagnostics);
|
self.save_diagnostics(diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if run_options.format() {
|
|
||||||
let formatter_options = FormatterOptions {
|
|
||||||
indentation: formatter_options.indentation,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let printed = Formatter::new(source_text.len(), formatter_options).build(program);
|
|
||||||
self.formatted_text = printed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if run_options.prettier_format() {
|
if run_options.prettier_format() {
|
||||||
let ret = Parser::new(&allocator, source_text, source_type)
|
let ret = Parser::new(&allocator, source_text, source_type)
|
||||||
.allow_return_outside_function(parser_options.allow_return_outside_function)
|
.allow_return_outside_function(parser_options.allow_return_outside_function)
|
||||||
|
|
|
||||||
|
|
@ -141,12 +141,12 @@ impl OxcLinterOptions {
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy)]
|
||||||
pub struct OxcFormatterOptions {
|
pub struct OxcCodegenOptions {
|
||||||
pub indentation: u8,
|
pub indentation: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl OxcFormatterOptions {
|
impl OxcCodegenOptions {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import initWasm, {
|
||||||
OxcParserOptions,
|
OxcParserOptions,
|
||||||
OxcLinterOptions,
|
OxcLinterOptions,
|
||||||
OxcMinifierOptions,
|
OxcMinifierOptions,
|
||||||
OxcFormatterOptions,
|
OxcCodegenOptions,
|
||||||
OxcTypeCheckingOptions,
|
OxcTypeCheckingOptions,
|
||||||
graphql_schema_text,
|
graphql_schema_text,
|
||||||
} from "@oxc/wasm-web";
|
} from "@oxc/wasm-web";
|
||||||
|
|
@ -87,7 +87,7 @@ class Playground {
|
||||||
|
|
||||||
runOptions;
|
runOptions;
|
||||||
parserOptions;
|
parserOptions;
|
||||||
formatterOptions;
|
codegenOptions;
|
||||||
linterOptions;
|
linterOptions;
|
||||||
minifierOptions;
|
minifierOptions;
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ class Playground {
|
||||||
this.oxc = new Oxc();
|
this.oxc = new Oxc();
|
||||||
this.runOptions = new OxcRunOptions();
|
this.runOptions = new OxcRunOptions();
|
||||||
this.parserOptions = new OxcParserOptions();
|
this.parserOptions = new OxcParserOptions();
|
||||||
this.formatterOptions = new OxcFormatterOptions();
|
this.codegenOptions = new OxcCodegenOptions();
|
||||||
this.linterOptions = new OxcLinterOptions();
|
this.linterOptions = new OxcLinterOptions();
|
||||||
this.minifierOptions = new OxcMinifierOptions();
|
this.minifierOptions = new OxcMinifierOptions();
|
||||||
this.typeCheckOptions = new OxcTypeCheckingOptions();
|
this.typeCheckOptions = new OxcTypeCheckingOptions();
|
||||||
|
|
@ -466,7 +466,7 @@ class Playground {
|
||||||
this.runOptions,
|
this.runOptions,
|
||||||
this.parserOptions,
|
this.parserOptions,
|
||||||
this.linterOptions,
|
this.linterOptions,
|
||||||
this.formatterOptions,
|
this.codegenOptions,
|
||||||
this.minifierOptions,
|
this.minifierOptions,
|
||||||
this.typeCheckOptions
|
this.typeCheckOptions
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue