9e247c1533d11a6f5576ffaf1a67446ed8570673
[platform/framework/web/crosswalk-tizen.git] /
1 /**
2  * @fileoverview Disallow use of multiple spaces.
3  * @author Nicholas C. Zakas
4  * @copyright 2015 Brandon Mills. All rights reserved.
5  * @copyright 2015 Nicholas C. Zakas. All rights reserved.
6  */
7
8 "use strict";
9
10 //------------------------------------------------------------------------------
11 // Rule Definition
12 //------------------------------------------------------------------------------
13
14 module.exports = function(context) {
15
16     // the index of the last comment that was checked
17     var exceptions = { "Property": true },
18         hasExceptions = true,
19         options = context.options[0],
20         lastCommentIndex = 0;
21
22     if (options && options.exceptions) {
23         Object.keys(options.exceptions).forEach(function (key) {
24             if (options.exceptions[key]) {
25                 exceptions[key] = true;
26             } else {
27                 delete exceptions[key];
28             }
29         });
30         hasExceptions = Object.keys(exceptions).length > 0;
31     }
32
33     /**
34      * Determines if a given source index is in a comment or not by checking
35      * the index against the comment range. Since the check goes straight
36      * through the file, once an index is passed a certain comment, we can
37      * go to the next comment to check that.
38      * @param {int} index The source index to check.
39      * @param {ASTNode[]} comments An array of comment nodes.
40      * @returns {boolean} True if the index is within a comment, false if not.
41      * @private
42      */
43     function isIndexInComment(index, comments) {
44
45         var comment;
46
47         while (lastCommentIndex < comments.length) {
48
49             comment = comments[lastCommentIndex];
50
51             if (comment.range[0] <= index && index < comment.range[1]) {
52                 return true;
53             } else if (index > comment.range[1]) {
54                 lastCommentIndex++;
55             } else {
56                 break;
57             }
58
59         }
60
61         return false;
62     }
63
64     //--------------------------------------------------------------------------
65     // Public
66     //--------------------------------------------------------------------------
67
68     return {
69         "Program": function() {
70
71             var source = context.getSource(),
72                 allComments = context.getAllComments(),
73                 pattern = /[^\n\r\u2028\u2029 ] {2,}/g,  // note: repeating space
74                 token,
75                 parent;
76
77             while (pattern.test(source)) {
78
79                 // do not flag anything inside of comments
80                 if (!isIndexInComment(pattern.lastIndex, allComments)) {
81
82                     token = context.getTokenByRangeStart(pattern.lastIndex);
83
84                     if (token) {
85                         if (hasExceptions) {
86                             parent = context.getNodeByRangeIndex(pattern.lastIndex - 1);
87                         }
88
89                         if (!parent || !exceptions[parent.type]) {
90                             context.report(token, token.loc.start,
91                                 "Multiple spaces found before '{{value}}'.",
92                                 { value: token.value });
93                         }
94                     }
95
96                 }
97             }
98         }
99     };
100
101 };