Repository: eslint/eslint
File: lib/rules/no-object-constructor.js (JavaScript)

Code before:
    return false;
}

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Disallow calls to the `Object` constructor without an argument",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/no-object-constructor"
        },

        hasSuggestions: true,

        schema: [],

        messages: {
            preferLiteral: "The object literal notation {} is preferable.",
            useLiteral: "Replace with '{{replacement}}'.",
            useLiteralAfterSemicolon: "Replace with '{{replacement}}', add implicit semicolon."
        }
    },

    create(context) {

        const sourceCode = context.sourceCode;

        /**
         * Determines whether or not an object literal that replaces a specified node needs to be enclosed in parentheses.
         * @param {ASTNode} node The node to be replaced.
         * @returns {boolean} Whether or not parentheses around the object literal are required.
         */
        function needsParentheses(node) {
            if (isStartOfExpressionStatement(node)) {
                return true;
            }

            const prevToken = sourceCode.getTokenBefore(node);

            if (prevToken && isArrowToken(prevToken)) {
                return true;
            }

            return false;
        }

Review comment (suggestion):
"add implicit semicolon" sounds confusing to me as the semicolon that's going to be added is rather explicit than implicit (I get that we're adding `;` in place of an implicit semicolon, but still sounds confusing as we're not adding an implicit semicolon).

Maybe preceding?


```suggestion
            useLiteralAfterSemicolon: "Replace with '{{replacement}}', add preceding semicolon."
```

Code after:
    else: "IfStatement",
    return: "ReturnStatement",
    yield: "YieldExpression"
};

/*
 * Before an opening parenthesis, `>` (for JSX), and postfix `++` and `--` always trigger ASI;
 * the tokens `:`, `;`, `{` and `=>` don't expect a semicolon, as that would count as an empty statement.
 */
const PUNCTUATORS = new Set([":", ";", ">", "{", "=>", "++", "--"]);

/*
 * Statements that can contain an `ExpressionStatement` after a closing parenthesis.
 * DoWhileStatement is an exception in that it always triggers ASI after the closing parenthesis.
 */
const STATEMENTS = new Set([
    "DoWhileStatement",
    "ForInStatement",
    "ForOfStatement",
    "ForStatement",
    "IfStatement",
    "WhileStatement",
    "WithStatement"
]);

/**
 * Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
 * @param {ASTNode} node The node to check.
 * @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
 */
function isStartOfExpressionStatement(node) {
    const start = node.range[0];
    let ancestor = node;

    while ((ancestor = ancestor.parent) && ancestor.range[0] === start) {
        if (ancestor.type === "ExpressionStatement") {
            return true;
        }
    }
    return false;
}

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",