Skip to content

Comments

JS-1322 Fix S7723 false positive on Object(value) type coercion pattern#6429

Open
ss-vibe-bot[bot] wants to merge 4 commits intomasterfrom
fix/JS-1322-fix-fp-on-s7723-object-used-for-type-coercion-not-object-creation-opus
Open

JS-1322 Fix S7723 false positive on Object(value) type coercion pattern#6429
ss-vibe-bot[bot] wants to merge 4 commits intomasterfrom
fix/JS-1322-fix-fp-on-s7723-object-used-for-type-coercion-not-object-creation-opus

Conversation

@ss-vibe-bot
Copy link
Contributor

@ss-vibe-bot ss-vibe-bot bot commented Feb 20, 2026

Summary

Fix a false positive in rule S7723 (based on upstream unicorn/new-for-builtins) where Object(value) calls used for type coercion were incorrectly flagged as missing new. Calling Object(value) with arguments is a common type coercion pattern (e.g., in polyfills), not object creation, and should not be reported.

Ticket: JS-1322

Changes

  • Add a decorator around the upstream unicorn/new-for-builtins rule that uses interceptReport to suppress issues when Object() is called with one or more arguments
  • Object() without arguments continues to be flagged as non-compliant
  • Update the RSPEC metadata to document this exception
  • Add test cases covering real-world Object(value) type coercion patterns: Object(this) in polyfills, Object(value) with the in operator, and for...in Object(value) loops
  • Add a RegExp() without new test to improve invalid case coverage
  • Sync expected ruling files
Proposed rspec changes
diff --git a/rules/S7723/javascript/rule.adoc b/rules/S7723/javascript/rule.adoc
index 08a2ce2..0189a74 100644
--- a/rules/S7723/javascript/rule.adoc
+++ b/rules/S7723/javascript/rule.adoc
@@ -8,6 +8,8 @@ For most built-in constructors like `Array`, `Object`, `Date`, `Map`, etc., both
 
 There are important exceptions: `String`, `Number`, `Boolean`, `Symbol`, and `BigInt` should NOT use `new`. When called without `new`, these functions convert values to primitive types. When called with `new`, they create wrapper objects instead of primitives, which is rarely what you want and can cause unexpected behavior in comparisons and type checks.
 
+Similarly, `Object(value)` called with an argument is a type coercion pattern that converts the value to an object, preserving existing objects while wrapping primitives. This is semantically different from `new Object()` which creates a new empty object, so `Object()` with arguments is not flagged by this rule.
+
 For example, `new String('hello')` creates a String object, while `String('hello')` creates a primitive string. The object version behaves differently in boolean contexts and equality comparisons.
 
 === What is the potential impact?
@@ -37,6 +39,13 @@ const now = new Date();
 const map = new Map([['foo', 'bar']]);
 ----
 
+`Object()` called with an argument is used for type coercion, not object creation:
+
+[source,javascript]
+----
+const obj = Object(value); // Compliant - type coercion
+----
+
 === Documentation
 
 * https://github.com/sindresorhus/eslint-plugin-unicorn#readme[eslint-plugin-unicorn] - Rule https://github.com/sindresorhus/eslint-plugin-unicorn/blob/HEAD/docs/rules/new-for-builtins.md[new-for-builtins]

Vibe Bot and others added 4 commits February 20, 2026 17:18
Tests cover the scenario where Object(value) is called with arguments
for type coercion rather than object creation. The tests verify that
Object(value) patterns are not flagged while Object() without arguments
and other constructors like Array() and Error() remain non-compliant.

Relates to JS-1322
Add a decorator for the upstream unicorn/new-for-builtins rule to suppress
issues when Object() is called with arguments, as this is a type coercion
pattern (e.g., Object(value)) rather than object creation. Object() without
arguments remains flagged. The implementation uses interceptReport to filter
CallExpression nodes with callee "Object" and one or more arguments. The
rspec is updated to document this exception. Test cases include output fields
for the upstream rule's auto-fixer.

