Repository: eslint/eslint
File: lib/rules/utils/ast-utils.js (JavaScript)

Code before:

            for (const statement of statements) {
                if (
                    statement.type === "ExpressionStatement" &&
                    statement.expression.type === "Literal"
                ) {
                    directives.push(statement);
                } else {
                    break;
                }
            }
        }

        return directives;
    },

    /**
     * Checks whether a specified node is an ExpressionStatement that is either part of,
     * or immediately follows a (possibly empty) directive prologue.
     * @see {@link http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive}
     * @param {SourceCode} sourceCode The source code object to get tokens.
     * @param {ASTNode} node An expression node.
     * @returns {boolean} Whether a specified node is an ExpressionStatement that is either part of,
     * or immediately follows a (possibly empty) directive prologue.
     */
    isExpressionInOrJustAfterDirectivePrologue(sourceCode, node) {
        if (node.type !== "ExpressionStatement") {
            return false;
        }
        const block = node.parent;

        if (block.type !== "Program" && (block.type !== "BlockStatement" || !isFunction(block.parent))) {
            return false;
        }
        for (const statement of block.body) {
            if (statement === node) {
                break;
            }
            if (statement.type !== "ExpressionStatement" ||
                statement.expression.type !== "Literal" ||
                typeof statement.expression.value !== "string" ||
                isParenthesised(sourceCode, statement.expression)) {
                return false;
            }
        }
        return true;
    },

    /**
     * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
     * after the node will be parsed as a decimal point, rather than a property-access dot.

Review comment (refactor):
This is a refactoring of the deleted function `isPartOfDirectivePrologue` from `quotes.js` with a few changes:
* Renamed the function to `isExpressionInOrJustAfterDirectivePrologue` to better describe what it does
* Changed the argument to the be the parent node (the `ExpressionStatement`)
* Added a check to make sure that the specified node is really an `ExpressionStatement`
* Fixed the logic that checks if a sibling node is a directive to ensure that literals in parentheses test negative
* Added an additional `SourceCode` argument to the function (necessary to test for parentheses)

Code after:
     * @param {ASTNode} node The node to check.
     * @returns {ASTNode[]} The directives found in the directive prologue.
     */
    getDirectivePrologue(node) {
        const directives = [];

        // Directive prologues only occur at the top of files or functions.
        if (
            node.type === "Program" ||
            node.type === "FunctionDeclaration" ||
            node.type === "FunctionExpression" ||

            /*
             * Do not check arrow functions with implicit return.
             * `() => "use strict";` returns the string `"use strict"`.
             */
            (node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
        ) {
            const statements = node.type === "Program" ? node.body : node.body.body;

            for (const statement of statements) {
                if (
                    statement.type === "ExpressionStatement" &&
                    statement.expression.type === "Literal"
                ) {
                    directives.push(statement);
                } else {
                    break;
                }
            }
        }

        return directives;
    },

    /**
     * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
     * after the node will be parsed as a decimal point, rather than a property-access dot.
     * @param {ASTNode} node The node to check.
     * @returns {boolean} `true` if this node is a decimal integer.
     * @example
     *
     * 0         // true
     * 5         // true
     * 50        // true
     * 5_000     // true
     * 1_234_56  // true
     * 08        // true
     * 0192      // true
     * 5.        // false
     * .5        // false