mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
parent
6d50ee01e4
commit
849489e8b4
2 changed files with 126 additions and 46 deletions
|
|
@ -1,12 +1,19 @@
|
||||||
use oxc_ast::{ast::Expression, AstKind};
|
use oxc_ast::{ast::Expression, AstKind};
|
||||||
use oxc_diagnostics::OxcDiagnostic;
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
use oxc_span::{CompactStr, Span};
|
use oxc_span::{CompactStr, GetSpan, Span};
|
||||||
|
|
||||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
use crate::{
|
||||||
|
context::LintContext,
|
||||||
|
fixer::{RuleFix, RuleFixer},
|
||||||
|
rule::Rule,
|
||||||
|
AstNode,
|
||||||
|
};
|
||||||
|
|
||||||
fn no_console_diagnostic(span: Span) -> OxcDiagnostic {
|
fn no_console_diagnostic(span: Span) -> OxcDiagnostic {
|
||||||
OxcDiagnostic::warn("Unexpected console statement.").with_label(span)
|
OxcDiagnostic::warn("eslint(no-console): Unexpected console statement.")
|
||||||
|
.with_label(span)
|
||||||
|
.with_help("Delete this console statement.")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
|
|
@ -47,7 +54,8 @@ declare_oxc_lint!(
|
||||||
/// console.log('here');
|
/// console.log('here');
|
||||||
/// ```
|
/// ```
|
||||||
NoConsole,
|
NoConsole,
|
||||||
restriction
|
restriction,
|
||||||
|
suggestion
|
||||||
);
|
);
|
||||||
|
|
||||||
impl Rule for NoConsole {
|
impl Rule for NoConsole {
|
||||||
|
|
@ -79,13 +87,57 @@ impl Rule for NoConsole {
|
||||||
&& ident.name == "console"
|
&& ident.name == "console"
|
||||||
&& !self.allow.iter().any(|s| mem.static_property_name().is_some_and(|f| f == s))
|
&& !self.allow.iter().any(|s| mem.static_property_name().is_some_and(|f| f == s))
|
||||||
{
|
{
|
||||||
if let Some(mem) = mem.static_property_info() {
|
if let Some((mem_span, _)) = mem.static_property_info() {
|
||||||
ctx.diagnostic(no_console_diagnostic(mem.0));
|
let diagnostic_span = ident.span().merge(&mem_span);
|
||||||
|
ctx.diagnostic_with_suggestion(no_console_diagnostic(diagnostic_span), |fixer| {
|
||||||
|
remove_console(fixer, ctx, node)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_console<'c, 'a: 'c>(
|
||||||
|
fixer: RuleFixer<'c, 'a>,
|
||||||
|
ctx: &'c LintContext<'a>,
|
||||||
|
node: &AstNode<'a>,
|
||||||
|
) -> RuleFix<'a> {
|
||||||
|
let mut node_to_delete = node;
|
||||||
|
for parent in ctx.nodes().ancestors(node.id()).skip(1) {
|
||||||
|
match parent.kind() {
|
||||||
|
AstKind::ParenthesizedExpression(_)
|
||||||
|
| AstKind::ExpressionStatement(_)
|
||||||
|
=> node_to_delete = parent,
|
||||||
|
AstKind::IfStatement(_)
|
||||||
|
| AstKind::WhileStatement(_)
|
||||||
|
| AstKind::ForStatement(_)
|
||||||
|
| AstKind::ForInStatement(_)
|
||||||
|
| AstKind::ForOfStatement(_)
|
||||||
|
| AstKind::ArrowFunctionExpression(_) => {
|
||||||
|
return fixer.replace(node_to_delete.span(), "{}")
|
||||||
|
}
|
||||||
|
// Arrow function AST nodes do not say whether they have brackets or
|
||||||
|
// not, so we need to check manually.
|
||||||
|
// e.g: const x = () => { console.log(foo) }
|
||||||
|
// vs: const x = () => console.log(foo)
|
||||||
|
| AstKind::FunctionBody(body) if !fixer.source_range(body.span).starts_with('{') => {
|
||||||
|
return fixer.replace(node_to_delete.span(), "{}")
|
||||||
|
}
|
||||||
|
// Marked as dangerous until we're sure this is safe
|
||||||
|
AstKind::ConditionalExpression(_)
|
||||||
|
// from: const x = (console.log("foo"), 5);
|
||||||
|
// to: const x = (undefined, 5);
|
||||||
|
| AstKind::SequenceExpression(_)
|
||||||
|
| AstKind::ObjectProperty(_)
|
||||||
|
=> {
|
||||||
|
return fixer.replace(node_to_delete.span(), "undefined").dangerously()
|
||||||
|
}
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixer.delete(node_to_delete)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
use crate::tester::Tester;
|
use crate::tester::Tester;
|
||||||
|
|
@ -120,5 +172,20 @@ fn test() {
|
||||||
("console.warn(foo)", Some(serde_json::json!([{ "allow": ["info", "log"] }]))),
|
("console.warn(foo)", Some(serde_json::json!([{ "allow": ["info", "log"] }]))),
|
||||||
];
|
];
|
||||||
|
|
||||||
Tester::new(NoConsole::NAME, pass, fail).test_and_snapshot();
|
let fix = vec![
|
||||||
|
("function foo() { console.log(bar); }", "function foo() { }", None),
|
||||||
|
("function foo() { console.log(bar) }", "function foo() { }", None),
|
||||||
|
("const x = () => console.log(foo)", "const x = () => {}", None),
|
||||||
|
("const x = () => { console.log(foo) }", "const x = () => { }", None),
|
||||||
|
("const x = () => { console.log(foo); }", "const x = () => { }", None),
|
||||||
|
("const x = () => { ((console.log(foo))); }", "const x = () => { }", None),
|
||||||
|
("const x = () => { console.log(foo); return 5 }", "const x = () => { return 5 }", None),
|
||||||
|
("if (foo) { console.log(foo) }", "if (foo) { }", None),
|
||||||
|
("foo ? console.log(foo) : 5", "foo ? undefined : 5", None),
|
||||||
|
("(console.log(foo), 5)", "(undefined, 5)", None),
|
||||||
|
("(5, console.log(foo))", "(5, undefined)", None),
|
||||||
|
("const x = { foo: console.log(bar) }", "const x = { foo: undefined }", None),
|
||||||
|
];
|
||||||
|
|
||||||
|
Tester::new(NoConsole::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,80 +2,93 @@
|
||||||
source: crates/oxc_linter/src/tester.rs
|
source: crates/oxc_linter/src/tester.rs
|
||||||
snapshot_kind: text
|
snapshot_kind: text
|
||||||
---
|
---
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.log()
|
1 │ console.log()
|
||||||
· ───
|
· ───────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.log(foo)
|
1 │ console.log(foo)
|
||||||
· ───
|
· ───────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.error(foo)
|
1 │ console.error(foo)
|
||||||
· ─────
|
· ─────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.info(foo)
|
1 │ console.info(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.warn(foo)
|
1 │ console.warn(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.log(foo)
|
1 │ console.log(foo)
|
||||||
· ───
|
· ───────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.error(foo)
|
1 │ console.error(foo)
|
||||||
· ─────
|
· ─────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.info(foo)
|
1 │ console.info(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.warn(foo)
|
1 │ console.warn(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.log(foo)
|
1 │ console.log(foo)
|
||||||
· ───
|
· ───────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.error(foo)
|
1 │ console.error(foo)
|
||||||
· ─────
|
· ─────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.info(foo)
|
1 │ console.info(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
||||||
⚠ eslint(no-console): Unexpected console statement.
|
⚠ eslint(no-console): eslint(no-console): Unexpected console statement.
|
||||||
╭─[no_console.tsx:1:9]
|
╭─[no_console.tsx:1:1]
|
||||||
1 │ console.warn(foo)
|
1 │ console.warn(foo)
|
||||||
· ────
|
· ────────────
|
||||||
╰────
|
╰────
|
||||||
|
help: Delete this console statement.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue