1 | /**
|
---|
2 | * @fileoverview Define utility functions for token store.
|
---|
3 | * @author Toru Nagashima
|
---|
4 | */
|
---|
5 | "use strict";
|
---|
6 |
|
---|
7 | //------------------------------------------------------------------------------
|
---|
8 | // Exports
|
---|
9 | //------------------------------------------------------------------------------
|
---|
10 |
|
---|
11 | /**
|
---|
12 | * Finds the index of the first token which is after the given location.
|
---|
13 | * If it was not found, this returns `tokens.length`.
|
---|
14 | * @param {(Token|Comment)[]} tokens It searches the token in this list.
|
---|
15 | * @param {number} location The location to search.
|
---|
16 | * @returns {number} The found index or `tokens.length`.
|
---|
17 | */
|
---|
18 | exports.search = function search(tokens, location) {
|
---|
19 | for (let minIndex = 0, maxIndex = tokens.length - 1; minIndex <= maxIndex;) {
|
---|
20 |
|
---|
21 | /*
|
---|
22 | * Calculate the index in the middle between minIndex and maxIndex.
|
---|
23 | * `| 0` is used to round a fractional value down to the nearest integer: this is similar to
|
---|
24 | * using `Math.trunc()` or `Math.floor()`, but performance tests have shown this method to
|
---|
25 | * be faster.
|
---|
26 | */
|
---|
27 | const index = (minIndex + maxIndex) / 2 | 0;
|
---|
28 | const token = tokens[index];
|
---|
29 | const tokenStartLocation = token.range[0];
|
---|
30 |
|
---|
31 | if (location <= tokenStartLocation) {
|
---|
32 | if (index === minIndex) {
|
---|
33 | return index;
|
---|
34 | }
|
---|
35 | maxIndex = index;
|
---|
36 | } else {
|
---|
37 | minIndex = index + 1;
|
---|
38 | }
|
---|
39 | }
|
---|
40 | return tokens.length;
|
---|
41 | };
|
---|
42 |
|
---|
43 | /**
|
---|
44 | * Gets the index of the `startLoc` in `tokens`.
|
---|
45 | * `startLoc` can be the value of `node.range[1]`, so this checks about `startLoc - 1` as well.
|
---|
46 | * @param {(Token|Comment)[]} tokens The tokens to find an index.
|
---|
47 | * @param {Object} indexMap The map from locations to indices.
|
---|
48 | * @param {number} startLoc The location to get an index.
|
---|
49 | * @returns {number} The index.
|
---|
50 | */
|
---|
51 | exports.getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) {
|
---|
52 | if (startLoc in indexMap) {
|
---|
53 | return indexMap[startLoc];
|
---|
54 | }
|
---|
55 | if ((startLoc - 1) in indexMap) {
|
---|
56 | const index = indexMap[startLoc - 1];
|
---|
57 | const token = tokens[index];
|
---|
58 |
|
---|
59 | // If the mapped index is out of bounds, the returned cursor index will point after the end of the tokens array.
|
---|
60 | if (!token) {
|
---|
61 | return tokens.length;
|
---|
62 | }
|
---|
63 |
|
---|
64 | /*
|
---|
65 | * For the map of "comment's location -> token's index", it points the next token of a comment.
|
---|
66 | * In that case, +1 is unnecessary.
|
---|
67 | */
|
---|
68 | if (token.range[0] >= startLoc) {
|
---|
69 | return index;
|
---|
70 | }
|
---|
71 | return index + 1;
|
---|
72 | }
|
---|
73 | return 0;
|
---|
74 | };
|
---|
75 |
|
---|
76 | /**
|
---|
77 | * Gets the index of the `endLoc` in `tokens`.
|
---|
78 | * The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well.
|
---|
79 | * @param {(Token|Comment)[]} tokens The tokens to find an index.
|
---|
80 | * @param {Object} indexMap The map from locations to indices.
|
---|
81 | * @param {number} endLoc The location to get an index.
|
---|
82 | * @returns {number} The index.
|
---|
83 | */
|
---|
84 | exports.getLastIndex = function getLastIndex(tokens, indexMap, endLoc) {
|
---|
85 | if (endLoc in indexMap) {
|
---|
86 | return indexMap[endLoc] - 1;
|
---|
87 | }
|
---|
88 | if ((endLoc - 1) in indexMap) {
|
---|
89 | const index = indexMap[endLoc - 1];
|
---|
90 | const token = tokens[index];
|
---|
91 |
|
---|
92 | // If the mapped index is out of bounds, the returned cursor index will point before the end of the tokens array.
|
---|
93 | if (!token) {
|
---|
94 | return tokens.length - 1;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /*
|
---|
98 | * For the map of "comment's location -> token's index", it points the next token of a comment.
|
---|
99 | * In that case, -1 is necessary.
|
---|
100 | */
|
---|
101 | if (token.range[1] > endLoc) {
|
---|
102 | return index - 1;
|
---|
103 | }
|
---|
104 | return index;
|
---|
105 | }
|
---|
106 | return tokens.length - 1;
|
---|
107 | };
|
---|