You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							126 lines
						
					
					
						
							4.1 KiB
						
					
					
				
			
		
		
	
	
							126 lines
						
					
					
						
							4.1 KiB
						
					
					
				/** | 
						|
 * @fileoverview Rule to flag use of unnecessary semicolons | 
						|
 * @author Nicholas C. Zakas | 
						|
 */ | 
						|
 | 
						|
"use strict"; | 
						|
 | 
						|
//------------------------------------------------------------------------------ | 
						|
// Requirements | 
						|
//------------------------------------------------------------------------------ | 
						|
 | 
						|
const FixTracker = require("./utils/fix-tracker"); | 
						|
const astUtils = require("./utils/ast-utils"); | 
						|
 | 
						|
//------------------------------------------------------------------------------ | 
						|
// Rule Definition | 
						|
//------------------------------------------------------------------------------ | 
						|
 | 
						|
module.exports = { | 
						|
    meta: { | 
						|
        type: "suggestion", | 
						|
 | 
						|
        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)); | 
						|
            } | 
						|
        }; | 
						|
 | 
						|
    } | 
						|
};
 | 
						|
 |