diff --git a/.gitattributes b/.gitattributes index 32bfa4031c3..0f898754a56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,6 +13,7 @@ npm/backend-jsonrpc/src/workspace.ts linguist-generated=true text=auto eol=lf website/src/docs/lint/rules/**/*.md linguist-generated=true text=auto eol=lf npm/rome/configuration_schema.json linguist-generated=true text=auto eol=lf editors/vscode/configuration_schema.json linguist-generated=true text=auto eol=lf +crates/rome_service/src/configuration/parse/json/rules.rs linguist-generated=true text=auto eol=lf crates/rome_js_formatter/tests/**/*.ts.prettier-snap linguist-language=TypeScript diff --git a/CHANGELOG.md b/CHANGELOG.md index 4374664d00f..de6a1174bd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ the code action is not formatted. - [`noRedundantRoles`](https://docs.rome.tools/lint/rules/noRedundantRoles/) - [`noNoninteractiveTabindex`](https://docs.rome.tools/lint/rules/noNoninteractiveTabindex/) - [`noAriaUnsupportedElements`](https://docs.rome.tools/lint/rules/noAriaUnsupportedElements/) +- [`noConsoleLog`](https://docs.rome.tools/lint/rules/noConsoleLog/) ### Parser diff --git a/crates/rome_diagnostics_categories/src/categories.rs b/crates/rome_diagnostics_categories/src/categories.rs index f03edead356..ca4cd29489a 100644 --- a/crates/rome_diagnostics_categories/src/categories.rs +++ b/crates/rome_diagnostics_categories/src/categories.rs @@ -97,11 +97,12 @@ define_categories! { "lint/nursery/noPrototypeBuiltins": "https://docs.rome.tools/lint/rules/noPrototypeBuiltins", "lint/nursery/noSvgWithoutTitle": "https://docs.rome.tools/lint/rules/noSvgWithoutTitle", "lint/nursery/noUselessCatch": "https://docs.rome.tools/lint/rules/noUselessCatch", -"lint/nursery/noParameterAssign": "https://docs.rome.tools/lint/rules/noParameterAssign", -"lint/nursery/noNamespace": "https://docs.rome.tools/lint/rules/noNamespace", -"lint/nursery/noConfusingArrow": "https://docs.rome.tools/lint/rules/noConfusingArrow", -"lint/nursery/noNoninteractiveTabindex": "https://docs.rome.tools/lint/rules/noNoninteractiveTabindex", -"lint/nursery/noAriaUnsupportedElements": "https://docs.rome.tools/lint/rules/noAriaUnsupportedElements", + "lint/nursery/noParameterAssign": "https://docs.rome.tools/lint/rules/noParameterAssign", + "lint/nursery/noNamespace": "https://docs.rome.tools/lint/rules/noNamespace", + "lint/nursery/noConfusingArrow": "https://docs.rome.tools/lint/rules/noConfusingArrow", + "lint/nursery/noNoninteractiveTabindex": "https://docs.rome.tools/lint/rules/noNoninteractiveTabindex", + "lint/nursery/noAriaUnsupportedElements": "https://docs.rome.tools/lint/rules/noAriaUnsupportedElements", + "lint/nursery/noConsoleLog": "https://docs.rome.tools/lint/rules/noConsoleLog", // Insert new nursery rule here "lint/nursery/noRedeclare": "https://docs.rome.tools/lint/rules/noRedeclare", "lint/nursery/useNamespaceKeyword": "https://docs.rome.tools/lint/rules/useNamespaceKeyword", diff --git a/crates/rome_js_analyze/src/analyzers/nursery/no_confusing_arrow.rs b/crates/rome_js_analyze/src/analyzers/nursery/no_confusing_arrow.rs index 4a258736340..2547d1dc7d0 100644 --- a/crates/rome_js_analyze/src/analyzers/nursery/no_confusing_arrow.rs +++ b/crates/rome_js_analyze/src/analyzers/nursery/no_confusing_arrow.rs @@ -16,6 +16,8 @@ declare_rule! { /// /// ```js,expect_diagnostic /// var x = a => 1 ? 2 : 3; + /// ``` + /// ```js,expect_diagnostic /// var x = (a) => 1 ? 2 : 3; /// ``` /// @@ -69,28 +71,4 @@ impl Rule for NoConfusingArrow { }, )) } - - // Formatter is not happy with the added parenthesis at the time of commit. - // This should be fixed before enabling the action. - //fn action(ctx: &RuleContext, _state: &Self::State) -> Option { - // let body_expr = ctx.query().body().ok()?.as_any_js_expression()?.clone(); - // - // let mut mutation = ctx.root().begin(); - // - // mutation.replace_node( - // body_expr.clone(), - // AnyJsExpression::from(make::js_parenthesized_expression( - // JsSyntaxToken::new_detached(JsSyntaxKind::L_PAREN, "(", [], []), - // body_expr, - // JsSyntaxToken::new_detached(JsSyntaxKind::R_PAREN, ")", [], []), - // )), - // ); - // - // Some(JsRuleAction { - // category: ActionCategory::QuickFix, - // applicability: Applicability::Always, - // message: markup! { "Wrap the function body in parenthesis." }.to_owned(), - // mutation, - // }) - //} } diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs index c6d094905d2..f50930b7bc9 100644 --- a/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery.rs @@ -2,6 +2,7 @@ use rome_analyze::declare_group; mod no_class_assign; +mod no_console_log; mod no_parameter_assign; mod no_redeclare; mod no_restricted_globals; @@ -9,4 +10,4 @@ mod use_camel_case; mod use_exhaustive_dependencies; mod use_hook_at_top_level; mod use_iframe_title; -declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_class_assign :: NoClassAssign , self :: no_parameter_assign :: NoParameterAssign , self :: no_redeclare :: NoRedeclare , self :: no_restricted_globals :: NoRestrictedGlobals , self :: use_camel_case :: UseCamelCase , self :: use_exhaustive_dependencies :: UseExhaustiveDependencies , self :: use_hook_at_top_level :: UseHookAtTopLevel , self :: use_iframe_title :: UseIframeTitle ,] } } +declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_class_assign :: NoClassAssign , self :: no_console_log :: NoConsoleLog , self :: no_parameter_assign :: NoParameterAssign , self :: no_redeclare :: NoRedeclare , self :: no_restricted_globals :: NoRestrictedGlobals , self :: use_camel_case :: UseCamelCase , self :: use_exhaustive_dependencies :: UseExhaustiveDependencies , self :: use_hook_at_top_level :: UseHookAtTopLevel , self :: use_iframe_title :: UseIframeTitle ,] } } diff --git a/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_console_log.rs b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_console_log.rs new file mode 100644 index 00000000000..85384accf89 --- /dev/null +++ b/crates/rome_js_analyze/src/semantic_analyzers/nursery/no_console_log.rs @@ -0,0 +1,81 @@ +use crate::semantic_services::Semantic; +use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic}; +use rome_console::markup; +use rome_js_syntax::JsCallExpression; +use rome_rowan::AstNode; + +declare_rule! { + /// Disallow the use of `console.log` + /// + /// ## Examples + /// + /// ### Invalid + /// + /// ```js,expect_diagnostic + /// console.log() + /// ``` + /// + /// ## Valid + /// + /// ```js + /// console.info("info"); + /// console.warn("warn"); + /// console.error("error"); + /// console.assert(true); + /// console.table(["foo", "bar"]); + /// const console = { log() {} }; + /// console.log(); + /// ``` + /// + pub(crate) NoConsoleLog { + version: "next", + name: "noConsoleLog", + recommended: false, + } +} + +impl Rule for NoConsoleLog { + type Query = Semantic; + type State = (); + type Signals = Option; + type Options = (); + + fn run(ctx: &RuleContext) -> Self::Signals { + let call_expression = ctx.query(); + let model = ctx.model(); + let callee = call_expression.callee().ok()?; + let callee = callee.as_js_static_member_expression()?; + + let member = callee.member().ok()?; + let object = callee.object().ok()?; + let object = object.as_js_identifier_expression()?; + + if member.as_js_name()?.value_token().ok()?.text_trimmed() == "log" + && object.name().ok()?.value_token().ok()?.text_trimmed() == "console" + { + let binding = object.name().ok()?; + let reference_binding = model.binding(&binding); + if reference_binding.is_none() { + return Some(()); + } + } + + None + } + + fn diagnostic(ctx: &RuleContext, _: &Self::State) -> Option { + let node = ctx.query(); + Some( + RuleDiagnostic::new( + rule_category!(), + node.syntax().text_trimmed_range(), + markup! { + "Don't use ""console.log" + }, + ) + .note(markup! { + "console.log"" is usually a tool for debugging and you don't want to have that in production." + }), + ) + } +} diff --git a/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js new file mode 100644 index 00000000000..fe0a52cb898 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js @@ -0,0 +1 @@ +console.log("something") diff --git a/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js.snap new file mode 100644 index 00000000000..668b5214e7c --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/invalid.js.snap @@ -0,0 +1,26 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: invalid.js +--- +# Input +```js +console.log("something") + +``` + +# Diagnostics +``` +invalid.js:1:1 lint/nursery/noConsoleLog ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Don't use console.log + + > 1 │ console.log("something") + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 2 │ + + i console.log is usually a tool for debugging and you don't want to have that in production. + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js new file mode 100644 index 00000000000..2397c4d9512 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js @@ -0,0 +1,8 @@ +const console = { + log() {} +}; +console.log(); +console.info("info"); +console.warn("warn"); +console.error("error"); +console.assert(true); diff --git a/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js.snap new file mode 100644 index 00000000000..185f1ca9d3f --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noConsoleLog/valid.js.snap @@ -0,0 +1,18 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: valid.js +--- +# Input +```js +const console = { + log() {} +}; +console.log(); +console.info("info"); +console.warn("warn"); +console.error("error"); +console.assert(true); + +``` + + diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index a80df146458..ed4a0070533 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -1208,6 +1208,9 @@ pub struct Nursery { #[doc = "Disallow labeled statements that are not loops."] #[serde(skip_serializing_if = "Option::is_none")] pub no_confusing_labels: Option, + #[doc = "Disallow the use of console.log"] + #[serde(skip_serializing_if = "Option::is_none")] + pub no_console_log: Option, #[doc = "Disallow duplicate case labels. If a switch statement has duplicate test expressions in case clauses, it is likely that a programmer copied a case clause but forgot to change the test expression."] #[serde(skip_serializing_if = "Option::is_none")] pub no_duplicate_case: Option, @@ -1337,7 +1340,7 @@ pub struct Nursery { } impl Nursery { const GROUP_NAME: &'static str = "nursery"; - pub(crate) const GROUP_RULES: [&'static str; 49] = [ + pub(crate) const GROUP_RULES: [&'static str; 50] = [ "noAriaUnsupportedElements", "noAssignInExpressions", "noBannedTypes", @@ -1345,6 +1348,7 @@ impl Nursery { "noCommaOperator", "noConfusingArrow", "noConfusingLabels", + "noConsoleLog", "noDuplicateCase", "noDuplicateClassMembers", "noDuplicateJsxProps", @@ -1437,7 +1441,6 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[3]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[4]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[6]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[7]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[8]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[9]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[10]), @@ -1448,11 +1451,11 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[15]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[16]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[17]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[19]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[22]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[18]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[20]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[23]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[24]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[26]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29]), @@ -1463,16 +1466,17 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[34]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[35]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[40]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[39]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[41]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]), - RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[47]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[48]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[49]), ]; - const ALL_RULES_AS_FILTERS: [RuleFilter<'static>; 49] = [ + const ALL_RULES_AS_FILTERS: [RuleFilter<'static>; 50] = [ RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[0]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[1]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[2]), @@ -1522,6 +1526,7 @@ impl Nursery { RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[47]), RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[48]), + RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[49]), ]; pub(crate) fn is_recommended(&self) -> bool { !matches!(self.recommended, Some(false)) } pub(crate) const fn is_not_recommended(&self) -> bool { @@ -1566,216 +1571,221 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[6])); } } - if let Some(rule) = self.no_duplicate_case.as_ref() { + if let Some(rule) = self.no_console_log.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[7])); } } - if let Some(rule) = self.no_duplicate_class_members.as_ref() { + if let Some(rule) = self.no_duplicate_case.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[8])); } } - if let Some(rule) = self.no_duplicate_jsx_props.as_ref() { + if let Some(rule) = self.no_duplicate_class_members.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[9])); } } - if let Some(rule) = self.no_extra_labels.as_ref() { + if let Some(rule) = self.no_duplicate_jsx_props.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[10])); } } - if let Some(rule) = self.no_extra_semicolons.as_ref() { + if let Some(rule) = self.no_extra_labels.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[11])); } } - if let Some(rule) = self.no_global_object_calls.as_ref() { + if let Some(rule) = self.no_extra_semicolons.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[12])); } } - if let Some(rule) = self.no_inferrable_types.as_ref() { + if let Some(rule) = self.no_global_object_calls.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[13])); } } - if let Some(rule) = self.no_inner_declarations.as_ref() { + if let Some(rule) = self.no_inferrable_types.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[14])); } } - if let Some(rule) = self.no_invalid_constructor_super.as_ref() { + if let Some(rule) = self.no_inner_declarations.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[15])); } } - if let Some(rule) = self.no_namespace.as_ref() { + if let Some(rule) = self.no_invalid_constructor_super.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[16])); } } - if let Some(rule) = self.no_noninteractive_element_to_interactive_role.as_ref() { + if let Some(rule) = self.no_namespace.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[17])); } } - if let Some(rule) = self.no_noninteractive_tabindex.as_ref() { + if let Some(rule) = self.no_noninteractive_element_to_interactive_role.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[18])); } } - if let Some(rule) = self.no_parameter_assign.as_ref() { + if let Some(rule) = self.no_noninteractive_tabindex.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[19])); } } - if let Some(rule) = self.no_parameter_properties.as_ref() { + if let Some(rule) = self.no_parameter_assign.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[20])); } } - if let Some(rule) = self.no_prototype_builtins.as_ref() { + if let Some(rule) = self.no_parameter_properties.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[21])); } } - if let Some(rule) = self.no_redeclare.as_ref() { + if let Some(rule) = self.no_prototype_builtins.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[22])); } } - if let Some(rule) = self.no_redundant_alt.as_ref() { + if let Some(rule) = self.no_redeclare.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[23])); } } - if let Some(rule) = self.no_redundant_roles.as_ref() { + if let Some(rule) = self.no_redundant_alt.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[24])); } } - if let Some(rule) = self.no_restricted_globals.as_ref() { + if let Some(rule) = self.no_redundant_roles.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25])); } } - if let Some(rule) = self.no_self_assign.as_ref() { + if let Some(rule) = self.no_restricted_globals.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[26])); } } - if let Some(rule) = self.no_self_compare.as_ref() { + if let Some(rule) = self.no_self_assign.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27])); } } - if let Some(rule) = self.no_svg_without_title.as_ref() { + if let Some(rule) = self.no_self_compare.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28])); } } - if let Some(rule) = self.no_switch_declarations.as_ref() { + if let Some(rule) = self.no_svg_without_title.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29])); } } - if let Some(rule) = self.no_unreachable_super.as_ref() { + if let Some(rule) = self.no_switch_declarations.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[30])); } } - if let Some(rule) = self.no_unsafe_optional_chaining.as_ref() { + if let Some(rule) = self.no_unreachable_super.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[31])); } } - if let Some(rule) = self.no_unused_labels.as_ref() { + if let Some(rule) = self.no_unsafe_optional_chaining.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[32])); } } - if let Some(rule) = self.no_useless_catch.as_ref() { + if let Some(rule) = self.no_unused_labels.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[33])); } } - if let Some(rule) = self.no_useless_rename.as_ref() { + if let Some(rule) = self.no_useless_catch.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[34])); } } - if let Some(rule) = self.no_useless_switch_case.as_ref() { + if let Some(rule) = self.no_useless_rename.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[35])); } } - if let Some(rule) = self.no_with.as_ref() { + if let Some(rule) = self.no_useless_switch_case.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36])); } } - if let Some(rule) = self.use_aria_prop_types.as_ref() { + if let Some(rule) = self.no_with.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37])); } } - if let Some(rule) = self.use_aria_props_for_role.as_ref() { + if let Some(rule) = self.use_aria_prop_types.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38])); } } - if let Some(rule) = self.use_camel_case.as_ref() { + if let Some(rule) = self.use_aria_props_for_role.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[39])); } } - if let Some(rule) = self.use_exhaustive_dependencies.as_ref() { + if let Some(rule) = self.use_camel_case.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[40])); } } - if let Some(rule) = self.use_hook_at_top_level.as_ref() { + if let Some(rule) = self.use_exhaustive_dependencies.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[41])); } } - if let Some(rule) = self.use_iframe_title.as_ref() { + if let Some(rule) = self.use_hook_at_top_level.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42])); } } - if let Some(rule) = self.use_is_nan.as_ref() { + if let Some(rule) = self.use_iframe_title.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43])); } } - if let Some(rule) = self.use_media_caption.as_ref() { + if let Some(rule) = self.use_is_nan.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } - if let Some(rule) = self.use_namespace_keyword.as_ref() { + if let Some(rule) = self.use_media_caption.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); } } - if let Some(rule) = self.use_valid_aria_props.as_ref() { + if let Some(rule) = self.use_namespace_keyword.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); } } - if let Some(rule) = self.use_valid_lang.as_ref() { + if let Some(rule) = self.use_valid_aria_props.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[47])); } } - if let Some(rule) = self.use_yield.as_ref() { + if let Some(rule) = self.use_valid_lang.as_ref() { if rule.is_enabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[48])); } } + if let Some(rule) = self.use_yield.as_ref() { + if rule.is_enabled() { + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[49])); + } + } index_set } pub(crate) fn get_disabled_rules(&self) -> IndexSet { @@ -1815,216 +1825,221 @@ impl Nursery { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[6])); } } - if let Some(rule) = self.no_duplicate_case.as_ref() { + if let Some(rule) = self.no_console_log.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[7])); } } - if let Some(rule) = self.no_duplicate_class_members.as_ref() { + if let Some(rule) = self.no_duplicate_case.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[8])); } } - if let Some(rule) = self.no_duplicate_jsx_props.as_ref() { + if let Some(rule) = self.no_duplicate_class_members.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[9])); } } - if let Some(rule) = self.no_extra_labels.as_ref() { + if let Some(rule) = self.no_duplicate_jsx_props.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[10])); } } - if let Some(rule) = self.no_extra_semicolons.as_ref() { + if let Some(rule) = self.no_extra_labels.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[11])); } } - if let Some(rule) = self.no_global_object_calls.as_ref() { + if let Some(rule) = self.no_extra_semicolons.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[12])); } } - if let Some(rule) = self.no_inferrable_types.as_ref() { + if let Some(rule) = self.no_global_object_calls.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[13])); } } - if let Some(rule) = self.no_inner_declarations.as_ref() { + if let Some(rule) = self.no_inferrable_types.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[14])); } } - if let Some(rule) = self.no_invalid_constructor_super.as_ref() { + if let Some(rule) = self.no_inner_declarations.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[15])); } } - if let Some(rule) = self.no_namespace.as_ref() { + if let Some(rule) = self.no_invalid_constructor_super.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[16])); } } - if let Some(rule) = self.no_noninteractive_element_to_interactive_role.as_ref() { + if let Some(rule) = self.no_namespace.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[17])); } } - if let Some(rule) = self.no_noninteractive_tabindex.as_ref() { + if let Some(rule) = self.no_noninteractive_element_to_interactive_role.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[18])); } } - if let Some(rule) = self.no_parameter_assign.as_ref() { + if let Some(rule) = self.no_noninteractive_tabindex.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[19])); } } - if let Some(rule) = self.no_parameter_properties.as_ref() { + if let Some(rule) = self.no_parameter_assign.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[20])); } } - if let Some(rule) = self.no_prototype_builtins.as_ref() { + if let Some(rule) = self.no_parameter_properties.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[21])); } } - if let Some(rule) = self.no_redeclare.as_ref() { + if let Some(rule) = self.no_prototype_builtins.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[22])); } } - if let Some(rule) = self.no_redundant_alt.as_ref() { + if let Some(rule) = self.no_redeclare.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[23])); } } - if let Some(rule) = self.no_redundant_roles.as_ref() { + if let Some(rule) = self.no_redundant_alt.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[24])); } } - if let Some(rule) = self.no_restricted_globals.as_ref() { + if let Some(rule) = self.no_redundant_roles.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25])); } } - if let Some(rule) = self.no_self_assign.as_ref() { + if let Some(rule) = self.no_restricted_globals.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[26])); } } - if let Some(rule) = self.no_self_compare.as_ref() { + if let Some(rule) = self.no_self_assign.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27])); } } - if let Some(rule) = self.no_svg_without_title.as_ref() { + if let Some(rule) = self.no_self_compare.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28])); } } - if let Some(rule) = self.no_switch_declarations.as_ref() { + if let Some(rule) = self.no_svg_without_title.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29])); } } - if let Some(rule) = self.no_unreachable_super.as_ref() { + if let Some(rule) = self.no_switch_declarations.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[30])); } } - if let Some(rule) = self.no_unsafe_optional_chaining.as_ref() { + if let Some(rule) = self.no_unreachable_super.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[31])); } } - if let Some(rule) = self.no_unused_labels.as_ref() { + if let Some(rule) = self.no_unsafe_optional_chaining.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[32])); } } - if let Some(rule) = self.no_useless_catch.as_ref() { + if let Some(rule) = self.no_unused_labels.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[33])); } } - if let Some(rule) = self.no_useless_rename.as_ref() { + if let Some(rule) = self.no_useless_catch.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[34])); } } - if let Some(rule) = self.no_useless_switch_case.as_ref() { + if let Some(rule) = self.no_useless_rename.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[35])); } } - if let Some(rule) = self.no_with.as_ref() { + if let Some(rule) = self.no_useless_switch_case.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36])); } } - if let Some(rule) = self.use_aria_prop_types.as_ref() { + if let Some(rule) = self.no_with.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37])); } } - if let Some(rule) = self.use_aria_props_for_role.as_ref() { + if let Some(rule) = self.use_aria_prop_types.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38])); } } - if let Some(rule) = self.use_camel_case.as_ref() { + if let Some(rule) = self.use_aria_props_for_role.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[39])); } } - if let Some(rule) = self.use_exhaustive_dependencies.as_ref() { + if let Some(rule) = self.use_camel_case.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[40])); } } - if let Some(rule) = self.use_hook_at_top_level.as_ref() { + if let Some(rule) = self.use_exhaustive_dependencies.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[41])); } } - if let Some(rule) = self.use_iframe_title.as_ref() { + if let Some(rule) = self.use_hook_at_top_level.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42])); } } - if let Some(rule) = self.use_is_nan.as_ref() { + if let Some(rule) = self.use_iframe_title.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43])); } } - if let Some(rule) = self.use_media_caption.as_ref() { + if let Some(rule) = self.use_is_nan.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44])); } } - if let Some(rule) = self.use_namespace_keyword.as_ref() { + if let Some(rule) = self.use_media_caption.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45])); } } - if let Some(rule) = self.use_valid_aria_props.as_ref() { + if let Some(rule) = self.use_namespace_keyword.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[46])); } } - if let Some(rule) = self.use_valid_lang.as_ref() { + if let Some(rule) = self.use_valid_aria_props.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[47])); } } - if let Some(rule) = self.use_yield.as_ref() { + if let Some(rule) = self.use_valid_lang.as_ref() { if rule.is_disabled() { index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[48])); } } + if let Some(rule) = self.use_yield.as_ref() { + if rule.is_disabled() { + index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[49])); + } + } index_set } #[doc = r" Checks if, given a rule name, matches one of the rules contained in this category"] @@ -2036,7 +2051,7 @@ impl Nursery { pub(crate) fn recommended_rules_as_filters() -> [RuleFilter<'static>; 40] { Self::RECOMMENDED_RULES_AS_FILTERS } - pub(crate) fn all_rules_as_filters() -> [RuleFilter<'static>; 49] { Self::ALL_RULES_AS_FILTERS } + pub(crate) fn all_rules_as_filters() -> [RuleFilter<'static>; 50] { Self::ALL_RULES_AS_FILTERS } #[doc = r" Select preset rules"] pub(crate) fn collect_preset_rules( &self, @@ -2063,6 +2078,7 @@ impl Nursery { "noCommaOperator" => self.no_comma_operator.as_ref(), "noConfusingArrow" => self.no_confusing_arrow.as_ref(), "noConfusingLabels" => self.no_confusing_labels.as_ref(), + "noConsoleLog" => self.no_console_log.as_ref(), "noDuplicateCase" => self.no_duplicate_case.as_ref(), "noDuplicateClassMembers" => self.no_duplicate_class_members.as_ref(), "noDuplicateJsxProps" => self.no_duplicate_jsx_props.as_ref(), diff --git a/crates/rome_service/src/configuration/parse/json/rules.rs b/crates/rome_service/src/configuration/parse/json/rules.rs index 18e05451232..6614973721e 100644 --- a/crates/rome_service/src/configuration/parse/json/rules.rs +++ b/crates/rome_service/src/configuration/parse/json/rules.rs @@ -918,6 +918,7 @@ impl VisitNode for Nursery { "noCommaOperator", "noConfusingArrow", "noConfusingLabels", + "noConsoleLog", "noDuplicateCase", "noDuplicateClassMembers", "noDuplicateJsxProps", @@ -1105,6 +1106,24 @@ impl VisitNode for Nursery { )); } }, + "noConsoleLog" => match value { + AnyJsonValue::JsonStringValue(_) => { + let mut configuration = RuleConfiguration::default(); + self.map_to_known_string(&value, name_text, &mut configuration, diagnostics)?; + self.no_console_log = Some(configuration); + } + AnyJsonValue::JsonObjectValue(_) => { + let mut configuration = RuleConfiguration::default(); + self.map_to_object(&value, name_text, &mut configuration, diagnostics)?; + self.no_console_log = Some(configuration); + } + _ => { + diagnostics.push(DeserializationDiagnostic::new_incorrect_type( + "object or string", + value.range(), + )); + } + }, "noDuplicateCase" => match value { AnyJsonValue::JsonStringValue(_) => { let mut configuration = RuleConfiguration::default(); diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json index 76996c2eb06..98cc397cc43 100644 --- a/editors/vscode/configuration_schema.json +++ b/editors/vscode/configuration_schema.json @@ -531,6 +531,13 @@ { "type": "null" } ] }, + "noConsoleLog": { + "description": "Disallow the use of console.log", + "anyOf": [ + { "$ref": "#/definitions/RuleConfiguration" }, + { "type": "null" } + ] + }, "noDuplicateCase": { "description": "Disallow duplicate case labels. If a switch statement has duplicate test expressions in case clauses, it is likely that a programmer copied a case clause but forgot to change the test expression.", "anyOf": [ diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index 2f07d88baf2..8a6236c168c 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -384,6 +384,10 @@ export interface Nursery { * Disallow labeled statements that are not loops. */ noConfusingLabels?: RuleConfiguration; + /** + * Disallow the use of console.log + */ + noConsoleLog?: RuleConfiguration; /** * Disallow duplicate case labels. If a switch statement has duplicate test expressions in case clauses, it is likely that a programmer copied a case clause but forgot to change the test expression. */ @@ -955,6 +959,7 @@ export type Category = | "lint/nursery/noConfusingArrow" | "lint/nursery/noNoninteractiveTabindex" | "lint/nursery/noAriaUnsupportedElements" + | "lint/nursery/noConsoleLog" | "lint/nursery/noRedeclare" | "lint/nursery/useNamespaceKeyword" | "lint/nursery/noRedundantRoles" diff --git a/npm/rome/configuration_schema.json b/npm/rome/configuration_schema.json index 76996c2eb06..98cc397cc43 100644 --- a/npm/rome/configuration_schema.json +++ b/npm/rome/configuration_schema.json @@ -531,6 +531,13 @@ { "type": "null" } ] }, + "noConsoleLog": { + "description": "Disallow the use of console.log", + "anyOf": [ + { "$ref": "#/definitions/RuleConfiguration" }, + { "type": "null" } + ] + }, "noDuplicateCase": { "description": "Disallow duplicate case labels. If a switch statement has duplicate test expressions in case clauses, it is likely that a programmer copied a case clause but forgot to change the test expression.", "anyOf": [ diff --git a/website/src/pages/lint/rules/index.mdx b/website/src/pages/lint/rules/index.mdx index 9175d76599a..89ea2d16169 100644 --- a/website/src/pages/lint/rules/index.mdx +++ b/website/src/pages/lint/rules/index.mdx @@ -675,6 +675,12 @@ Disallow arrow functions where they could be confused with comparisons. Disallow labeled statements that are not loops.
+

+ noConsoleLog +

+Disallow the use of console.log +
+

noDuplicateCase

diff --git a/website/src/pages/lint/rules/noConfusingArrow.md b/website/src/pages/lint/rules/noConfusingArrow.md index 77d06131c1a..716764779cf 100644 --- a/website/src/pages/lint/rules/noConfusingArrow.md +++ b/website/src/pages/lint/rules/noConfusingArrow.md @@ -18,7 +18,6 @@ Source: https://eslint.org/docs/latest/rules/no-confusing-arrow ```jsx var x = a => 1 ? 2 : 3; -var x = (a) => 1 ? 2 : 3; ```
nursery/noConfusingArrow.js:1:11 lint/nursery/noConfusingArrow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -27,17 +26,21 @@ var x = (a) => 1 ? 2 : 3;
   
   > 1 │ var x = a => 1 ? 2 : 3;
              ^^
-    2 │ var x = (a) => 1 ? 2 : 3;
-    3 │ 
+    2 │ 
   
-nursery/noConfusingArrow.js:2:13 lint/nursery/noConfusingArrow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+ +```jsx +var x = (a) => 1 ? 2 : 3; +``` + +
nursery/noConfusingArrow.js:1:13 lint/nursery/noConfusingArrow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
    Fat arrows can be confused with some comparison operators (<, >, <=, >=).
   
-    1 │ var x = a => 1 ? 2 : 3;
-  > 2 │ var x = (a) => 1 ? 2 : 3;
+  > 1 │ var x = (a) => 1 ? 2 : 3;
                ^^
-    3 │ 
+    2 │ 
   
 
diff --git a/website/src/pages/lint/rules/noConsoleLog.md b/website/src/pages/lint/rules/noConsoleLog.md new file mode 100644 index 00000000000..52e21aae5e2 --- /dev/null +++ b/website/src/pages/lint/rules/noConsoleLog.md @@ -0,0 +1,45 @@ +--- +title: Lint Rule noConsoleLog +parent: lint/rules/index +--- + +# noConsoleLog (since vnext) + +Disallow the use of `console.log` + +## Examples + +### Invalid + +```jsx +console.log() +``` + +
nursery/noConsoleLog.js:1:1 lint/nursery/noConsoleLog ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Don't use console.log
+  
+  > 1 │ console.log()
+   ^^^^^^^^^^^^^
+    2 │ 
+  
+   console.log is usually a tool for debugging and you don't want to have that in production.
+  
+
+ +## Valid + +```jsx +console.info("info"); +console.warn("warn"); +console.error("error"); +console.assert(true); +console.table(["foo", "bar"]); +const console = { log() {} }; +console.log(); +``` + +## Related links + +- [Disable a rule](/linter/#disable-a-lint-rule) +- [Rule options](/linter/#rule-options)