Ohm-Management - Projektarbeit B-ME
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

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