59ebb5e7f9741659fa0f80962e81bd0a1fdffd7a
[platform/framework/web/crosswalk-tizen.git] /
1 /**
2  * @fileoverview A rule to ensure blank lines within blocks.
3  * @author Mathias Schreck <https://github.com/lo1tuma>
4  * @copyright 2014 Mathias Schreck. All rights reserved.
5  */
6
7 "use strict";
8
9 //------------------------------------------------------------------------------
10 // Rule Definition
11 //------------------------------------------------------------------------------
12
13 module.exports = function (context) {
14     var requirePadding = context.options[0] !== "never";
15
16     /**
17      * Checks if the given non empty block node has a blank line before its first child node.
18      * @param {ASTNode} node The AST node of a BlockStatement.
19      * @returns {boolean} Whether or not the block starts with a blank line.
20      */
21     function isNonEmptyBlockTopPadded(node) {
22         var blockStart = node.loc.start.line,
23             first = node.body[0],
24             firstLine = first.loc.start.line,
25             expectedFirstLine = blockStart + 2,
26             leadingComments = context.getComments(first).leading;
27
28         if (leadingComments.length > 0) {
29             firstLine = leadingComments[0].loc.start.line;
30         }
31
32         return expectedFirstLine <= firstLine;
33     }
34
35     /**
36      * Checks if the given non empty block node has a blank line after its last child node.
37      * @param {ASTNode} node The AST node of a BlockStatement.
38      * @returns {boolean} Whether or not the block ends with a blank line.
39      */
40     function isNonEmptyBlockBottomPadded(node) {
41         var blockEnd = node.loc.end.line,
42             last = node.body[node.body.length - 1],
43             lastLine = last.loc.end.line,
44             expectedLastLine = blockEnd - 2,
45             trailingComments = context.getComments(last).trailing;
46
47         if (trailingComments.length > 0) {
48             lastLine = trailingComments[trailingComments.length - 1].loc.end.line;
49         }
50
51         return lastLine <= expectedLastLine;
52     }
53
54     /**
55      * Checks if the given non empty block node starts AND ends with a blank line.
56      * @param {ASTNode} node The AST node of a BlockStatement.
57      * @returns {boolean} Whether or not the block starts and ends with a blank line.
58      */
59     function isNonEmptyBlockPadded(node) {
60         return isNonEmptyBlockTopPadded(node) && isNonEmptyBlockBottomPadded(node);
61     }
62
63     /**
64      * Checks if the given non empty block node starts OR ends with a blank line.
65      * @param {ASTNode} node The AST node of a BlockStatement.
66      * @returns {boolean} Whether or not the block starts and ends with a blank line.
67      */
68     function hasNonEmptyBlockExtraPadding(node) {
69         return isNonEmptyBlockTopPadded(node) || isNonEmptyBlockBottomPadded(node);
70     }
71
72     /**
73      * Checks the given BlockStatement node to be padded if the block is not empty.
74      * @param {ASTNode} node The AST node of a BlockStatement.
75      * @returns {void} undefined.
76      */
77     function checkPadding(node) {
78         if (node.body.length > 0) {
79             if (requirePadding) {
80                 if (!isNonEmptyBlockPadded(node)) {
81                     context.report(node, "Block must be padded by blank lines.");
82                 }
83             } else {
84                 if (hasNonEmptyBlockExtraPadding(node)) {
85                     context.report(node, "Block must not be padded by blank lines.");
86                 }
87             }
88         }
89     }
90
91     return {
92         "BlockStatement": checkPadding
93     };
94
95 };