global-reference-tracker.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. 'use strict';
  2. const {ReferenceTracker} = require('@eslint-community/eslint-utils');
  3. const createTraceMap = (object, type) => {
  4. let map = {[type]: true};
  5. const path = object.split('.').reverse();
  6. for (const name of path) {
  7. map = {[name]: map};
  8. }
  9. return map;
  10. };
  11. class GlobalReferenceTracker {
  12. #traceMap = {};
  13. #filter;
  14. #handle;
  15. constructor({
  16. object,
  17. objects = [object],
  18. filter,
  19. handle,
  20. type = ReferenceTracker.READ,
  21. }) {
  22. for (const object of objects) {
  23. Object.assign(this.#traceMap, createTraceMap(object, type));
  24. }
  25. this.#filter = filter;
  26. this.#handle = handle;
  27. }
  28. * track(globalScope) {
  29. const tracker = new ReferenceTracker(globalScope);
  30. for (const reference of tracker.iterateGlobalReferences(this.#traceMap)) {
  31. if (this.#filter && !this.#filter(reference)) {
  32. continue;
  33. }
  34. const problems = this.#handle(reference);
  35. if (!problems) {
  36. continue;
  37. }
  38. if (problems[Symbol.iterator]) {
  39. yield * problems;
  40. } else {
  41. yield problems;
  42. }
  43. }
  44. }
  45. createListeners(context) {
  46. return {
  47. 'Program:exit': () => this.track(context.getScope()),
  48. };
  49. }
  50. }
  51. Object.assign(GlobalReferenceTracker, {
  52. READ: ReferenceTracker.READ,
  53. CALL: ReferenceTracker.CALL,
  54. CONSTRUCT: ReferenceTracker.CONSTRUCT,
  55. });
  56. module.exports = {
  57. GlobalReferenceTracker,
  58. };