[d565449] | 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 | };
|
---|