1 | var assign = require('lodash').assign;
|
2 |
|
3 | var BLOCK_REGEXP = /^\s*(?:jscs\s*:\s*(en|dis)able)(.*)/;
|
4 | var LINE_REGEXP = /^\s*(?:jscs\s*:\s*ignore)(.*)/;
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | function parseRuleNames(text, enabled) {
|
14 | text = text.trim();
|
15 |
|
16 | if (!text) {
|
17 | return {'*': enabled};
|
18 | }
|
19 |
|
20 | return text.split(',').reduce(function(result, ruleName) {
|
21 | ruleName = ruleName.trim();
|
22 | if (ruleName) {
|
23 | result[ruleName] = enabled;
|
24 | }
|
25 | return result;
|
26 | }, {});
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | function TokenIndex(firstToken) {
|
37 | this._buildIndex(firstToken);
|
38 | }
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | TokenIndex.prototype._buildIndex = function(firstToken) {
|
47 | this._hasPragmas = false;
|
48 |
|
49 | var tokens = [];
|
50 | var index = [];
|
51 | var positions = [];
|
52 | var currentPosition = 0;
|
53 | var currentToken = firstToken;
|
54 | var lastBlockState = {'*': true};
|
55 | var tokenState;
|
56 | var previousLoc = {line: 1, column: 0};
|
57 |
|
58 | while (currentToken) {
|
59 | tokens.push(currentToken);
|
60 | currentToken.__loc = previousLoc;
|
61 |
|
62 | var newlineCount = currentToken.getNewlineCount();
|
63 | if (newlineCount > 0) {
|
64 | var lines = currentToken.getSourceCodeLines();
|
65 | previousLoc = {
|
66 | line: previousLoc.line + newlineCount,
|
67 | column: lines[lines.length - 1].length
|
68 | };
|
69 | } else {
|
70 | previousLoc = {
|
71 | line: previousLoc.line,
|
72 | column: previousLoc.column + currentToken.getSourceCodeLength()
|
73 | };
|
74 | }
|
75 |
|
76 | if (currentToken.isComment) {
|
77 | var value = currentToken.value;
|
78 | var blockMatch = BLOCK_REGEXP.exec(value);
|
79 | if (blockMatch) {
|
80 | this._hasPragmas = true;
|
81 | lastBlockState = assign({}, lastBlockState, parseRuleNames(blockMatch[2], blockMatch[1] === 'en'));
|
82 | tokenState = lastBlockState;
|
83 | } else {
|
84 | var lineMatch = LINE_REGEXP.exec(value);
|
85 | if (lineMatch) {
|
86 | this._hasPragmas = true;
|
87 | var ignoreState = parseRuleNames(lineMatch[1], false);
|
88 | index.push(null);
|
89 | var ignoreToken = currentToken.getPreviousToken();
|
90 | var i = index.length - 1;
|
91 | while (ignoreToken) {
|
92 | i--;
|
93 | index[i] = assign({}, index[i], ignoreState);
|
94 | if (ignoreToken.getNewlineCount() > 0) {
|
95 | break;
|
96 | }
|
97 | ignoreToken = ignoreToken.getPreviousToken();
|
98 | }
|
99 | ignoreToken = currentToken.getNextToken();
|
100 | while (ignoreToken) {
|
101 | index.push(ignoreState);
|
102 | if (ignoreToken.getNewlineCount() > 0) {
|
103 | break;
|
104 | }
|
105 | ignoreToken = ignoreToken.getNextToken();
|
106 | }
|
107 | tokenState = assign({}, lastBlockState, ignoreState);
|
108 | } else {
|
109 | tokenState = lastBlockState;
|
110 | }
|
111 | }
|
112 | } else {
|
113 | tokenState = lastBlockState;
|
114 | }
|
115 |
|
116 | if (index[currentPosition]) {
|
117 | tokenState = assign({}, tokenState, index[currentPosition]);
|
118 | }
|
119 |
|
120 | index[currentPosition] = tokenState;
|
121 | currentPosition++;
|
122 |
|
123 | currentToken = currentToken.getNextToken();
|
124 | }
|
125 | this._tokens = tokens;
|
126 | this._index = index;
|
127 | this._positions = positions;
|
128 | };
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | TokenIndex.prototype.isRuleEnabled = function(ruleName, element) {
|
138 | if (!this._hasPragmas) {
|
139 | return true;
|
140 | }
|
141 | var pos = this._tokens.indexOf(element.getFirstToken());
|
142 | if (pos !== -1) {
|
143 | var state = this._index[pos];
|
144 | if (ruleName in state) {
|
145 | return state[ruleName];
|
146 | }
|
147 |
|
148 | return state['*'];
|
149 | }
|
150 |
|
151 | return true;
|
152 | };
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 | TokenIndex.prototype.getElementLoc = function(element) {
|
161 | return element.getFirstToken().__loc || {
|
162 | line: 1,
|
163 | column: 0
|
164 | };
|
165 | };
|
166 |
|
167 | module.exports = TokenIndex;
|
168 |
|