UNPKG

3.45 kBJavaScriptView Raw
1/**
2 * @fileoverview Define utilify functions for token store.
3 * @author Toru Nagashima
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11const lodash = require("lodash");
12
13//------------------------------------------------------------------------------
14// Helpers
15//------------------------------------------------------------------------------
16
17/**
18 * Gets `token.range[0]` from the given token.
19 *
20 * @param {Node|Token|Comment} token - The token to get.
21 * @returns {number} The start location.
22 * @private
23 */
24function getStartLocation(token) {
25 return token.range[0];
26}
27
28//------------------------------------------------------------------------------
29// Exports
30//------------------------------------------------------------------------------
31
32/**
33 * Binary-searches the index of the first token which is after the given location.
34 * If it was not found, this returns `tokens.length`.
35 *
36 * @param {(Token|Comment)[]} tokens - It searches the token in this list.
37 * @param {number} location - The location to search.
38 * @returns {number} The found index or `tokens.length`.
39 */
40exports.search = function search(tokens, location) {
41 return lodash.sortedIndexBy(
42 tokens,
43 { range: [location] },
44 getStartLocation
45 );
46};
47
48/**
49 * Gets the index of the `startLoc` in `tokens`.
50 * `startLoc` can be the value of `node.range[1]`, so this checks about `startLoc - 1` as well.
51 *
52 * @param {(Token|Comment)[]} tokens - The tokens to find an index.
53 * @param {Object} indexMap - The map from locations to indices.
54 * @param {number} startLoc - The location to get an index.
55 * @returns {number} The index.
56 */
57exports.getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) {
58 if (startLoc in indexMap) {
59 return indexMap[startLoc];
60 }
61 if ((startLoc - 1) in indexMap) {
62 const index = indexMap[startLoc - 1];
63 const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
64
65 /*
66 * For the map of "comment's location -> token's index", it points the next token of a comment.
67 * In that case, +1 is unnecessary.
68 */
69 if (token && token.range[0] >= startLoc) {
70 return index;
71 }
72 return index + 1;
73 }
74 return 0;
75};
76
77/**
78 * Gets the index of the `endLoc` in `tokens`.
79 * The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well.
80 *
81 * @param {(Token|Comment)[]} tokens - The tokens to find an index.
82 * @param {Object} indexMap - The map from locations to indices.
83 * @param {number} endLoc - The location to get an index.
84 * @returns {number} The index.
85 */
86exports.getLastIndex = function getLastIndex(tokens, indexMap, endLoc) {
87 if (endLoc in indexMap) {
88 return indexMap[endLoc] - 1;
89 }
90 if ((endLoc - 1) in indexMap) {
91 const index = indexMap[endLoc - 1];
92 const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
93
94 /*
95 * For the map of "comment's location -> token's index", it points the next token of a comment.
96 * In that case, -1 is necessary.
97 */
98 if (token && token.range[1] > endLoc) {
99 return index - 1;
100 }
101 return index;
102 }
103 return tokens.length - 1;
104};