eslint 3.15.0 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/conf/{eslint.json → eslint-recommended.js} +85 -71
- package/lib/ast-utils.js +185 -19
- package/lib/code-path-analysis/code-path-state.js +2 -2
- package/lib/config/autoconfig.js +3 -3
- package/lib/config/config-file.js +14 -7
- package/lib/config/config-initializer.js +1 -1
- package/lib/config.js +3 -2
- package/lib/eslint.js +4 -4
- package/lib/rules/arrow-body-style.js +7 -4
- package/lib/rules/arrow-spacing.js +7 -6
- package/lib/rules/block-spacing.js +2 -2
- package/lib/rules/brace-style.js +2 -6
- package/lib/rules/capitalized-comments.js +6 -6
- package/lib/rules/comma-spacing.js +3 -3
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/constructor-super.js +3 -3
- package/lib/rules/curly.js +11 -7
- package/lib/rules/default-case.js +3 -3
- package/lib/rules/eqeqeq.js +15 -6
- package/lib/rules/func-call-spacing.js +10 -13
- package/lib/rules/generator-star-spacing.js +18 -19
- package/lib/rules/id-blacklist.js +2 -2
- package/lib/rules/id-length.js +3 -3
- package/lib/rules/id-match.js +2 -2
- package/lib/rules/indent.js +7 -6
- package/lib/rules/key-spacing.js +12 -16
- package/lib/rules/keyword-spacing.js +2 -13
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +7 -1
- package/lib/rules/lines-around-comment.js +4 -4
- package/lib/rules/lines-around-directive.js +3 -3
- package/lib/rules/max-lines.js +2 -2
- package/lib/rules/max-statements-per-line.js +7 -6
- package/lib/rules/newline-after-var.js +7 -2
- package/lib/rules/newline-per-chained-call.js +3 -1
- package/lib/rules/no-cond-assign.js +3 -3
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-extra-bind.js +3 -4
- package/lib/rules/no-extra-boolean-cast.js +8 -0
- package/lib/rules/no-extra-parens.js +1 -2
- package/lib/rules/no-inner-declarations.js +4 -4
- package/lib/rules/no-irregular-whitespace.js +7 -1
- package/lib/rules/no-lone-blocks.js +10 -10
- package/lib/rules/no-mixed-operators.js +1 -7
- package/lib/rules/no-multi-spaces.js +4 -1
- package/lib/rules/no-multi-str.js +7 -3
- package/lib/rules/no-return-assign.js +7 -14
- package/lib/rules/no-sequences.js +7 -6
- package/lib/rules/no-trailing-spaces.js +8 -2
- package/lib/rules/no-undefined.js +45 -6
- package/lib/rules/no-unexpected-multiline.js +9 -8
- package/lib/rules/no-unneeded-ternary.js +5 -1
- package/lib/rules/no-unused-labels.js +17 -2
- package/lib/rules/no-unused-vars.js +2 -16
- package/lib/rules/no-useless-computed-key.js +8 -3
- package/lib/rules/no-useless-concat.js +10 -7
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-useless-return.js +1 -7
- package/lib/rules/no-var.js +1 -3
- package/lib/rules/no-whitespace-before-property.js +5 -16
- package/lib/rules/object-curly-newline.js +2 -2
- package/lib/rules/object-curly-spacing.js +7 -25
- package/lib/rules/object-property-newline.js +3 -3
- package/lib/rules/object-shorthand.js +2 -2
- package/lib/rules/operator-assignment.js +1 -1
- package/lib/rules/operator-linebreak.js +8 -10
- package/lib/rules/padded-blocks.js +4 -4
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quotes.js +10 -6
- package/lib/rules/semi-spacing.js +4 -0
- package/lib/rules/space-before-function-paren.js +8 -5
- package/lib/rules/spaced-comment.js +2 -2
- package/lib/rules/strict.js +2 -2
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/rules/wrap-iife.js +5 -5
- package/lib/rules/yoda.js +2 -7
- package/lib/testers/rule-tester.js +13 -6
- package/lib/token-store/backward-token-comment-cursor.js +57 -0
- package/lib/token-store/backward-token-cursor.js +56 -0
- package/lib/token-store/cursor.js +76 -0
- package/lib/token-store/cursors.js +92 -0
- package/lib/token-store/decorative-cursor.js +39 -0
- package/lib/token-store/filter-cursor.js +43 -0
- package/lib/token-store/forward-token-comment-cursor.js +57 -0
- package/lib/token-store/forward-token-cursor.js +61 -0
- package/lib/token-store/index.js +604 -0
- package/lib/token-store/limit-cursor.js +40 -0
- package/lib/token-store/padded-token-cursor.js +38 -0
- package/lib/token-store/skip-cursor.js +42 -0
- package/lib/token-store/utils.js +100 -0
- package/lib/util/source-code-fixer.js +35 -39
- package/lib/util/source-code.js +31 -15
- package/messages/extend-config-missing.txt +3 -0
- package/package.json +2 -2
- package/lib/token-store.js +0 -203
@@ -0,0 +1,604 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Object to handle access and retrieval of tokens.
|
3
|
+
* @author Brandon Mills
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const assert = require("assert");
|
12
|
+
const cursors = require("./cursors");
|
13
|
+
const ForwardTokenCursor = require("./forward-token-cursor");
|
14
|
+
const PaddedTokenCursor = require("./padded-token-cursor");
|
15
|
+
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
// Helpers
|
18
|
+
//------------------------------------------------------------------------------
|
19
|
+
|
20
|
+
const PUBLIC_METHODS = Object.freeze([
|
21
|
+
"getTokenByRangeStart",
|
22
|
+
|
23
|
+
"getFirstToken",
|
24
|
+
"getLastToken",
|
25
|
+
"getTokenBefore",
|
26
|
+
"getTokenAfter",
|
27
|
+
"getFirstTokenBetween",
|
28
|
+
"getLastTokenBetween",
|
29
|
+
|
30
|
+
"getFirstTokens",
|
31
|
+
"getLastTokens",
|
32
|
+
"getTokensBefore",
|
33
|
+
"getTokensAfter",
|
34
|
+
"getFirstTokensBetween",
|
35
|
+
"getLastTokensBetween",
|
36
|
+
|
37
|
+
"getTokens",
|
38
|
+
"getTokensBetween",
|
39
|
+
|
40
|
+
"getTokenOrCommentBefore",
|
41
|
+
"getTokenOrCommentAfter"
|
42
|
+
]);
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Creates the map from locations to indices in `tokens`.
|
46
|
+
*
|
47
|
+
* The first/last location of tokens is mapped to the index of the token.
|
48
|
+
* The first/last location of comments is mapped to the index of the next token of each comment.
|
49
|
+
*
|
50
|
+
* @param {Token[]} tokens - The array of tokens.
|
51
|
+
* @param {Comment[]} comments - The array of comments.
|
52
|
+
* @returns {Object} The map from locations to indices in `tokens`.
|
53
|
+
* @private
|
54
|
+
*/
|
55
|
+
function createIndexMap(tokens, comments) {
|
56
|
+
const map = Object.create(null);
|
57
|
+
let tokenIndex = 0;
|
58
|
+
let commentIndex = 0;
|
59
|
+
let nextStart = 0;
|
60
|
+
let range = null;
|
61
|
+
|
62
|
+
while (tokenIndex < tokens.length || commentIndex < comments.length) {
|
63
|
+
nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER;
|
64
|
+
while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) {
|
65
|
+
map[range[0]] = tokenIndex;
|
66
|
+
map[range[1] - 1] = tokenIndex;
|
67
|
+
tokenIndex += 1;
|
68
|
+
}
|
69
|
+
|
70
|
+
nextStart = (tokenIndex < tokens.length) ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER;
|
71
|
+
while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) {
|
72
|
+
map[range[0]] = tokenIndex;
|
73
|
+
map[range[1] - 1] = tokenIndex;
|
74
|
+
commentIndex += 1;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
return map;
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Creates the cursor iterates tokens with options.
|
83
|
+
*
|
84
|
+
* @param {CursorFactory} factory - The cursor factory to initialize cursor.
|
85
|
+
* @param {Token[]} tokens - The array of tokens.
|
86
|
+
* @param {Comment[]} comments - The array of comments.
|
87
|
+
* @param {Object} indexMap - The map from locations to indices in `tokens`.
|
88
|
+
* @param {number} startLoc - The start location of the iteration range.
|
89
|
+
* @param {number} endLoc - The end location of the iteration range.
|
90
|
+
* @param {number|Function|Object} [opts=0] - The option object. If this is a number then it's `opts.skip`. If this is a function then it's `opts.filter`.
|
91
|
+
* @param {boolean} [opts.includeComments=false] - The flag to iterate comments as well.
|
92
|
+
* @param {Function|null} [opts.filter=null] - The predicate function to choose tokens.
|
93
|
+
* @param {number} [opts.skip=0] - The count of tokens the cursor skips.
|
94
|
+
* @returns {Cursor} The created cursor.
|
95
|
+
* @private
|
96
|
+
*/
|
97
|
+
function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
|
98
|
+
let includeComments = false;
|
99
|
+
let skip = 0;
|
100
|
+
let filter = null;
|
101
|
+
|
102
|
+
if (typeof opts === "number") {
|
103
|
+
skip = opts | 0;
|
104
|
+
} else if (typeof opts === "function") {
|
105
|
+
filter = opts;
|
106
|
+
} else if (opts) {
|
107
|
+
includeComments = !!opts.includeComments;
|
108
|
+
skip = opts.skip | 0;
|
109
|
+
filter = opts.filter || null;
|
110
|
+
}
|
111
|
+
assert(skip >= 0, "options.skip should be zero or a positive integer.");
|
112
|
+
assert(!filter || typeof filter === "function", "options.filter should be a function.");
|
113
|
+
|
114
|
+
return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1);
|
115
|
+
}
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Creates the cursor iterates tokens with options.
|
119
|
+
*
|
120
|
+
* @param {CursorFactory} factory - The cursor factory to initialize cursor.
|
121
|
+
* @param {Token[]} tokens - The array of tokens.
|
122
|
+
* @param {Comment[]} comments - The array of comments.
|
123
|
+
* @param {Object} indexMap - The map from locations to indices in `tokens`.
|
124
|
+
* @param {number} startLoc - The start location of the iteration range.
|
125
|
+
* @param {number} endLoc - The end location of the iteration range.
|
126
|
+
* @param {number|Function|Object} [opts=0] - The option object. If this is a number then it's `opts.count`. If this is a function then it's `opts.filter`.
|
127
|
+
* @param {boolean} [opts.includeComments] - The flag to iterate comments as well.
|
128
|
+
* @param {Function|null} [opts.filter=null] - The predicate function to choose tokens.
|
129
|
+
* @param {number} [opts.count=0] - The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility.
|
130
|
+
* @returns {Cursor} The created cursor.
|
131
|
+
* @private
|
132
|
+
*/
|
133
|
+
function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
|
134
|
+
let includeComments = false;
|
135
|
+
let count = 0;
|
136
|
+
let countExists = false;
|
137
|
+
let filter = null;
|
138
|
+
|
139
|
+
if (typeof opts === "number") {
|
140
|
+
count = opts | 0;
|
141
|
+
countExists = true;
|
142
|
+
} else if (typeof opts === "function") {
|
143
|
+
filter = opts;
|
144
|
+
} else if (opts) {
|
145
|
+
includeComments = !!opts.includeComments;
|
146
|
+
count = opts.count | 0;
|
147
|
+
countExists = typeof opts.count === "number";
|
148
|
+
filter = opts.filter || null;
|
149
|
+
}
|
150
|
+
assert(count >= 0, "options.count should be zero or a positive integer.");
|
151
|
+
assert(!filter || typeof filter === "function", "options.filter should be a function.");
|
152
|
+
|
153
|
+
return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1);
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Creates the cursor iterates tokens with options.
|
158
|
+
* This is overload function of the below.
|
159
|
+
*
|
160
|
+
* @param {Token[]} tokens - The array of tokens.
|
161
|
+
* @param {Comment[]} comments - The array of comments.
|
162
|
+
* @param {Object} indexMap - The map from locations to indices in `tokens`.
|
163
|
+
* @param {number} startLoc - The start location of the iteration range.
|
164
|
+
* @param {number} endLoc - The end location of the iteration range.
|
165
|
+
* @param {Function|Object} opts - The option object. If this is a function then it's `opts.filter`.
|
166
|
+
* @param {boolean} [opts.includeComments] - The flag to iterate comments as well.
|
167
|
+
* @param {Function|null} [opts.filter=null] - The predicate function to choose tokens.
|
168
|
+
* @param {number} [opts.count=0] - The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility.
|
169
|
+
* @returns {Cursor} The created cursor.
|
170
|
+
* @private
|
171
|
+
*/
|
172
|
+
/**
|
173
|
+
* Creates the cursor iterates tokens with options.
|
174
|
+
*
|
175
|
+
* @param {Token[]} tokens - The array of tokens.
|
176
|
+
* @param {Comment[]} comments - The array of comments.
|
177
|
+
* @param {Object} indexMap - The map from locations to indices in `tokens`.
|
178
|
+
* @param {number} startLoc - The start location of the iteration range.
|
179
|
+
* @param {number} endLoc - The end location of the iteration range.
|
180
|
+
* @param {number} [beforeCount=0] - The number of tokens before the node to retrieve.
|
181
|
+
* @param {boolean} [afterCount=0] - The number of tokens after the node to retrieve.
|
182
|
+
* @returns {Cursor} The created cursor.
|
183
|
+
* @private
|
184
|
+
*/
|
185
|
+
function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) {
|
186
|
+
if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") {
|
187
|
+
return new ForwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc);
|
188
|
+
}
|
189
|
+
if (typeof beforeCount === "number" || typeof beforeCount === "undefined") {
|
190
|
+
return new PaddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount | 0, afterCount | 0);
|
191
|
+
}
|
192
|
+
return createCursorWithCount(cursors.forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount);
|
193
|
+
}
|
194
|
+
|
195
|
+
//------------------------------------------------------------------------------
|
196
|
+
// Exports
|
197
|
+
//------------------------------------------------------------------------------
|
198
|
+
|
199
|
+
/**
|
200
|
+
* The token store.
|
201
|
+
*
|
202
|
+
* This class provides methods to get tokens by locations as fast as possible.
|
203
|
+
* The methods are a part of public API, so we should be careful if it changes this class.
|
204
|
+
*
|
205
|
+
* People can get tokens in O(1) by the hash map which is mapping from the location of tokens/comments to tokens.
|
206
|
+
* Also people can get a mix of tokens and comments in O(log k), the k is the number of comments.
|
207
|
+
* Assuming that comments to be much fewer than tokens, this does not make hash map from token's locations to comments to reduce memory cost.
|
208
|
+
* This uses binary-searching instead for comments.
|
209
|
+
*/
|
210
|
+
module.exports = class TokenStore {
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Initializes this token store.
|
214
|
+
*
|
215
|
+
* ※ `comments` needs to be cloned for backward compatibility.
|
216
|
+
* After this initialization, ESLint removes a shebang's comment from `comments`.
|
217
|
+
* However, so far we had been concatenating 'tokens' and 'comments' before,
|
218
|
+
* so the shebang's comment had remained in the concatenated array.
|
219
|
+
* As a result, both the result of `getTokenOrCommentAfter` and `getTokenOrCommentBefore`
|
220
|
+
* methods had included the shebang's comment.
|
221
|
+
* And some rules depends on this behavior.
|
222
|
+
*
|
223
|
+
* @param {Token[]} tokens - The array of tokens.
|
224
|
+
* @param {Comment[]} comments - The array of comments.
|
225
|
+
*/
|
226
|
+
constructor(tokens, comments) {
|
227
|
+
this.tokens = tokens;
|
228
|
+
this.comments = comments.slice(0);
|
229
|
+
this.indexMap = createIndexMap(tokens, comments);
|
230
|
+
}
|
231
|
+
|
232
|
+
//--------------------------------------------------------------------------
|
233
|
+
// Gets single token.
|
234
|
+
//--------------------------------------------------------------------------
|
235
|
+
|
236
|
+
/**
|
237
|
+
* Gets the token starting at the specified index.
|
238
|
+
* @param {number} offset - Index of the start of the token's range.
|
239
|
+
* @param {Object} [options=0] - The option object.
|
240
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
241
|
+
* @returns {Token|null} The token starting at index, or null if no such token.
|
242
|
+
*/
|
243
|
+
getTokenByRangeStart(offset, options) {
|
244
|
+
const includeComments = options && options.includeComments;
|
245
|
+
const token = cursors.forward.createBaseCursor(
|
246
|
+
this.tokens,
|
247
|
+
this.comments,
|
248
|
+
this.indexMap,
|
249
|
+
offset,
|
250
|
+
-1,
|
251
|
+
includeComments
|
252
|
+
).getOneToken();
|
253
|
+
|
254
|
+
if (token && token.range[0] === offset) {
|
255
|
+
return token;
|
256
|
+
}
|
257
|
+
return null;
|
258
|
+
}
|
259
|
+
|
260
|
+
/**
|
261
|
+
* Gets the first token of the given node.
|
262
|
+
* @param {ASTNode} node - The AST node.
|
263
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
264
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
265
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
266
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
267
|
+
* @returns {Token|null} An object representing the token.
|
268
|
+
*/
|
269
|
+
getFirstToken(node, options) {
|
270
|
+
return createCursorWithSkip(
|
271
|
+
cursors.forward,
|
272
|
+
this.tokens,
|
273
|
+
this.comments,
|
274
|
+
this.indexMap,
|
275
|
+
node.range[0],
|
276
|
+
node.range[1],
|
277
|
+
options
|
278
|
+
).getOneToken();
|
279
|
+
}
|
280
|
+
|
281
|
+
/**
|
282
|
+
* Gets the last token of the given node.
|
283
|
+
* @param {ASTNode} node - The AST node.
|
284
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
285
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
286
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
287
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
288
|
+
* @returns {Token|null} An object representing the token.
|
289
|
+
*/
|
290
|
+
getLastToken(node, options) {
|
291
|
+
return createCursorWithSkip(
|
292
|
+
cursors.backward,
|
293
|
+
this.tokens,
|
294
|
+
this.comments,
|
295
|
+
this.indexMap,
|
296
|
+
node.range[0],
|
297
|
+
node.range[1],
|
298
|
+
options
|
299
|
+
).getOneToken();
|
300
|
+
}
|
301
|
+
|
302
|
+
/**
|
303
|
+
* Gets the token that precedes a given node or token.
|
304
|
+
* @param {ASTNode|Token|Comment} node - The AST node or token.
|
305
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
306
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
307
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
308
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
309
|
+
* @returns {Token|null} An object representing the token.
|
310
|
+
*/
|
311
|
+
getTokenBefore(node, options) {
|
312
|
+
return createCursorWithSkip(
|
313
|
+
cursors.backward,
|
314
|
+
this.tokens,
|
315
|
+
this.comments,
|
316
|
+
this.indexMap,
|
317
|
+
-1,
|
318
|
+
node.range[0],
|
319
|
+
options
|
320
|
+
).getOneToken();
|
321
|
+
}
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Gets the token that follows a given node or token.
|
325
|
+
* @param {ASTNode|Token|Comment} node - The AST node or token.
|
326
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
327
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
328
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
329
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
330
|
+
* @returns {Token|null} An object representing the token.
|
331
|
+
*/
|
332
|
+
getTokenAfter(node, options) {
|
333
|
+
return createCursorWithSkip(
|
334
|
+
cursors.forward,
|
335
|
+
this.tokens,
|
336
|
+
this.comments,
|
337
|
+
this.indexMap,
|
338
|
+
node.range[1],
|
339
|
+
-1,
|
340
|
+
options
|
341
|
+
).getOneToken();
|
342
|
+
}
|
343
|
+
|
344
|
+
/**
|
345
|
+
* Gets the first token between two non-overlapping nodes.
|
346
|
+
* @param {ASTNode|Token|Comment} left - Node before the desired token range.
|
347
|
+
* @param {ASTNode|Token|Comment} right - Node after the desired token range.
|
348
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
349
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
350
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
351
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
352
|
+
* @returns {Token|null} An object representing the token.
|
353
|
+
*/
|
354
|
+
getFirstTokenBetween(left, right, options) {
|
355
|
+
return createCursorWithSkip(
|
356
|
+
cursors.forward,
|
357
|
+
this.tokens,
|
358
|
+
this.comments,
|
359
|
+
this.indexMap,
|
360
|
+
left.range[1],
|
361
|
+
right.range[0],
|
362
|
+
options
|
363
|
+
).getOneToken();
|
364
|
+
}
|
365
|
+
|
366
|
+
/**
|
367
|
+
* Gets the last token between two non-overlapping nodes.
|
368
|
+
* @param {ASTNode|Token|Comment} left Node before the desired token range.
|
369
|
+
* @param {ASTNode|Token|Comment} right Node after the desired token range.
|
370
|
+
* @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`.
|
371
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
372
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
373
|
+
* @param {number} [options.skip=0] - The count of tokens the cursor skips.
|
374
|
+
* @returns {Token|null} Tokens between left and right.
|
375
|
+
*/
|
376
|
+
getLastTokenBetween(left, right, options) {
|
377
|
+
return createCursorWithSkip(
|
378
|
+
cursors.backward,
|
379
|
+
this.tokens,
|
380
|
+
this.comments,
|
381
|
+
this.indexMap,
|
382
|
+
left.range[1],
|
383
|
+
right.range[0],
|
384
|
+
options
|
385
|
+
).getOneToken();
|
386
|
+
}
|
387
|
+
|
388
|
+
/**
|
389
|
+
* Gets the token that precedes a given node or token in the token stream.
|
390
|
+
* This is defined for backward compatibility. Use `includeComments` option instead.
|
391
|
+
* TODO: We have a plan to remove this in a future major version.
|
392
|
+
* @param {ASTNode|Token|Comment} node The AST node or token.
|
393
|
+
* @param {number} [skip=0] A number of tokens to skip.
|
394
|
+
* @returns {Token|null} An object representing the token.
|
395
|
+
* @deprecated
|
396
|
+
*/
|
397
|
+
getTokenOrCommentBefore(node, skip) {
|
398
|
+
return this.getTokenBefore(node, { includeComments: true, skip });
|
399
|
+
}
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Gets the token that follows a given node or token in the token stream.
|
403
|
+
* This is defined for backward compatibility. Use `includeComments` option instead.
|
404
|
+
* TODO: We have a plan to remove this in a future major version.
|
405
|
+
* @param {ASTNode|Token|Comment} node The AST node or token.
|
406
|
+
* @param {number} [skip=0] A number of tokens to skip.
|
407
|
+
* @returns {Token|null} An object representing the token.
|
408
|
+
* @deprecated
|
409
|
+
*/
|
410
|
+
getTokenOrCommentAfter(node, skip) {
|
411
|
+
return this.getTokenAfter(node, { includeComments: true, skip });
|
412
|
+
}
|
413
|
+
|
414
|
+
//--------------------------------------------------------------------------
|
415
|
+
// Gets multiple tokens.
|
416
|
+
//--------------------------------------------------------------------------
|
417
|
+
|
418
|
+
/**
|
419
|
+
* Gets the first `count` tokens of the given node.
|
420
|
+
* @param {ASTNode} node - The AST node.
|
421
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
422
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
423
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
424
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
425
|
+
* @returns {Token[]} Tokens.
|
426
|
+
*/
|
427
|
+
getFirstTokens(node, options) {
|
428
|
+
return createCursorWithCount(
|
429
|
+
cursors.forward,
|
430
|
+
this.tokens,
|
431
|
+
this.comments,
|
432
|
+
this.indexMap,
|
433
|
+
node.range[0],
|
434
|
+
node.range[1],
|
435
|
+
options
|
436
|
+
).getAllTokens();
|
437
|
+
}
|
438
|
+
|
439
|
+
/**
|
440
|
+
* Gets the last `count` tokens of the given node.
|
441
|
+
* @param {ASTNode} node - The AST node.
|
442
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
443
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
444
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
445
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
446
|
+
* @returns {Token[]} Tokens.
|
447
|
+
*/
|
448
|
+
getLastTokens(node, options) {
|
449
|
+
return createCursorWithCount(
|
450
|
+
cursors.backward,
|
451
|
+
this.tokens,
|
452
|
+
this.comments,
|
453
|
+
this.indexMap,
|
454
|
+
node.range[0],
|
455
|
+
node.range[1],
|
456
|
+
options
|
457
|
+
).getAllTokens().reverse();
|
458
|
+
}
|
459
|
+
|
460
|
+
/**
|
461
|
+
* Gets the `count` tokens that precedes a given node or token.
|
462
|
+
* @param {ASTNode|Token|Comment} node - The AST node or token.
|
463
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
464
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
465
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
466
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
467
|
+
* @returns {Token[]} Tokens.
|
468
|
+
*/
|
469
|
+
getTokensBefore(node, options) {
|
470
|
+
return createCursorWithCount(
|
471
|
+
cursors.backward,
|
472
|
+
this.tokens,
|
473
|
+
this.comments,
|
474
|
+
this.indexMap,
|
475
|
+
-1,
|
476
|
+
node.range[0],
|
477
|
+
options
|
478
|
+
).getAllTokens().reverse();
|
479
|
+
}
|
480
|
+
|
481
|
+
/**
|
482
|
+
* Gets the `count` tokens that follows a given node or token.
|
483
|
+
* @param {ASTNode|Token|Comment} node - The AST node or token.
|
484
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
485
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
486
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
487
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
488
|
+
* @returns {Token[]} Tokens.
|
489
|
+
*/
|
490
|
+
getTokensAfter(node, options) {
|
491
|
+
return createCursorWithCount(
|
492
|
+
cursors.forward,
|
493
|
+
this.tokens,
|
494
|
+
this.comments,
|
495
|
+
this.indexMap,
|
496
|
+
node.range[1],
|
497
|
+
-1,
|
498
|
+
options
|
499
|
+
).getAllTokens();
|
500
|
+
}
|
501
|
+
|
502
|
+
/**
|
503
|
+
* Gets the first `count` tokens between two non-overlapping nodes.
|
504
|
+
* @param {ASTNode|Token|Comment} left - Node before the desired token range.
|
505
|
+
* @param {ASTNode|Token|Comment} right - Node after the desired token range.
|
506
|
+
* @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
507
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
508
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
509
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
510
|
+
* @returns {Token[]} Tokens between left and right.
|
511
|
+
*/
|
512
|
+
getFirstTokensBetween(left, right, options) {
|
513
|
+
return createCursorWithCount(
|
514
|
+
cursors.forward,
|
515
|
+
this.tokens,
|
516
|
+
this.comments,
|
517
|
+
this.indexMap,
|
518
|
+
left.range[1],
|
519
|
+
right.range[0],
|
520
|
+
options
|
521
|
+
).getAllTokens();
|
522
|
+
}
|
523
|
+
|
524
|
+
/**
|
525
|
+
* Gets the last `count` tokens between two non-overlapping nodes.
|
526
|
+
* @param {ASTNode|Token|Comment} left Node before the desired token range.
|
527
|
+
* @param {ASTNode|Token|Comment} right Node after the desired token range.
|
528
|
+
* @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`.
|
529
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
530
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
531
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
532
|
+
* @returns {Token[]} Tokens between left and right.
|
533
|
+
*/
|
534
|
+
getLastTokensBetween(left, right, options) {
|
535
|
+
return createCursorWithCount(
|
536
|
+
cursors.backward,
|
537
|
+
this.tokens,
|
538
|
+
this.comments,
|
539
|
+
this.indexMap,
|
540
|
+
left.range[1],
|
541
|
+
right.range[0],
|
542
|
+
options
|
543
|
+
).getAllTokens().reverse();
|
544
|
+
}
|
545
|
+
|
546
|
+
/**
|
547
|
+
* Gets all tokens that are related to the given node.
|
548
|
+
* @param {ASTNode} node - The AST node.
|
549
|
+
* @param {Function|Object} options The option object. If this is a function then it's `options.filter`.
|
550
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
551
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
552
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
553
|
+
* @returns {Token[]} Array of objects representing tokens.
|
554
|
+
*/
|
555
|
+
/**
|
556
|
+
* Gets all tokens that are related to the given node.
|
557
|
+
* @param {ASTNode} node - The AST node.
|
558
|
+
* @param {int} [beforeCount=0] - The number of tokens before the node to retrieve.
|
559
|
+
* @param {int} [afterCount=0] - The number of tokens after the node to retrieve.
|
560
|
+
* @returns {Token[]} Array of objects representing tokens.
|
561
|
+
*/
|
562
|
+
getTokens(node, beforeCount, afterCount) {
|
563
|
+
return createCursorWithPadding(
|
564
|
+
this.tokens,
|
565
|
+
this.comments,
|
566
|
+
this.indexMap,
|
567
|
+
node.range[0],
|
568
|
+
node.range[1],
|
569
|
+
beforeCount,
|
570
|
+
afterCount
|
571
|
+
).getAllTokens();
|
572
|
+
}
|
573
|
+
|
574
|
+
/**
|
575
|
+
* Gets all of the tokens between two non-overlapping nodes.
|
576
|
+
* @param {ASTNode|Token|Comment} left Node before the desired token range.
|
577
|
+
* @param {ASTNode|Token|Comment} right Node after the desired token range.
|
578
|
+
* @param {Function|Object} options The option object. If this is a function then it's `options.filter`.
|
579
|
+
* @param {boolean} [options.includeComments=false] - The flag to iterate comments as well.
|
580
|
+
* @param {Function|null} [options.filter=null] - The predicate function to choose tokens.
|
581
|
+
* @param {number} [options.count=0] - The maximum count of tokens the cursor iterates.
|
582
|
+
* @returns {Token[]} Tokens between left and right.
|
583
|
+
*/
|
584
|
+
/**
|
585
|
+
* Gets all of the tokens between two non-overlapping nodes.
|
586
|
+
* @param {ASTNode|Token|Comment} left Node before the desired token range.
|
587
|
+
* @param {ASTNode|Token|Comment} right Node after the desired token range.
|
588
|
+
* @param {int} [padding=0] Number of extra tokens on either side of center.
|
589
|
+
* @returns {Token[]} Tokens between left and right.
|
590
|
+
*/
|
591
|
+
getTokensBetween(left, right, padding) {
|
592
|
+
return createCursorWithPadding(
|
593
|
+
this.tokens,
|
594
|
+
this.comments,
|
595
|
+
this.indexMap,
|
596
|
+
left.range[1],
|
597
|
+
right.range[0],
|
598
|
+
padding,
|
599
|
+
padding
|
600
|
+
).getAllTokens();
|
601
|
+
}
|
602
|
+
};
|
603
|
+
|
604
|
+
module.exports.PUBLIC_METHODS = PUBLIC_METHODS;
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Define the cursor which limits the number of tokens.
|
3
|
+
* @author Toru Nagashima
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const DecorativeCursor = require("./decorative-cursor");
|
12
|
+
|
13
|
+
//------------------------------------------------------------------------------
|
14
|
+
// Exports
|
15
|
+
//------------------------------------------------------------------------------
|
16
|
+
|
17
|
+
/**
|
18
|
+
* The decorative cursor which limits the number of tokens.
|
19
|
+
*/
|
20
|
+
module.exports = class LimitCursor extends DecorativeCursor {
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Initializes this cursor.
|
24
|
+
* @param {Cursor} cursor - The cursor to be decorated.
|
25
|
+
* @param {number} count - The count of tokens this cursor iterates.
|
26
|
+
*/
|
27
|
+
constructor(cursor, count) {
|
28
|
+
super(cursor);
|
29
|
+
this.count = count;
|
30
|
+
}
|
31
|
+
|
32
|
+
/** @inheritdoc */
|
33
|
+
moveNext() {
|
34
|
+
if (this.count > 0) {
|
35
|
+
this.count -= 1;
|
36
|
+
return super.moveNext();
|
37
|
+
}
|
38
|
+
return false;
|
39
|
+
}
|
40
|
+
};
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Define the cursor which iterates tokens only, with inflated range.
|
3
|
+
* @author Toru Nagashima
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const ForwardTokenCursor = require("./forward-token-cursor");
|
12
|
+
|
13
|
+
//------------------------------------------------------------------------------
|
14
|
+
// Exports
|
15
|
+
//------------------------------------------------------------------------------
|
16
|
+
|
17
|
+
/**
|
18
|
+
* The cursor which iterates tokens only, with inflated range.
|
19
|
+
* This is for the backward compatibility of padding options.
|
20
|
+
*/
|
21
|
+
module.exports = class PaddedTokenCursor extends ForwardTokenCursor {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Initializes this cursor.
|
25
|
+
* @param {Token[]} tokens - The array of tokens.
|
26
|
+
* @param {Comment[]} comments - The array of comments.
|
27
|
+
* @param {Object} indexMap - The map from locations to indices in `tokens`.
|
28
|
+
* @param {number} startLoc - The start location of the iteration range.
|
29
|
+
* @param {number} endLoc - The end location of the iteration range.
|
30
|
+
* @param {number} beforeCount - The number of tokens this cursor iterates before start.
|
31
|
+
* @param {number} afterCount - The number of tokens this cursor iterates after end.
|
32
|
+
*/
|
33
|
+
constructor(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) {
|
34
|
+
super(tokens, comments, indexMap, startLoc, endLoc);
|
35
|
+
this.index = Math.max(0, this.index - beforeCount);
|
36
|
+
this.indexEnd = Math.min(tokens.length - 1, this.indexEnd + afterCount);
|
37
|
+
}
|
38
|
+
};
|