| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 | /** * @fileoverview Rule to flag use of unnecessary semicolons * @author Nicholas C. Zakas */"use strict";//------------------------------------------------------------------------------// Requirements//------------------------------------------------------------------------------const FixTracker = require("../util/fix-tracker");const astUtils = require("../ast-utils");//------------------------------------------------------------------------------// Rule Definition//------------------------------------------------------------------------------module.exports = {    meta: {        docs: {            description: "disallow unnecessary semicolons",            category: "Possible Errors",            recommended: true,            url: "https://eslint.org/docs/rules/no-extra-semi"        },        fixable: "code",        schema: [],        messages: {            unexpected: "Unnecessary semicolon."        }    },    create(context) {        const sourceCode = context.getSourceCode();        /**         * Reports an unnecessary semicolon error.         * @param {Node|Token} nodeOrToken - A node or a token to be reported.         * @returns {void}         */        function report(nodeOrToken) {            context.report({                node: nodeOrToken,                messageId: "unexpected",                fix(fixer) {                    /*                     * Expand the replacement range to include the surrounding                     * tokens to avoid conflicting with semi.                     * https://github.com/eslint/eslint/issues/7928                     */                    return new FixTracker(fixer, context.getSourceCode())                        .retainSurroundingTokens(nodeOrToken)                        .remove(nodeOrToken);                }            });        }        /**         * Checks for a part of a class body.         * This checks tokens from a specified token to a next MethodDefinition or the end of class body.         *         * @param {Token} firstToken - The first token to check.         * @returns {void}         */        function checkForPartOfClassBody(firstToken) {            for (let token = firstToken;                token.type === "Punctuator" && !astUtils.isClosingBraceToken(token);                token = sourceCode.getTokenAfter(token)            ) {                if (astUtils.isSemicolonToken(token)) {                    report(token);                }            }        }        return {            /**             * Reports this empty statement, except if the parent node is a loop.             * @param {Node} node - A EmptyStatement node to be reported.             * @returns {void}             */            EmptyStatement(node) {                const parent = node.parent,                    allowedParentTypes = [                        "ForStatement",                        "ForInStatement",                        "ForOfStatement",                        "WhileStatement",                        "DoWhileStatement",                        "IfStatement",                        "LabeledStatement",                        "WithStatement"                    ];                if (allowedParentTypes.indexOf(parent.type) === -1) {                    report(node);                }            },            /**             * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.             * @param {Node} node - A ClassBody node to check.             * @returns {void}             */            ClassBody(node) {                checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`.            },            /**             * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.             * @param {Node} node - A MethodDefinition node of the start point.             * @returns {void}             */            MethodDefinition(node) {                checkForPartOfClassBody(sourceCode.getTokenAfter(node));            }        };    }};
 |