33926741e0b677ef3fa167b2f426ccd950c9f76b
[platform/framework/web/crosswalk-tizen.git] /
1 /**
2  * @fileoverview Rule to disallow whitespace before the semicolon
3  * @author Jonathan Kingston
4  * @copyright 2015 Mathias Schreck
5  * @copyright 2014 Jonathan Kingston
6  */
7
8 "use strict";
9
10 //------------------------------------------------------------------------------
11 // Rule Definition
12 //------------------------------------------------------------------------------
13
14 module.exports = function(context) {
15
16     /**
17      * Determines whether two adjacent tokens are have whitespace between them.
18      * @param {Object} left - The left token object.
19      * @param {Object} right - The right token object.
20      * @returns {boolean} Whether or not there is space between the tokens.
21      */
22     function isSpaced(left, right) {
23         return left.range[1] < right.range[0];
24     }
25
26     /**
27      * Checks whether two tokens are on the same line.
28      * @param {Object} left The leftmost token.
29      * @param {Object} right The rightmost token.
30      * @returns {boolean} True if the tokens are on the same line, false if not.
31      * @private
32      */
33     function isSameLine(left, right) {
34         return left.loc.end.line === right.loc.start.line;
35     }
36
37     /**
38      * Checks if a given token has leading whitespace.
39      * @param {Object} token The token to check.
40      * @returns {boolean} True if the given token has leading space, false if not.
41      */
42     function hasLeadingSpace(token) {
43         var tokenBefore = context.getTokenBefore(token);
44         return isSameLine(tokenBefore, token) && isSpaced(tokenBefore, token);
45     }
46
47     /**
48      * Checks if the given token is a semicolon.
49      * @param {Token} token The token to check.
50      * @returns {boolean} Whether or not the given token is a semicolon.
51      */
52     function isSemicolon(token) {
53         return token.type === "Punctuator" && token.value === ";";
54     }
55
56     /**
57      * Reports if the given token has leading space.
58      * @param {Token} token The semicolon token to check.
59      * @param {ASTNode} node The corresponding node of the token.
60      * @returns {void}
61      */
62     function checkSemiTokenForLeadingSpace(token, node) {
63         if (isSemicolon(token) && hasLeadingSpace(token)) {
64             context.report(node, token.loc.start, "Unexpected whitespace before semicolon.");
65         }
66     }
67
68     /**
69      * Checks leading space before the semicolon with the assumption that the last token is the semicolon.
70      * @param {ASTNode} node The node to check.
71      * @returns {void}
72      */
73     function checkNode(node) {
74         var token = context.getLastToken(node);
75         checkSemiTokenForLeadingSpace(token, node);
76     }
77
78     return {
79         "VariableDeclaration": checkNode,
80         "ExpressionStatement": checkNode,
81         "BreakStatement": checkNode,
82         "ContinueStatement": checkNode,
83         "DebuggerStatement": checkNode,
84         "ReturnStatement": checkNode,
85         "ThrowStatement": checkNode,
86         "ForStatement": function (node) {
87             if (node.init) {
88                 checkSemiTokenForLeadingSpace(context.getTokenAfter(node.init), node);
89             }
90
91             if (node.test) {
92                 checkSemiTokenForLeadingSpace(context.getTokenAfter(node.test), node);
93             }
94         }
95     };
96 };