Relates to JS-1322
Add test cases for S7723 covering real-world Object(value) type coercion
patterns discovered during ruling analysis: Object(this) in polyfills,
Object(value) with the 'in' operator, and for...in Object(value) loops.
Also add a RegExp() without new test to improve invalid case coverage.

No implementation changes were needed - the decorator correctly suppresses
all Object(value) type coercion patterns while allowing other constructor
violations to be reported.
Ticket: JS-1322

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Contributor

Ruling Report

Code no longer flagged (27 issues)

S7723

ace/lib/ace/mode/javascript/jshint.js:1130

  1128 |   }
  1129 |   var result = [];
> 1130 |   for (var key in Object(object)) {
  1131 |     if (hasOwnProperty.call(object, key) && key != 'constructor') {
  1132 |       result.push(key);

ace/lib/ace/mode/javascript/jshint.js:1230

  1228 |  */
  1229 | function cloneSymbol(symbol) {
> 1230 |   return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
  1231 | }
  1232 | 

ace/lib/ace/mode/javascript/jshint.js:2695

  2693 |     var _keys = keys(attrs), length = _keys.length;
  2694 |     if (object == null) return !length;
> 2695 |     var obj = Object(object);
  2696 |     for (var i = 0; i < length; i++) {
  2697 |       var key = _keys[i];

ace/lib/ace/mode/javascript/jshint.js:2963

  2961 |     return function(obj) {
  2962 |       var length = arguments.length;
> 2963 |       if (defaults) obj = Object(obj);
  2964 |       if (length < 2 || obj == null) return obj;
  2965 |       for (var index = 1; index < length; index++) {

ace/lib/ace/mode/javascript/jshint.js:4022

  4020 |       iteratee = keyInObj;
  4021 |       keys = flatten$1(keys, false, false);
> 4022 |       obj = Object(obj);
  4023 |     }
  4024 |     for (var i = 0, length = keys.length; i < length; i++) {

ace/lib/ace/mode/yaml/yaml-lint.js:4792

  4790 |     return value === undefined ? undefinedTag : nullTag;
  4791 |   }
> 4792 |   return (symToStringTag && symToStringTag in Object(value))
  4793 |     ? getRawTag(value)
  4794 |     : objectToString(value);

ace/lib/ace/mode/yaml/yaml-lint.js:5119

  5117 |       length = 1;
  5118 |     }
> 5119 |     object = Object(object);
  5120 |     while (++index < length) {
  5121 |       var source = sources[index];

ace/lib/ace/mode/yaml/yaml-lint.js:5140

  5138 |   return function(object, iteratee, keysFunc) {
  5139 |     var index = -1,
> 5140 |         iterable = Object(object),
  5141 |         props = keysFunc(object),
  5142 |         length = props.length;

ace/lib/ace/mode/yaml/yaml-lint.js:5315

  5313 |   var result = [];
  5314 |   if (object != null) {
> 5315 |     for (var key in Object(object)) {
  5316 |       result.push(key);
  5317 |     }

ace/src/lib/es6-shim.js:54

    52 |       }
    53 | 
>   54 |       var output = Object(target);
    55 |       for (var index = 1; index < arguments.length; index++) {
    56 |         var source = arguments[index];

...and 17 more

📋 View full report

Code no longer flagged (27)

S7723

@sonarqube-next
Copy link

@ss-vibe-bot
Copy link
Contributor Author

ss-vibe-bot bot commented Feb 20, 2026

github-actions[bot] 2026-02-20T18:21:56Z addressed
The ruling report looks as expected. All 27 "code no longer flagged" issues are Object(value) type coercion patterns (e.g., Object(object) for iteration, Object(target) in polyfills, Object(value) with the in operator). These are exactly the false positives this PR fixes by suppressing Object() calls with arguments. No new issues were introduced.

@ss-vibe-bot ss-vibe-bot bot marked this pull request as ready for review February 20, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants