diff --git a/crates/swc/tests/errors/lints/no-debugger/.swcrc b/crates/swc/tests/errors/lints/no-debugger/.swcrc new file mode 100644 index 00000000000..3cd93f8aec8 --- /dev/null +++ b/crates/swc/tests/errors/lints/no-debugger/.swcrc @@ -0,0 +1,7 @@ +{ + "jsc": { + "lints": { + "noDebugger": ["error"] + } + } +} \ No newline at end of file diff --git a/crates/swc/tests/errors/lints/no-debugger/1/input.js b/crates/swc/tests/errors/lints/no-debugger/1/input.js new file mode 100644 index 00000000000..f916ba64c11 --- /dev/null +++ b/crates/swc/tests/errors/lints/no-debugger/1/input.js @@ -0,0 +1,5 @@ +function f() { + debugger; +} + +debugger; diff --git a/crates/swc/tests/errors/lints/no-debugger/1/output.swc-stderr b/crates/swc/tests/errors/lints/no-debugger/1/output.swc-stderr new file mode 100644 index 00000000000..182d336badb --- /dev/null +++ b/crates/swc/tests/errors/lints/no-debugger/1/output.swc-stderr @@ -0,0 +1,12 @@ +error: Unexpected 'debugger' statement + + | +2 | debugger; + | ^^^^^^^^^ + +error: Unexpected 'debugger' statement + + | +5 | debugger; + | ^^^^^^^^^ + diff --git a/crates/swc_ecma_lints/src/config.rs b/crates/swc_ecma_lints/src/config.rs index d1e9cdf42a2..081f3dfbaf4 100644 --- a/crates/swc_ecma_lints/src/config.rs +++ b/crates/swc_ecma_lints/src/config.rs @@ -2,7 +2,7 @@ use crate::rules::no_console::NoConsoleConfig; use serde::{Deserialize, Serialize}; use std::fmt::Debug; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum LintRuleReaction { Off, @@ -38,4 +38,7 @@ impl RuleConfig { pub struct LintConfig { #[serde(default)] pub no_console: RuleConfig, + + #[serde(default)] + pub no_debugger: RuleConfig<()>, } diff --git a/crates/swc_ecma_lints/src/rules/mod.rs b/crates/swc_ecma_lints/src/rules/mod.rs index 93146e4c7d9..99fd8ad20c9 100644 --- a/crates/swc_ecma_lints/src/rules/mod.rs +++ b/crates/swc_ecma_lints/src/rules/mod.rs @@ -7,6 +7,7 @@ mod const_assign; mod duplicate_bindings; mod duplicate_exports; pub mod no_console; +mod no_debugger; pub fn all(lint_config: &LintConfig, top_level_ctxt: SyntaxContext) -> Vec> { let mut rules = vec![ @@ -20,6 +21,8 @@ pub fn all(lint_config: &LintConfig, top_level_ctxt: SyntaxContext) -> Vec) -> Option> { + let rule_reaction = config.get_rule_reaction(); + + match rule_reaction { + LintRuleReaction::Off => None, + _ => Some(visitor_rule(NoDebugger::new(*rule_reaction))), + } +} + +#[derive(Debug, Default)] +struct NoDebugger { + expected_reaction: LintRuleReaction, +} + +impl NoDebugger { + fn new(expected_reaction: LintRuleReaction) -> Self { + Self { expected_reaction } + } + + fn check(&self, span: Span) { + HANDLER.with(|handler| match self.expected_reaction { + LintRuleReaction::Error => { + handler.struct_span_err(span, MESSAGE).emit(); + } + LintRuleReaction::Warning => { + handler.struct_span_warn(span, MESSAGE).emit(); + } + _ => {} + }); + } +} + +impl Visit for NoDebugger { + noop_visit_type!(); + + fn visit_debugger_stmt(&mut self, debugger_stmt: &DebuggerStmt) { + self.check(debugger_stmt.span); + } +}