UNPKG

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