Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. /**
  2. * @fileoverview Object to handle access and retrieval of tokens.
  3. * @author Brandon Mills
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const assert = require("assert");
  10. const { isCommentToken } = require("eslint-utils");
  11. const cursors = require("./cursors");
  12. const ForwardTokenCursor = require("./forward-token-cursor");
  13. const PaddedTokenCursor = require("./padded-token-cursor");
  14. const utils = require("./utils");
  15. //------------------------------------------------------------------------------
  16. // Helpers
  17. //------------------------------------------------------------------------------
  18. const TOKENS = Symbol("tokens");
  19. const COMMENTS = Symbol("comments");
  20. const INDEX_MAP = Symbol("indexMap");
  21. /**
  22. * Creates the map from locations to indices in `tokens`.
  23. *
  24. * The first/last location of tokens is mapped to the index of the token.
  25. * The first/last location of comments is mapped to the index of the next token of each comment.
  26. * @param {Token[]} tokens The array of tokens.
  27. * @param {Comment[]} comments The array of comments.
  28. * @returns {Object} The map from locations to indices in `tokens`.
  29. * @private
  30. */
  31. function createIndexMap(tokens, comments) {
  32. const map = Object.create(null);
  33. let tokenIndex = 0;
  34. let commentIndex = 0;
  35. let nextStart = 0;
  36. let range = null;
  37. while (tokenIndex < tokens.length || commentIndex < comments.length) {
  38. nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER;
  39. while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) {
  40. map[range[0]] = tokenIndex;
  41. map[range[1] - 1] = tokenIndex;
  42. tokenIndex += 1;
  43. }
  44. nextStart = (tokenIndex < tokens.length) ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER;
  45. while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) {
  46. map[range[0]] = tokenIndex;
  47. map[range[1] - 1] = tokenIndex;
  48. commentIndex += 1;
  49. }
  50. }
  51. return map;
  52. }
  53. /**
  54. * Creates the cursor iterates tokens with options.
  55. * @param {CursorFactory} factory The cursor factory to initialize cursor.
  56. * @param {Token[]} tokens The array of tokens.
  57. * @param {Comment[]} comments The array of comments.
  58. * @param {Object} indexMap The map from locations to indices in `tokens`.
  59. * @param {number} startLoc The start location of the iteration range.
  60. * @param {number} endLoc The end location of the iteration range.
  61. * @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`.
  62. * @param {boolean} [opts.includeComments=false] The flag to iterate comments as well.
  63. * @param {Function|null} [opts.filter=null] The predicate function to choose tokens.
  64. * @param {number} [opts.skip=0] The count of tokens the cursor skips.
  65. * @returns {Cursor} The created cursor.
  66. * @private
  67. */
  68. function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
  69. let includeComments = false;
  70. let skip = 0;
  71. let filter = null;
  72. if (typeof opts === "number") {
  73. skip = opts | 0;
  74. } else if (typeof opts === "function") {
  75. filter = opts;
  76. } else if (opts) {
  77. includeComments = !!opts.includeComments;
  78. skip = opts.skip | 0;
  79. filter = opts.filter || null;
  80. }
  81. assert(skip >= 0, "options.skip should be zero or a positive integer.");
  82. assert(!filter || typeof filter === "function", "options.filter should be a function.");
  83. return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1);
  84. }
  85. /**
  86. * Creates the cursor iterates tokens with options.
  87. * @param {CursorFactory} factory The cursor factory to initialize cursor.
  88. * @param {Token[]} tokens The array of tokens.
  89. * @param {Comment[]} comments The array of comments.
  90. * @param {Object} indexMap The map from locations to indices in `tokens`.
  91. * @param {number} startLoc The start location of the iteration range.
  92. * @param {number} endLoc The end location of the iteration range.
  93. * @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`.
  94. * @param {boolean} [opts.includeComments] The flag to iterate comments as well.
  95. * @param {Function|null} [opts.filter=null] The predicate function to choose tokens.
  96. * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility.
  97. * @returns {Cursor} The created cursor.
  98. * @private
  99. */
  100. function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) {
  101. let includeComments = false;
  102. let count = 0;
  103. let countExists = false;
  104. let filter = null;
  105. if (typeof opts === "number") {
  106. count = opts | 0;
  107. countExists = true;
  108. } else if (typeof opts === "function") {
  109. filter = opts;
  110. } else if (opts) {
  111. includeComments = !!opts.includeComments;
  112. count = opts.count | 0;
  113. countExists = typeof opts.count === "number";
  114. filter = opts.filter || null;
  115. }
  116. assert(count >= 0, "options.count should be zero or a positive integer.");
  117. assert(!filter || typeof filter === "function", "options.filter should be a function.");
  118. return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1);
  119. }
  120. /**
  121. * Creates the cursor iterates tokens with options.
  122. * This is overload function of the below.
  123. * @param {Token[]} tokens The array of tokens.
  124. * @param {Comment[]} comments The array of comments.
  125. * @param {Object} indexMap The map from locations to indices in `tokens`.
  126. * @param {number} startLoc The start location of the iteration range.
  127. * @param {number} endLoc The end location of the iteration range.
  128. * @param {Function|Object} opts The option object. If this is a function then it's `opts.filter`.
  129. * @param {boolean} [opts.includeComments] The flag to iterate comments as well.
  130. * @param {Function|null} [opts.filter=null] The predicate function to choose tokens.
  131. * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility.
  132. * @returns {Cursor} The created cursor.
  133. * @private
  134. */
  135. /**
  136. * Creates the cursor iterates tokens with options.
  137. * @param {Token[]} tokens The array of tokens.
  138. * @param {Comment[]} comments The array of comments.
  139. * @param {Object} indexMap The map from locations to indices in `tokens`.
  140. * @param {number} startLoc The start location of the iteration range.
  141. * @param {number} endLoc The end location of the iteration range.
  142. * @param {number} [beforeCount=0] The number of tokens before the node to retrieve.
  143. * @param {boolean} [afterCount=0] The number of tokens after the node to retrieve.
  144. * @returns {Cursor} The created cursor.
  145. * @private
  146. */
  147. function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) {
  148. if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") {
  149. return new ForwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc);
  150. }
  151. if (typeof beforeCount === "number" || typeof beforeCount === "undefined") {
  152. return new PaddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount | 0, afterCount | 0);
  153. }
  154. return createCursorWithCount(cursors.forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount);
  155. }
  156. /**
  157. * Gets comment tokens that are adjacent to the current cursor position.
  158. * @param {Cursor} cursor A cursor instance.
  159. * @returns {Array} An array of comment tokens adjacent to the current cursor position.
  160. * @private
  161. */
  162. function getAdjacentCommentTokensFromCursor(cursor) {
  163. const tokens = [];
  164. let currentToken = cursor.getOneToken();
  165. while (currentToken && isCommentToken(currentToken)) {
  166. tokens.push(currentToken);
  167. currentToken = cursor.getOneToken();
  168. }
  169. return tokens;
  170. }
  171. //------------------------------------------------------------------------------
  172. // Exports
  173. //------------------------------------------------------------------------------
  174. /**
  175. * The token store.
  176. *
  177. * This class provides methods to get tokens by locations as fast as possible.
  178. * The methods are a part of public API, so we should be careful if it changes this class.
  179. *
  180. * People can get tokens in O(1) by the hash map which is mapping from the location of tokens/comments to tokens.
  181. * Also people can get a mix of tokens and comments in O(log k), the k is the number of comments.
  182. * 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.
  183. * This uses binary-searching instead for comments.
  184. */
  185. module.exports = class TokenStore {
  186. /**
  187. * Initializes this token store.
  188. * @param {Token[]} tokens The array of tokens.
  189. * @param {Comment[]} comments The array of comments.
  190. */
  191. constructor(tokens, comments) {
  192. this[TOKENS] = tokens;
  193. this[COMMENTS] = comments;
  194. this[INDEX_MAP] = createIndexMap(tokens, comments);
  195. }
  196. //--------------------------------------------------------------------------
  197. // Gets single token.
  198. //--------------------------------------------------------------------------
  199. /**
  200. * Gets the token starting at the specified index.
  201. * @param {number} offset Index of the start of the token's range.
  202. * @param {Object} [options=0] The option object.
  203. * @param {boolean} [options.includeComments=false] The flag to iterate comments as well.
  204. * @returns {Token|null} The token starting at index, or null if no such token.
  205. */
  206. getTokenByRangeStart(offset, options) {
  207. const includeComments = options && options.includeComments;
  208. const token = cursors.forward.createBaseCursor(
  209. this[TOKENS],
  210. this[COMMENTS],
  211. this[INDEX_MAP],
  212. offset,
  213. -1,
  214. includeComments
  215. ).getOneToken();
  216. if (token && token.range[0] === offset) {
  217. return token;
  218. }
  219. return null;
  220. }
  221. /**
  222. * Gets the first token of the given node.
  223. * @param {ASTNode} node The AST node.
  224. * @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`.
  225. * @param {boolean} [options.includeComments=false] The flag to iterate comments as well.
  226. * @param {Function|null} [options.filter=null] The predicate function to choose tokens.
  227. * @param {number} [options.skip=0] The count of tokens the cursor skips.
  228. * @returns {Token|null} An object representing the token.
  229. */
  230. getFirstToken(node, options) {
  231. return createCursorWithSkip(
  232. cursors.forward,
  233. this[TOKENS],
  234. this[COMMENTS],
  235. this[INDEX_MAP],
  236. node.range[0],
  237. node.range[1],
  238. options
  239. ).getOneToken();
  240. }
  241. /**
  242. * Gets the last token of the given node.
  243. * @param {ASTNode} node The AST node.
  244. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken()
  245. * @returns {Token|null} An object representing the token.
  246. */
  247. getLastToken(node, options) {
  248. return createCursorWithSkip(
  249. cursors.backward,
  250. this[TOKENS],
  251. this[COMMENTS],
  252. this[INDEX_MAP],
  253. node.range[0],
  254. node.range[1],
  255. options
  256. ).getOneToken();
  257. }
  258. /**
  259. * Gets the token that precedes a given node or token.
  260. * @param {ASTNode|Token|Comment} node The AST node or token.
  261. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken()
  262. * @returns {Token|null} An object representing the token.
  263. */
  264. getTokenBefore(node, options) {
  265. return createCursorWithSkip(
  266. cursors.backward,
  267. this[TOKENS],
  268. this[COMMENTS],
  269. this[INDEX_MAP],
  270. -1,
  271. node.range[0],
  272. options
  273. ).getOneToken();
  274. }
  275. /**
  276. * Gets the token that follows a given node or token.
  277. * @param {ASTNode|Token|Comment} node The AST node or token.
  278. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken()
  279. * @returns {Token|null} An object representing the token.
  280. */
  281. getTokenAfter(node, options) {
  282. return createCursorWithSkip(
  283. cursors.forward,
  284. this[TOKENS],
  285. this[COMMENTS],
  286. this[INDEX_MAP],
  287. node.range[1],
  288. -1,
  289. options
  290. ).getOneToken();
  291. }
  292. /**
  293. * Gets the first token between two non-overlapping nodes.
  294. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  295. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  296. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken()
  297. * @returns {Token|null} An object representing the token.
  298. */
  299. getFirstTokenBetween(left, right, options) {
  300. return createCursorWithSkip(
  301. cursors.forward,
  302. this[TOKENS],
  303. this[COMMENTS],
  304. this[INDEX_MAP],
  305. left.range[1],
  306. right.range[0],
  307. options
  308. ).getOneToken();
  309. }
  310. /**
  311. * Gets the last token between two non-overlapping nodes.
  312. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  313. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  314. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken()
  315. * @returns {Token|null} An object representing the token.
  316. */
  317. getLastTokenBetween(left, right, options) {
  318. return createCursorWithSkip(
  319. cursors.backward,
  320. this[TOKENS],
  321. this[COMMENTS],
  322. this[INDEX_MAP],
  323. left.range[1],
  324. right.range[0],
  325. options
  326. ).getOneToken();
  327. }
  328. /**
  329. * Gets the token that precedes a given node or token in the token stream.
  330. * This is defined for backward compatibility. Use `includeComments` option instead.
  331. * TODO: We have a plan to remove this in a future major version.
  332. * @param {ASTNode|Token|Comment} node The AST node or token.
  333. * @param {number} [skip=0] A number of tokens to skip.
  334. * @returns {Token|null} An object representing the token.
  335. * @deprecated
  336. */
  337. getTokenOrCommentBefore(node, skip) {
  338. return this.getTokenBefore(node, { includeComments: true, skip });
  339. }
  340. /**
  341. * Gets the token that follows a given node or token in the token stream.
  342. * This is defined for backward compatibility. Use `includeComments` option instead.
  343. * TODO: We have a plan to remove this in a future major version.
  344. * @param {ASTNode|Token|Comment} node The AST node or token.
  345. * @param {number} [skip=0] A number of tokens to skip.
  346. * @returns {Token|null} An object representing the token.
  347. * @deprecated
  348. */
  349. getTokenOrCommentAfter(node, skip) {
  350. return this.getTokenAfter(node, { includeComments: true, skip });
  351. }
  352. //--------------------------------------------------------------------------
  353. // Gets multiple tokens.
  354. //--------------------------------------------------------------------------
  355. /**
  356. * Gets the first `count` tokens of the given node.
  357. * @param {ASTNode} node The AST node.
  358. * @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`.
  359. * @param {boolean} [options.includeComments=false] The flag to iterate comments as well.
  360. * @param {Function|null} [options.filter=null] The predicate function to choose tokens.
  361. * @param {number} [options.count=0] The maximum count of tokens the cursor iterates.
  362. * @returns {Token[]} Tokens.
  363. */
  364. getFirstTokens(node, options) {
  365. return createCursorWithCount(
  366. cursors.forward,
  367. this[TOKENS],
  368. this[COMMENTS],
  369. this[INDEX_MAP],
  370. node.range[0],
  371. node.range[1],
  372. options
  373. ).getAllTokens();
  374. }
  375. /**
  376. * Gets the last `count` tokens of the given node.
  377. * @param {ASTNode} node The AST node.
  378. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens()
  379. * @returns {Token[]} Tokens.
  380. */
  381. getLastTokens(node, options) {
  382. return createCursorWithCount(
  383. cursors.backward,
  384. this[TOKENS],
  385. this[COMMENTS],
  386. this[INDEX_MAP],
  387. node.range[0],
  388. node.range[1],
  389. options
  390. ).getAllTokens().reverse();
  391. }
  392. /**
  393. * Gets the `count` tokens that precedes a given node or token.
  394. * @param {ASTNode|Token|Comment} node The AST node or token.
  395. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens()
  396. * @returns {Token[]} Tokens.
  397. */
  398. getTokensBefore(node, options) {
  399. return createCursorWithCount(
  400. cursors.backward,
  401. this[TOKENS],
  402. this[COMMENTS],
  403. this[INDEX_MAP],
  404. -1,
  405. node.range[0],
  406. options
  407. ).getAllTokens().reverse();
  408. }
  409. /**
  410. * Gets the `count` tokens that follows a given node or token.
  411. * @param {ASTNode|Token|Comment} node The AST node or token.
  412. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens()
  413. * @returns {Token[]} Tokens.
  414. */
  415. getTokensAfter(node, options) {
  416. return createCursorWithCount(
  417. cursors.forward,
  418. this[TOKENS],
  419. this[COMMENTS],
  420. this[INDEX_MAP],
  421. node.range[1],
  422. -1,
  423. options
  424. ).getAllTokens();
  425. }
  426. /**
  427. * Gets the first `count` tokens between two non-overlapping nodes.
  428. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  429. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  430. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens()
  431. * @returns {Token[]} Tokens between left and right.
  432. */
  433. getFirstTokensBetween(left, right, options) {
  434. return createCursorWithCount(
  435. cursors.forward,
  436. this[TOKENS],
  437. this[COMMENTS],
  438. this[INDEX_MAP],
  439. left.range[1],
  440. right.range[0],
  441. options
  442. ).getAllTokens();
  443. }
  444. /**
  445. * Gets the last `count` tokens between two non-overlapping nodes.
  446. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  447. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  448. * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens()
  449. * @returns {Token[]} Tokens between left and right.
  450. */
  451. getLastTokensBetween(left, right, options) {
  452. return createCursorWithCount(
  453. cursors.backward,
  454. this[TOKENS],
  455. this[COMMENTS],
  456. this[INDEX_MAP],
  457. left.range[1],
  458. right.range[0],
  459. options
  460. ).getAllTokens().reverse();
  461. }
  462. /**
  463. * Gets all tokens that are related to the given node.
  464. * @param {ASTNode} node The AST node.
  465. * @param {Function|Object} options The option object. If this is a function then it's `options.filter`.
  466. * @param {boolean} [options.includeComments=false] The flag to iterate comments as well.
  467. * @param {Function|null} [options.filter=null] The predicate function to choose tokens.
  468. * @param {number} [options.count=0] The maximum count of tokens the cursor iterates.
  469. * @returns {Token[]} Array of objects representing tokens.
  470. */
  471. /**
  472. * Gets all tokens that are related to the given node.
  473. * @param {ASTNode} node The AST node.
  474. * @param {int} [beforeCount=0] The number of tokens before the node to retrieve.
  475. * @param {int} [afterCount=0] The number of tokens after the node to retrieve.
  476. * @returns {Token[]} Array of objects representing tokens.
  477. */
  478. getTokens(node, beforeCount, afterCount) {
  479. return createCursorWithPadding(
  480. this[TOKENS],
  481. this[COMMENTS],
  482. this[INDEX_MAP],
  483. node.range[0],
  484. node.range[1],
  485. beforeCount,
  486. afterCount
  487. ).getAllTokens();
  488. }
  489. /**
  490. * Gets all of the tokens between two non-overlapping nodes.
  491. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  492. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  493. * @param {Function|Object} options The option object. If this is a function then it's `options.filter`.
  494. * @param {boolean} [options.includeComments=false] The flag to iterate comments as well.
  495. * @param {Function|null} [options.filter=null] The predicate function to choose tokens.
  496. * @param {number} [options.count=0] The maximum count of tokens the cursor iterates.
  497. * @returns {Token[]} Tokens between left and right.
  498. */
  499. /**
  500. * Gets all of the tokens between two non-overlapping nodes.
  501. * @param {ASTNode|Token|Comment} left Node before the desired token range.
  502. * @param {ASTNode|Token|Comment} right Node after the desired token range.
  503. * @param {int} [padding=0] Number of extra tokens on either side of center.
  504. * @returns {Token[]} Tokens between left and right.
  505. */
  506. getTokensBetween(left, right, padding) {
  507. return createCursorWithPadding(
  508. this[TOKENS],
  509. this[COMMENTS],
  510. this[INDEX_MAP],
  511. left.range[1],
  512. right.range[0],
  513. padding,
  514. padding
  515. ).getAllTokens();
  516. }
  517. //--------------------------------------------------------------------------
  518. // Others.
  519. //--------------------------------------------------------------------------
  520. /**
  521. * Checks whether any comments exist or not between the given 2 nodes.
  522. * @param {ASTNode} left The node to check.
  523. * @param {ASTNode} right The node to check.
  524. * @returns {boolean} `true` if one or more comments exist.
  525. */
  526. commentsExistBetween(left, right) {
  527. const index = utils.search(this[COMMENTS], left.range[1]);
  528. return (
  529. index < this[COMMENTS].length &&
  530. this[COMMENTS][index].range[1] <= right.range[0]
  531. );
  532. }
  533. /**
  534. * Gets all comment tokens directly before the given node or token.
  535. * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens.
  536. * @returns {Array} An array of comments in occurrence order.
  537. */
  538. getCommentsBefore(nodeOrToken) {
  539. const cursor = createCursorWithCount(
  540. cursors.backward,
  541. this[TOKENS],
  542. this[COMMENTS],
  543. this[INDEX_MAP],
  544. -1,
  545. nodeOrToken.range[0],
  546. { includeComments: true }
  547. );
  548. return getAdjacentCommentTokensFromCursor(cursor).reverse();
  549. }
  550. /**
  551. * Gets all comment tokens directly after the given node or token.
  552. * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens.
  553. * @returns {Array} An array of comments in occurrence order.
  554. */
  555. getCommentsAfter(nodeOrToken) {
  556. const cursor = createCursorWithCount(
  557. cursors.forward,
  558. this[TOKENS],
  559. this[COMMENTS],
  560. this[INDEX_MAP],
  561. nodeOrToken.range[1],
  562. -1,
  563. { includeComments: true }
  564. );
  565. return getAdjacentCommentTokensFromCursor(cursor);
  566. }
  567. /**
  568. * Gets all comment tokens inside the given node.
  569. * @param {ASTNode} node The AST node to get the comments for.
  570. * @returns {Array} An array of comments in occurrence order.
  571. */
  572. getCommentsInside(node) {
  573. return this.getTokens(node, {
  574. includeComments: true,
  575. filter: isCommentToken
  576. });
  577. }
  578. };