diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 86772b4df63f..a53c03ac2953 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -1335,6 +1335,13 @@ pub(crate) fn migrate_eslint_any_rule( let rule = group.use_numeric_literals.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } + "prefer-object-has-own" => { + let group = rules.suspicious.get_or_insert_with(Default::default); + let rule = group + .no_prototype_builtins + .get_or_insert(Default::default()); + rule.set_level(rule_severity.into()); + } "prefer-regex-literals" => { let group = rules.complexity.get_or_insert_with(Default::default); let rule = group.use_regex_literals.get_or_insert(Default::default()); diff --git a/crates/biome_configuration/src/analyzer/linter/rules.rs b/crates/biome_configuration/src/analyzer/linter/rules.rs index 8f6f8d302ff0..d8dd18c0be50 100644 --- a/crates/biome_configuration/src/analyzer/linter/rules.rs +++ b/crates/biome_configuration/src/analyzer/linter/rules.rs @@ -5989,7 +5989,7 @@ pub struct Suspicious { #[doc = "Disallow direct use of Object.prototype builtins."] #[serde(skip_serializing_if = "Option::is_none")] pub no_prototype_builtins: - Option>, + Option>, #[doc = "Prevents React-specific JSX properties from being used."] #[serde(skip_serializing_if = "Option::is_none")] pub no_react_specific_props: diff --git a/crates/biome_js_analyze/src/lint/suspicious/no_prototype_builtins.rs b/crates/biome_js_analyze/src/lint/suspicious/no_prototype_builtins.rs index f7b0a3ce8be9..77a9cbc25a6d 100644 --- a/crates/biome_js_analyze/src/lint/suspicious/no_prototype_builtins.rs +++ b/crates/biome_js_analyze/src/lint/suspicious/no_prototype_builtins.rs @@ -1,9 +1,16 @@ +use crate::{services::semantic::Semantic, JsRuleAction}; use biome_analyze::{ - context::RuleContext, declare_lint_rule, Ast, Rule, RuleDiagnostic, RuleSource, + context::RuleContext, declare_lint_rule, ActionCategory, FixKind, Rule, RuleDiagnostic, + RuleSource, }; use biome_console::markup; -use biome_js_syntax::{AnyJsMemberExpression, JsCallExpression, TextRange}; -use biome_rowan::AstNode; +use biome_js_factory::make::{self}; +use biome_js_semantic::SemanticModel; +use biome_js_syntax::{ + AnyJsCallArgument, AnyJsExpression, AnyJsMemberExpression, JsCallExpression, JsSyntaxKind, + TextRange, T, +}; +use biome_rowan::{AstNode, BatchMutationExt, TriviaPieceKind}; declare_lint_rule! { /// Disallow direct use of `Object.prototype` builtins. @@ -33,6 +40,10 @@ declare_lint_rule! { /// var invalid = foo.propertyIsEnumerable("bar"); /// ``` /// + /// ```js,expect_diagnostic + /// Object.hasOwnProperty.call(foo, "bar"); + /// ``` + /// /// ### Valid /// /// ```js @@ -42,21 +53,26 @@ declare_lint_rule! { /// ``` /// pub NoPrototypeBuiltins { - version: "1.0.0", + version: "1.1.0", name: "noPrototypeBuiltins", language: "js", - sources: &[RuleSource::Eslint("no-prototype-builtins")], + sources: &[ + RuleSource::Eslint("no-prototype-builtins"), + RuleSource::Eslint("prefer-object-has-own") + ], recommended: true, + fix_kind: FixKind::Safe, } } pub struct RuleState { prototype_builtins_method_name: String, text_range: TextRange, + has_call_fn: bool, } impl Rule for NoPrototypeBuiltins { - type Query = Ast; + type Query = Semantic; type State = RuleState; type Signals = Option; type Options = (); @@ -64,14 +80,36 @@ impl Rule for NoPrototypeBuiltins { fn run(ctx: &RuleContext) -> Self::Signals { let call_expr = ctx.query(); let callee = call_expr.callee().ok()?.omit_parentheses(); - if let Some(member_expr) = AnyJsMemberExpression::cast(callee.into_syntax()) { - let member_name = member_expr.member_name()?; - let member_name_text = member_name.text(); - return is_prototype_builtins(member_name_text).then_some(RuleState { + let member_expr = AnyJsMemberExpression::cast(callee.into_syntax())?; + let member_name = member_expr.member_name()?; + let member_name_text = member_name.text(); + + if is_prototype_builtins(member_name_text) { + return Some(RuleState { prototype_builtins_method_name: member_name_text.to_string(), text_range: member_name.range(), + has_call_fn: false, }); } + + if member_name_text == "call" { + let object = member_expr.object().ok()?.omit_parentheses(); + let obj_expr = AnyJsMemberExpression::cast(object.into_syntax())?; + let obj_name = obj_expr.member_name()?; + let obj_name_text = obj_name.text(); + + if obj_name_text == "hasOwnProperty" + && has_left_hand_object(&obj_expr)? + && is_global_object(ctx.model()) + { + return Some(RuleState { + prototype_builtins_method_name: obj_name_text.to_string(), + text_range: call_expr.range(), + has_call_fn: true, + }); + } + } + None } @@ -97,12 +135,165 @@ impl Rule for NoPrototypeBuiltins { Some(diag) } } + + fn action(ctx: &RuleContext, state: &Self::State) -> Option { + let node = ctx.query(); + + if node.is_optional() || state.prototype_builtins_method_name != "hasOwnProperty" { + return None; + } + + let mut callee = node.callee().ok()?; + let is_callee_parenthesized = callee.as_js_parenthesized_expression().is_some(); + + while let Some(paren_callee) = callee.as_js_parenthesized_expression() { + callee = paren_callee.expression().ok()?; + } + + let member_expr = AnyJsMemberExpression::cast(callee.clone().into_syntax())?; + let member_syntax = member_expr.syntax(); + + if member_expr.is_optional_chain() + || member_syntax.has_comments_direct() + || member_syntax.has_comments_descendants() + { + return None; + } + + let mut mutation = ctx.root().begin(); + let has_own_expr = build_has_own_expr(node, is_callee_parenthesized); + + // foo.hasOwnProperty('bar') -> Object.hasOwn(foo, 'bar') + // foo.bar.hasOwnProperty('bar') -> Object.hasOwn(foo.bar, 'bar') + // foo.["bar"].hasOwnProperty('bar') -> Object.hasOwn(foo.["bar"], 'bar') + if !state.has_call_fn { + let callee_arg = AnyJsCallArgument::AnyJsExpression(member_expr.object().ok()?); + let existing_arg = node.arguments().ok()?.args().into_iter().next()?.ok()?; + + mutation.replace_node( + node.clone(), + make::js_call_expression( + has_own_expr, + make::js_call_arguments( + make::token(T!['(']), + make::js_call_argument_list( + [callee_arg.trim_trivia()?, existing_arg], + [make::token(T![,]) + .with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")])], + ), + make::token(T![')']), + ), + ) + .build(), + ); + } else { + mutation.replace_node(callee, has_own_expr); + } + + Some(JsRuleAction::new( + ActionCategory::QuickFix, + ctx.metadata().applicability(), + markup! { "Use 'Object.hasOwn()' instead." }, + mutation, + )) + } } -/// Chekcks if the `Object.prototype` builtins called directly. +/// Checks if the `Object.prototype` builtins called directly. fn is_prototype_builtins(token_text: &str) -> bool { matches!( token_text, "hasOwnProperty" | "isPrototypeOf" | "propertyIsEnumerable" ) } + +fn is_global_object(semantic: &SemanticModel) -> bool { + semantic + .scopes() + .find(|s| s.get_binding("Object").is_some()) + .map_or(true, |s| s.is_global_scope()) +} + +/// Checks if the given node is considered to be an access to a property of `Object.prototype`. +/// Returns `true` if `expression.object` is `Object`, `Object.prototype`, or `{}` (empty `JsObjectExpression`). +fn has_left_hand_object(member_expr: &AnyJsMemberExpression) -> Option { + let object = member_expr.object().ok()?.omit_parentheses(); + + let node = match &object { + AnyJsExpression::JsObjectExpression(obj_expr) => { + if obj_expr.members().into_iter().count() == 0 { + return Some(true); + } + object + } + AnyJsExpression::JsStaticMemberExpression(_) + | AnyJsExpression::JsComputedMemberExpression(_) => { + let obj_member_expr = AnyJsMemberExpression::cast(object.clone().into_syntax())?; + + if obj_member_expr.member_name()?.text() == "prototype" { + obj_member_expr.object().ok()?.omit_parentheses() + } else { + object + } + } + _ => object, + }; + + if let AnyJsExpression::JsIdentifierExpression(id_expr) = &node { + if id_expr.name().ok()?.text() == "Object" { + return Some(true); + } + } + + Some(false) +} + +/// Checks if previous token of the given node can be adjacent when applying the action. Some +/// tokens are not valid such as `return`, `in` and `of`. +/// +/// # Example +/// ```js +/// return{}.hasOwnProperty.call(a, b); // valid +/// returnObject.hasOwn(a, b); // invalid +/// ``` +fn can_previous_token_be_adjacent(node: &JsCallExpression) -> bool { + let mut prev_sibling = None; + let mut current = node.syntax().clone(); + + while AnyJsExpression::can_cast(current.kind()) { + prev_sibling = current.prev_sibling_or_token(); + + if let Some(parent) = current.parent() { + current = parent; + } else { + break; + } + } + + if let Some(sibling) = prev_sibling { + node.range().start() == sibling.text_range().end() + && matches!( + sibling.kind(), + JsSyntaxKind::IN_KW | JsSyntaxKind::OF_KW | JsSyntaxKind::RETURN_KW + ) + } else { + false + } +} + +fn build_has_own_expr(node: &JsCallExpression, is_callee_parenthesized: bool) -> AnyJsExpression { + let mut object_identifier = String::from("Object"); + + if !is_callee_parenthesized && can_previous_token_be_adjacent(node) { + object_identifier.insert(0, ' '); + } + + AnyJsExpression::from(make::js_static_member_expression( + make::js_identifier_expression(make::js_reference_identifier(make::ident( + &object_identifier, + ))) + .into(), + make::token(T![.]), + make::js_name(make::ident("hasOwn")).into(), + )) +} diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js index 49465d08984c..1b08a8b0dbf8 100644 --- a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js @@ -8,4 +8,37 @@ foo[`isPrototypeOf`]("bar").baz; foo?.hasOwnProperty(bar); (foo?.hasOwnProperty)("bar"); foo?.["hasOwnProperty"]("bar"); -(foo?.[`hasOwnProperty`])("bar"); \ No newline at end of file +(foo?.[`hasOwnProperty`])("bar"); +Object.hasOwnProperty.call(obj, 'foo'); +Object.hasOwnProperty.call(obj, property); +Object.prototype.hasOwnProperty.call(obj, 'foo'); +({}).hasOwnProperty.call(obj, 'foo'); +Object/* comment */.prototype.hasOwnProperty.call(a, b); +const hasProperty = Object.prototype.hasOwnProperty.call(object, property); +const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); +const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); +const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); +const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); +const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); +const hasProperty6 = {}.hasOwnProperty.call(object, property); +const hasProperty7 = {}.hasOwnProperty.call(object, property); +const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); +const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); +const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); +const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); +function foo(){return {}.hasOwnProperty.call(object, property)} +function foo(){return{}.hasOwnProperty.call(object, property)} +function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} +async function foo(){return await{}.hasOwnProperty.call(object, property)} +async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} +for (const x of{}.hasOwnProperty.call(object, property).toString()); +for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); +for (const x in{}.hasOwnProperty.call(object, property).toString()); +for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); +function foo(){return({}.hasOwnProperty.call)(object, property)} +Object['prototype']['hasOwnProperty']['call'](object, property); +Object[`prototype`][`hasOwnProperty`][`call`](object, property); +Object['hasOwnProperty']['call'](object, property); +Object[`hasOwnProperty`][`call`](object, property); +({})['hasOwnProperty']['call'](object, property); +({})[`hasOwnProperty`][`call`](object, property); \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js.snap b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js.snap index 012516ec8c8c..68a0167a428a 100644 --- a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js.snap +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/invalid.js.snap @@ -1,5 +1,6 @@ --- source: crates/biome_js_analyze/tests/spec_tests.rs +assertion_line: 86 expression: invalid.js --- # Input @@ -15,11 +16,44 @@ foo?.hasOwnProperty(bar); (foo?.hasOwnProperty)("bar"); foo?.["hasOwnProperty"]("bar"); (foo?.[`hasOwnProperty`])("bar"); +Object.hasOwnProperty.call(obj, 'foo'); +Object.hasOwnProperty.call(obj, property); +Object.prototype.hasOwnProperty.call(obj, 'foo'); +({}).hasOwnProperty.call(obj, 'foo'); +Object/* comment */.prototype.hasOwnProperty.call(a, b); +const hasProperty = Object.prototype.hasOwnProperty.call(object, property); +const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); +const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); +const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); +const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); +const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); +const hasProperty6 = {}.hasOwnProperty.call(object, property); +const hasProperty7 = {}.hasOwnProperty.call(object, property); +const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); +const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); +const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); +const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); +function foo(){return {}.hasOwnProperty.call(object, property)} +function foo(){return{}.hasOwnProperty.call(object, property)} +function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} +async function foo(){return await{}.hasOwnProperty.call(object, property)} +async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} +for (const x of{}.hasOwnProperty.call(object, property).toString()); +for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); +for (const x in{}.hasOwnProperty.call(object, property).toString()); +for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); +function foo(){return({}.hasOwnProperty.call)(object, property)} +Object['prototype']['hasOwnProperty']['call'](object, property); +Object[`prototype`][`hasOwnProperty`][`call`](object, property); +Object['hasOwnProperty']['call'](object, property); +Object[`hasOwnProperty`][`call`](object, property); +({})['hasOwnProperty']['call'](object, property); +({})[`hasOwnProperty`][`call`](object, property); ``` # Diagnostics ``` -invalid.js:1:5 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalid.js:1:5 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Do not access Object.prototype method 'hasOwnProperty' from target object. @@ -32,6 +66,13 @@ invalid.js:1:5 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ i See MDN web docs for more details. + i Safe fix: Use 'Object.hasOwn()' instead. + + 1 │ - foo.hasOwnProperty("bar"); + 1 │ + Object.hasOwn(foo,·"bar"); + 2 2 │ foo.isPrototypeOf(bar); + 3 3 │ foo.propertyIsEnumerable("bar"); + ``` @@ -65,7 +106,7 @@ invalid.js:3:5 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ ``` ``` -invalid.js:4:9 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalid.js:4:9 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Do not access Object.prototype method 'hasOwnProperty' from target object. @@ -80,6 +121,15 @@ invalid.js:4:9 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ i See MDN web docs for more details. + i Safe fix: Use 'Object.hasOwn()' instead. + + 2 2 │ foo.isPrototypeOf(bar); + 3 3 │ foo.propertyIsEnumerable("bar"); + 4 │ - foo.bar.hasOwnProperty("bar"); + 4 │ + Object.hasOwn(foo.bar,·"bar"); + 5 5 │ foo.bar.baz.isPrototypeOf("bar"); + 6 6 │ foo["hasOwnProperty"]("bar"); + ``` @@ -99,7 +149,7 @@ invalid.js:5:13 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ ``` ``` -invalid.js:6:5 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +invalid.js:6:5 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ! Do not access Object.prototype method 'hasOwnProperty' from target object. @@ -114,6 +164,15 @@ invalid.js:6:5 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ i See MDN web docs for more details. + i Safe fix: Use 'Object.hasOwn()' instead. + + 4 4 │ foo.bar.hasOwnProperty("bar"); + 5 5 │ foo.bar.baz.isPrototypeOf("bar"); + 6 │ - foo["hasOwnProperty"]("bar"); + 6 │ + Object.hasOwn(foo,·"bar"); + 7 7 │ foo[`isPrototypeOf`]("bar").baz; + 8 8 │ foo?.hasOwnProperty(bar); + ``` @@ -180,6 +239,7 @@ invalid.js:10:7 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ > 10 │ foo?.["hasOwnProperty"]("bar"); │ ^^^^^^^^^^^^^^^^ 11 │ (foo?.[`hasOwnProperty`])("bar"); + 12 │ Object.hasOwnProperty.call(obj, 'foo'); i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). @@ -197,12 +257,921 @@ invalid.js:11:9 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━ 10 │ foo?.["hasOwnProperty"]("bar"); > 11 │ (foo?.[`hasOwnProperty`])("bar"); │ ^^^^^^^^^^^^^^ + 12 │ Object.hasOwnProperty.call(obj, 'foo'); + 13 │ Object.hasOwnProperty.call(obj, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + +``` + +``` +invalid.js:12:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 10 │ foo?.["hasOwnProperty"]("bar"); + 11 │ (foo?.[`hasOwnProperty`])("bar"); + > 12 │ Object.hasOwnProperty.call(obj, 'foo'); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 13 │ Object.hasOwnProperty.call(obj, property); + 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 10 10 │ foo?.["hasOwnProperty"]("bar"); + 11 11 │ (foo?.[`hasOwnProperty`])("bar"); + 12 │ - Object.hasOwnProperty.call(obj,·'foo'); + 12 │ + Object.hasOwn(obj,·'foo'); + 13 13 │ Object.hasOwnProperty.call(obj, property); + 14 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + + +``` + +``` +invalid.js:13:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 11 │ (foo?.[`hasOwnProperty`])("bar"); + 12 │ Object.hasOwnProperty.call(obj, 'foo'); + > 13 │ Object.hasOwnProperty.call(obj, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 11 11 │ (foo?.[`hasOwnProperty`])("bar"); + 12 12 │ Object.hasOwnProperty.call(obj, 'foo'); + 13 │ - Object.hasOwnProperty.call(obj,·property); + 13 │ + Object.hasOwn(obj,·property); + 14 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + 15 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + + +``` + +``` +invalid.js:14:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 12 │ Object.hasOwnProperty.call(obj, 'foo'); + 13 │ Object.hasOwnProperty.call(obj, property); + > 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 12 12 │ Object.hasOwnProperty.call(obj, 'foo'); + 13 13 │ Object.hasOwnProperty.call(obj, property); + 14 │ - Object.prototype.hasOwnProperty.call(obj,·'foo'); + 14 │ + Object.hasOwn(obj,·'foo'); + 15 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + 16 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + + +``` + +``` +invalid.js:15:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 13 │ Object.hasOwnProperty.call(obj, property); + 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + > 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 13 13 │ Object.hasOwnProperty.call(obj, property); + 14 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + 15 │ - ({}).hasOwnProperty.call(obj,·'foo'); + 15 │ + Object.hasOwn(obj,·'foo'); + 16 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + 17 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + + +``` + +``` +invalid.js:16:1 lint/suspicious/noPrototypeBuiltins ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 14 │ Object.prototype.hasOwnProperty.call(obj, 'foo'); + 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + > 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + +``` + +``` +invalid.js:17:21 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + > 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 15 15 │ ({}).hasOwnProperty.call(obj, 'foo'); + 16 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + 17 │ - const·hasProperty·=·Object.prototype.hasOwnProperty.call(object,·property); + 17 │ + const·hasProperty·=·Object.hasOwn(object,·property); + 18 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + 19 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + + +``` + +``` +invalid.js:18:25 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + > 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 16 16 │ Object/* comment */.prototype.hasOwnProperty.call(a, b); + 17 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + 18 │ - const·hasProperty1·=·((·Object.prototype.hasOwnProperty.call(object,·property)·)); + 18 │ + const·hasProperty1·=·((·Object.hasOwn(object,·property)·)); + 19 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + 20 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + + +``` + +``` +invalid.js:19:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + > 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). i See MDN web docs for more details. + i Safe fix: Use 'Object.hasOwn()' instead. + + 17 17 │ const hasProperty = Object.prototype.hasOwnProperty.call(object, property); + 18 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + 19 │ - const·hasProperty2·=·((·Object.prototype.hasOwnProperty.call·))(object,·property); + 19 │ + const·hasProperty2·=·((·Object.hasOwn·))(object,·property); + 20 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + 21 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + + +``` + +``` +invalid.js:20:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + > 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 18 18 │ const hasProperty1 = (( Object.prototype.hasOwnProperty.call(object, property) )); + 19 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + 20 │ - const·hasProperty3·=·((·Object.prototype.hasOwnProperty·)).call(object,·property); + 20 │ + const·hasProperty3·=·Object.hasOwn(object,·property); + 21 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + 22 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + + +``` + +``` +invalid.js:21:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + > 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 19 19 │ const hasProperty2 = (( Object.prototype.hasOwnProperty.call ))(object, property); + 20 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + 21 │ - const·hasProperty4·=·((·Object.prototype·)).hasOwnProperty.call(object,·property); + 21 │ + const·hasProperty4·=·Object.hasOwn(object,·property); + 22 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + 23 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + ``` +``` +invalid.js:22:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + > 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 20 20 │ const hasProperty3 = (( Object.prototype.hasOwnProperty )).call(object, property); + 21 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + 22 │ - const·hasProperty5·=·((·Object·)).prototype.hasOwnProperty.call(object,·property); + 22 │ + const·hasProperty5·=·Object.hasOwn(object,·property); + 23 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + 24 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + + +``` + +``` +invalid.js:23:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + > 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 21 21 │ const hasProperty4 = (( Object.prototype )).hasOwnProperty.call(object, property); + 22 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + 23 │ - const·hasProperty6·=·{}.hasOwnProperty.call(object,·property); + 23 │ + const·hasProperty6·=·Object.hasOwn(object,·property); + 24 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + 25 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + + +``` + +``` +invalid.js:24:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + > 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 22 22 │ const hasProperty5 = (( Object )).prototype.hasOwnProperty.call(object, property); + 23 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + 24 │ - const·hasProperty7·=·{}.hasOwnProperty.call(object,·property); + 24 │ + const·hasProperty7·=·Object.hasOwn(object,·property); + 25 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + 26 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + + +``` + +``` +invalid.js:25:25 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + > 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 23 23 │ const hasProperty6 = {}.hasOwnProperty.call(object, property); + 24 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + 25 │ - const·hasProperty8·=·((·{}.hasOwnProperty.call(object,·property)·)); + 25 │ + const·hasProperty8·=·((·Object.hasOwn(object,·property)·)); + 26 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + 27 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + + +``` + +``` +invalid.js:26:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + > 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 24 24 │ const hasProperty7 = {}.hasOwnProperty.call(object, property); + 25 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + 26 │ - const·hasProperty9·=·((·{}.hasOwnProperty.call·))(object,·property); + 26 │ + const·hasProperty9·=·((·Object.hasOwn·))(object,·property); + 27 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + 28 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + + +``` + +``` +invalid.js:27:23 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + > 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 25 25 │ const hasProperty8 = (( {}.hasOwnProperty.call(object, property) )); + 26 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + 27 │ - const·hasProperty10·=·((·{}.hasOwnProperty·)).call(object,·property); + 27 │ + const·hasProperty10·=·Object.hasOwn(object,·property); + 28 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + 29 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + + +``` + +``` +invalid.js:28:23 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + > 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 26 26 │ const hasProperty9 = (( {}.hasOwnProperty.call ))(object, property); + 27 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + 28 │ - const·hasProperty11·=·((·{}·)).hasOwnProperty.call(object,·property); + 28 │ + const·hasProperty11·=·Object.hasOwn(object,·property); + 29 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + 30 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + + +``` + +``` +invalid.js:29:23 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + > 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 27 27 │ const hasProperty10 = (( {}.hasOwnProperty )).call(object, property); + 28 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + 29 │ - function·foo(){return·{}.hasOwnProperty.call(object,·property)} + 29 │ + function·foo(){return··Object.hasOwn(object,·property)} + 30 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + 31 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + + +``` + +``` +invalid.js:30:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + > 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 28 28 │ const hasProperty11 = (( {} )).hasOwnProperty.call(object, property); + 29 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + 30 │ - function·foo(){return{}.hasOwnProperty.call(object,·property)} + 30 │ + function·foo(){return·Object.hasOwn(object,·property)} + 31 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + 32 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + + +``` + +``` +invalid.js:31:33 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + > 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 29 29 │ function foo(){return {}.hasOwnProperty.call(object, property)} + 30 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + 31 │ - function·foo(){return/*comment*/{}.hasOwnProperty.call(object,·property)} + 31 │ + function·foo(){return/*comment*/·Object.hasOwn(object,·property)} + 32 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + 33 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + + +``` + +``` +invalid.js:32:34 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + > 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 30 30 │ function foo(){return{}.hasOwnProperty.call(object, property)} + 31 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + 32 │ - async·function·foo(){return·await{}.hasOwnProperty.call(object,·property)} + 32 │ + async·function·foo(){return·awaitObject.hasOwn(object,·property)} + 33 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + 34 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + + +``` + +``` +invalid.js:33:45 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + > 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 31 31 │ function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)} + 32 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + 33 │ - async·function·foo(){return·await/*comment*/{}.hasOwnProperty.call(object,·property)} + 33 │ + async·function·foo(){return·await/*comment*/Object.hasOwn(object,·property)} + 34 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + 35 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + + +``` + +``` +invalid.js:34:16 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + > 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 32 32 │ async function foo(){return await{}.hasOwnProperty.call(object, property)} + 33 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + 34 │ - for·(const·x·of{}.hasOwnProperty.call(object,·property).toString()); + 34 │ + for·(const·x·of·Object.hasOwn(object,·property).toString()); + 35 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 36 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + + +``` + +``` +invalid.js:35:27 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + > 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 33 33 │ async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)} + 34 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + 35 │ - for·(const·x·of/*comment*/{}.hasOwnProperty.call(object,·property).toString()); + 35 │ + for·(const·x·of/*comment*/·Object.hasOwn(object,·property).toString()); + 36 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + 37 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + + +``` + +``` +invalid.js:36:16 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + > 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 34 34 │ for (const x of{}.hasOwnProperty.call(object, property).toString()); + 35 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 36 │ - for·(const·x·in{}.hasOwnProperty.call(object,·property).toString()); + 36 │ + for·(const·x·in·Object.hasOwn(object,·property).toString()); + 37 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 38 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + + +``` + +``` +invalid.js:37:27 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + > 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 35 35 │ for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 36 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + 37 │ - for·(const·x·in/*comment*/{}.hasOwnProperty.call(object,·property).toString()); + 37 │ + for·(const·x·in/*comment*/·Object.hasOwn(object,·property).toString()); + 38 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + 39 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + + +``` + +``` +invalid.js:38:22 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + > 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 36 36 │ for (const x in{}.hasOwnProperty.call(object, property).toString()); + 37 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 38 │ - function·foo(){return({}.hasOwnProperty.call)(object,·property)} + 38 │ + function·foo(){return(Object.hasOwn)(object,·property)} + 39 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + 40 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + + +``` + +``` +invalid.js:39:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + > 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + 41 │ Object['hasOwnProperty']['call'](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 37 37 │ for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString()); + 38 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + 39 │ - Object['prototype']['hasOwnProperty']['call'](object,·property); + 39 │ + Object.hasOwn(object,·property); + 40 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + 41 41 │ Object['hasOwnProperty']['call'](object, property); + + +``` + +``` +invalid.js:40:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + > 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 41 │ Object['hasOwnProperty']['call'](object, property); + 42 │ Object[`hasOwnProperty`][`call`](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 38 38 │ function foo(){return({}.hasOwnProperty.call)(object, property)} + 39 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + 40 │ - Object[`prototype`][`hasOwnProperty`][`call`](object,·property); + 40 │ + Object.hasOwn(object,·property); + 41 41 │ Object['hasOwnProperty']['call'](object, property); + 42 42 │ Object[`hasOwnProperty`][`call`](object, property); + + +``` + +``` +invalid.js:41:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + > 41 │ Object['hasOwnProperty']['call'](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 42 │ Object[`hasOwnProperty`][`call`](object, property); + 43 │ ({})['hasOwnProperty']['call'](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 39 39 │ Object['prototype']['hasOwnProperty']['call'](object, property); + 40 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + 41 │ - Object['hasOwnProperty']['call'](object,·property); + 41 │ + Object.hasOwn(object,·property); + 42 42 │ Object[`hasOwnProperty`][`call`](object, property); + 43 43 │ ({})['hasOwnProperty']['call'](object, property); + + +``` + +``` +invalid.js:42:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + 41 │ Object['hasOwnProperty']['call'](object, property); + > 42 │ Object[`hasOwnProperty`][`call`](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 43 │ ({})['hasOwnProperty']['call'](object, property); + 44 │ ({})[`hasOwnProperty`][`call`](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 40 40 │ Object[`prototype`][`hasOwnProperty`][`call`](object, property); + 41 41 │ Object['hasOwnProperty']['call'](object, property); + 42 │ - Object[`hasOwnProperty`][`call`](object,·property); + 42 │ + Object.hasOwn(object,·property); + 43 43 │ ({})['hasOwnProperty']['call'](object, property); + 44 44 │ ({})[`hasOwnProperty`][`call`](object, property); + + +``` + +``` +invalid.js:43:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 41 │ Object['hasOwnProperty']['call'](object, property); + 42 │ Object[`hasOwnProperty`][`call`](object, property); + > 43 │ ({})['hasOwnProperty']['call'](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 44 │ ({})[`hasOwnProperty`][`call`](object, property); + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 41 41 │ Object['hasOwnProperty']['call'](object, property); + 42 42 │ Object[`hasOwnProperty`][`call`](object, property); + 43 │ - ({})['hasOwnProperty']['call'](object,·property); + 43 │ + Object.hasOwn(object,·property); + 44 44 │ ({})[`hasOwnProperty`][`call`](object, property); + + +``` + +``` +invalid.js:44:1 lint/suspicious/noPrototypeBuiltins FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Do not access Object.prototype method 'hasOwnProperty' from target object. + + 42 │ Object[`hasOwnProperty`][`call`](object, property); + 43 │ ({})['hasOwnProperty']['call'](object, property); + > 44 │ ({})[`hasOwnProperty`][`call`](object, property); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + i It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty(). + + i See MDN web docs for more details. + + i Safe fix: Use 'Object.hasOwn()' instead. + + 42 42 │ Object[`hasOwnProperty`][`call`](object, property); + 43 43 │ ({})['hasOwnProperty']['call'](object, property); + 44 │ - ({})[`hasOwnProperty`][`call`](object,·property); + 44 │ + Object.hasOwn(object,·property); + + +``` diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js index d73d0a32e9d0..c0d04fe7f987 100644 --- a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js @@ -1,5 +1,4 @@ Object.hasOwn(foo, "bar"); -Object.prototype.hasOwnProperty.call(foo, "bar"); Object.prototype.isPrototypeOf.call(foo, bar); Object.prototype.propertyIsEnumerable.call(foo, 'bar'); Object.prototype.hasOwnProperty.apply(foo, ['bar']); @@ -11,11 +10,34 @@ foo(hasOwnProperty); hasOwnProperty(foo, 'bar'); isPrototypeOf(foo, 'bar'); propertyIsEnumerable(foo, 'bar'); -({}.hasOwnProperty.call(foo, 'bar')); ({}.isPrototypeOf.call(foo, 'bar')); ({}.propertyIsEnumerable.call(foo, 'bar')); ({}.hasOwnProperty.apply(foo, ['bar'])); ({}.isPrototypeOf.apply(foo, ['bar'])); ({}.propertyIsEnumerable.apply(foo, ['bar'])); foo[hasOwnProperty]('bar'); -foo['HasOwnProperty']('bar'); \ No newline at end of file +foo['HasOwnProperty']('bar'); +Object; +Object(obj, prop); +Object.hasOwnProperty; +hasOwnProperty(obj, prop); +Object.hasOwnProperty.call; +foo.Object.hasOwnProperty.call(obj, prop); +foo.hasOwnProperty.call(obj, prop); +Object.foo.call(obj, prop); +Object.hasOwnProperty.foo(obj, prop); +Object.hasOwnProperty.call.foo(obj, prop); +Object[hasOwnProperty].call(obj, prop); +Object.hasOwnProperty[call](obj, prop); +Object.foo.hasOwnProperty.call(obj, prop); +({}); +({}(obj, prop)); +({}.hasOwnProperty); +({}.hasOwnProperty.call); +({}.foo.call(obj, prop)); +({}.hasOwnProperty.foo(obj, prop)); +({}[hasOwnProperty].call(obj, prop)); +({}.hasOwnProperty[call](obj, prop)); +({}).hasOwnProperty[call](object, property); +({})[hasOwnProperty].call(object, property); +({ foo }.hasOwnProperty.call(obj, prop)); // object literal should be empty \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js.snap b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js.snap index fc13578bc464..2be5fe31c372 100644 --- a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js.snap +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/valid.js.snap @@ -1,11 +1,11 @@ --- source: crates/biome_js_analyze/tests/spec_tests.rs +assertion_line: 86 expression: valid.js --- # Input ```jsx Object.hasOwn(foo, "bar"); -Object.prototype.hasOwnProperty.call(foo, "bar"); Object.prototype.isPrototypeOf.call(foo, bar); Object.prototype.propertyIsEnumerable.call(foo, 'bar'); Object.prototype.hasOwnProperty.apply(foo, ['bar']); @@ -17,7 +17,6 @@ foo(hasOwnProperty); hasOwnProperty(foo, 'bar'); isPrototypeOf(foo, 'bar'); propertyIsEnumerable(foo, 'bar'); -({}.hasOwnProperty.call(foo, 'bar')); ({}.isPrototypeOf.call(foo, 'bar')); ({}.propertyIsEnumerable.call(foo, 'bar')); ({}.hasOwnProperty.apply(foo, ['bar'])); @@ -25,6 +24,28 @@ propertyIsEnumerable(foo, 'bar'); ({}.propertyIsEnumerable.apply(foo, ['bar'])); foo[hasOwnProperty]('bar'); foo['HasOwnProperty']('bar'); +Object; +Object(obj, prop); +Object.hasOwnProperty; +hasOwnProperty(obj, prop); +Object.hasOwnProperty.call; +foo.Object.hasOwnProperty.call(obj, prop); +foo.hasOwnProperty.call(obj, prop); +Object.foo.call(obj, prop); +Object.hasOwnProperty.foo(obj, prop); +Object.hasOwnProperty.call.foo(obj, prop); +Object[hasOwnProperty].call(obj, prop); +Object.hasOwnProperty[call](obj, prop); +Object.foo.hasOwnProperty.call(obj, prop); +({}); +({}(obj, prop)); +({}.hasOwnProperty); +({}.hasOwnProperty.call); +({}.foo.call(obj, prop)); +({}.hasOwnProperty.foo(obj, prop)); +({}[hasOwnProperty].call(obj, prop)); +({}.hasOwnProperty[call](obj, prop)); +({}).hasOwnProperty[call](object, property); +({})[hasOwnProperty].call(object, property); +({ foo }.hasOwnProperty.call(obj, prop)); // object literal should be empty ``` - - diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js new file mode 100644 index 000000000000..b8589f8154f5 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js @@ -0,0 +1,7 @@ +class C { #hasOwnProperty; foo() { Object.#hasOwnProperty.call(obj, prop) } } +class C { #call; foo() { Object.hasOwnProperty.#call(obj, prop) } } +class C { #hasOwnProperty; foo() { Object.prototype.#hasOwnProperty.call(obj, prop) } } +class C { #call; foo() { Object.prototype.hasOwnProperty.#call(obj, prop) } } +class C { #hasOwnProperty; foo() { ({}.#hasOwnProperty.call(obj, prop)) } } +class C { #call; foo() { ({}.hasOwnProperty.#call(obj, prop)) } } +class C { #prototype; foo() { Object.#prototype.hasOwnProperty.call(obj, prop) } } \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js.snap b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js.snap new file mode 100644 index 000000000000..077489b0f516 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validClass.js.snap @@ -0,0 +1,15 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +assertion_line: 86 +expression: validClass.js +--- +# Input +```jsx +class C { #hasOwnProperty; foo() { Object.#hasOwnProperty.call(obj, prop) } } +class C { #call; foo() { Object.hasOwnProperty.#call(obj, prop) } } +class C { #hasOwnProperty; foo() { Object.prototype.#hasOwnProperty.call(obj, prop) } } +class C { #call; foo() { Object.prototype.hasOwnProperty.#call(obj, prop) } } +class C { #hasOwnProperty; foo() { ({}.#hasOwnProperty.call(obj, prop)) } } +class C { #call; foo() { ({}.hasOwnProperty.#call(obj, prop)) } } +class C { #prototype; foo() { Object.#prototype.hasOwnProperty.call(obj, prop) } } +``` diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js new file mode 100644 index 000000000000..23f9bb556832 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js @@ -0,0 +1,3 @@ +(Object) => Object.hasOwnProperty.call(obj, prop); // not global Object +(Object) => ({}).hasOwnProperty.call(obj, prop); // Object is shadowed, so Object.hasOwn cannot be used here +(Object) => Object.prototype.hasOwnProperty.call(obj, prop); // not global Object \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js.snap b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js.snap new file mode 100644 index 000000000000..2bc145841ffa --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validNonGlobalObject.js.snap @@ -0,0 +1,11 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +assertion_line: 86 +expression: validNonGlobalObject.js +--- +# Input +```jsx +(Object) => Object.hasOwnProperty.call(obj, prop); // not global Object +(Object) => ({}).hasOwnProperty.call(obj, prop); // Object is shadowed, so Object.hasOwn cannot be used here +(Object) => Object.prototype.hasOwnProperty.call(obj, prop); // not global Object +``` diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js new file mode 100644 index 000000000000..854306f233dc --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js @@ -0,0 +1,15 @@ +foo.call(Object.prototype.hasOwnProperty, Object.prototype.hasOwnProperty.call); +Object.prototype; +Object.prototype(obj, prop); +Object.prototype.hasOwnProperty.call; +foo.Object.prototype.hasOwnProperty.call(obj, prop); +foo.prototype.hasOwnProperty.call(obj, prop); +Object.prototype.foo.call(obj, prop); +Object.prototype.hasOwnProperty.foo(obj, prop); +Object.prototype.hasOwnProperty.call.foo(obj, prop); +Object.prototype.prototype.hasOwnProperty.call(a, b); +Object.hasOwnProperty.prototype.hasOwnProperty.call(a, b); +Object.prototype[hasOwnProperty].call(obj, prop); +Object.prototype.hasOwnProperty[call](obj, prop); +Object[prototype].hasOwnProperty.call(obj, prop); +({}).prototype.hasOwnProperty.call(a, b); \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js.snap b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js.snap new file mode 100644 index 000000000000..fe658280f206 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/suspicious/noPrototypeBuiltins/validPrototype.js.snap @@ -0,0 +1,23 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +assertion_line: 86 +expression: validPrototype.js +--- +# Input +```jsx +foo.call(Object.prototype.hasOwnProperty, Object.prototype.hasOwnProperty.call); +Object.prototype; +Object.prototype(obj, prop); +Object.prototype.hasOwnProperty.call; +foo.Object.prototype.hasOwnProperty.call(obj, prop); +foo.prototype.hasOwnProperty.call(obj, prop); +Object.prototype.foo.call(obj, prop); +Object.prototype.hasOwnProperty.foo(obj, prop); +Object.prototype.hasOwnProperty.call.foo(obj, prop); +Object.prototype.prototype.hasOwnProperty.call(a, b); +Object.hasOwnProperty.prototype.hasOwnProperty.call(a, b); +Object.prototype[hasOwnProperty].call(obj, prop); +Object.prototype.hasOwnProperty[call](obj, prop); +Object[prototype].hasOwnProperty.call(obj, prop); +({}).prototype.hasOwnProperty.call(a, b); +``` diff --git a/crates/biome_js_semantic/src/semantic_model/scope.rs b/crates/biome_js_semantic/src/semantic_model/scope.rs index 11799ebc30b3..a55f970a698e 100644 --- a/crates/biome_js_semantic/src/semantic_model/scope.rs +++ b/crates/biome_js_semantic/src/semantic_model/scope.rs @@ -41,6 +41,10 @@ impl PartialEq for Scope { impl Eq for Scope {} impl Scope { + pub fn is_global_scope(&self) -> bool { + self.id.index() == 0 + } + /// Returns all parents of this scope. Starting with the current /// [Scope]. pub fn ancestors(&self) -> impl Iterator { diff --git a/crates/biome_js_syntax/src/expr_ext.rs b/crates/biome_js_syntax/src/expr_ext.rs index 07ec15fe3ebb..8ed55c3833dc 100644 --- a/crates/biome_js_syntax/src/expr_ext.rs +++ b/crates/biome_js_syntax/src/expr_ext.rs @@ -1448,6 +1448,13 @@ impl AnyJsMemberExpression { } } + pub fn is_optional_chain(&self) -> bool { + match self { + AnyJsMemberExpression::JsComputedMemberExpression(e) => e.is_optional_chain(), + AnyJsMemberExpression::JsStaticMemberExpression(e) => e.is_optional_chain(), + } + } + /// Returns the member name of `self` if `self` is a static member or a computed member with a literal string. /// /// ## Examples diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index fee8e0c5094d..53c5e76e28d8 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -1881,7 +1881,7 @@ export interface Suspicious { /** * Disallow direct use of Object.prototype builtins. */ - noPrototypeBuiltins?: RuleConfiguration_for_Null; + noPrototypeBuiltins?: RuleFixConfiguration_for_Null; /** * Prevents React-specific JSX properties from being used. */ diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index b9e701ff783a..1c1de25f4504 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -3921,7 +3921,7 @@ "noPrototypeBuiltins": { "description": "Disallow direct use of Object.prototype builtins.", "anyOf": [ - { "$ref": "#/definitions/RuleConfiguration" }, + { "$ref": "#/definitions/RuleFixConfiguration" }, { "type": "null" } ] },