mergeScope.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("eslint-scope").Reference} Reference */
  7. /** @typedef {import("eslint-scope").Variable} Variable */
  8. /** @typedef {import("../javascript/JavascriptParser").AnyNode} AnyNode */
  9. /** @typedef {import("../javascript/JavascriptParser").Program} Program */
  10. /**
  11. * @param {Variable} variable variable
  12. * @returns {Reference[]} references
  13. */
  14. const getAllReferences = variable => {
  15. let set = variable.references;
  16. // Look for inner scope variables too (like in class Foo { t() { Foo } })
  17. const identifiers = new Set(variable.identifiers);
  18. for (const scope of variable.scope.childScopes) {
  19. for (const innerVar of scope.variables) {
  20. if (innerVar.identifiers.some(id => identifiers.has(id))) {
  21. set = set.concat(innerVar.references);
  22. break;
  23. }
  24. }
  25. }
  26. return set;
  27. };
  28. /**
  29. * @param {Program | Program[]} ast ast
  30. * @param {AnyNode} node node
  31. * @returns {undefined | AnyNode[]} result
  32. */
  33. const getPathInAst = (ast, node) => {
  34. if (ast === node) {
  35. return [];
  36. }
  37. const nr = node.range;
  38. const enterNode = n => {
  39. if (!n) return undefined;
  40. const r = n.range;
  41. if (r) {
  42. if (r[0] <= nr[0] && r[1] >= nr[1]) {
  43. const path = getPathInAst(n, node);
  44. if (path) {
  45. path.push(n);
  46. return path;
  47. }
  48. }
  49. }
  50. return undefined;
  51. };
  52. if (Array.isArray(ast)) {
  53. for (let i = 0; i < ast.length; i++) {
  54. const enterResult = enterNode(ast[i]);
  55. if (enterResult !== undefined) return enterResult;
  56. }
  57. } else if (ast && typeof ast === "object") {
  58. const keys = Object.keys(ast);
  59. for (let i = 0; i < keys.length; i++) {
  60. const value = ast[keys[i]];
  61. if (Array.isArray(value)) {
  62. const pathResult = getPathInAst(value, node);
  63. if (pathResult !== undefined) return pathResult;
  64. } else if (value && typeof value === "object") {
  65. const enterResult = enterNode(value);
  66. if (enterResult !== undefined) return enterResult;
  67. }
  68. }
  69. }
  70. };
  71. module.exports = { getAllReferences, getPathInAst };