UNPKG

4.72 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.findParent = findParent;
7exports.find = find;
8exports.getFunctionParent = getFunctionParent;
9exports.getStatementParent = getStatementParent;
10exports.getEarliestCommonAncestorFrom = getEarliestCommonAncestorFrom;
11exports.getDeepestCommonAncestorFrom = getDeepestCommonAncestorFrom;
12exports.getAncestry = getAncestry;
13exports.isAncestor = isAncestor;
14exports.isDescendant = isDescendant;
15exports.inType = inType;
16
17var t = _interopRequireWildcard(require("@babel/types"));
18
19var _index = _interopRequireDefault(require("./index"));
20
21function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
23function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
24
25function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
27function findParent(callback) {
28 let path = this;
29
30 while (path = path.parentPath) {
31 if (callback(path)) return path;
32 }
33
34 return null;
35}
36
37function find(callback) {
38 let path = this;
39
40 do {
41 if (callback(path)) return path;
42 } while (path = path.parentPath);
43
44 return null;
45}
46
47function getFunctionParent() {
48 return this.findParent(p => p.isFunction());
49}
50
51function getStatementParent() {
52 let path = this;
53
54 do {
55 if (!path.parentPath || Array.isArray(path.container) && path.isStatement()) {
56 break;
57 } else {
58 path = path.parentPath;
59 }
60 } while (path);
61
62 if (path && (path.isProgram() || path.isFile())) {
63 throw new Error("File/Program node, we can't possibly find a statement parent to this");
64 }
65
66 return path;
67}
68
69function getEarliestCommonAncestorFrom(paths) {
70 return this.getDeepestCommonAncestorFrom(paths, function (deepest, i, ancestries) {
71 let earliest;
72 const keys = t.VISITOR_KEYS[deepest.type];
73
74 for (const ancestry of ancestries) {
75 const path = ancestry[i + 1];
76
77 if (!earliest) {
78 earliest = path;
79 continue;
80 }
81
82 if (path.listKey && earliest.listKey === path.listKey) {
83 if (path.key < earliest.key) {
84 earliest = path;
85 continue;
86 }
87 }
88
89 const earliestKeyIndex = keys.indexOf(earliest.parentKey);
90 const currentKeyIndex = keys.indexOf(path.parentKey);
91
92 if (earliestKeyIndex > currentKeyIndex) {
93 earliest = path;
94 }
95 }
96
97 return earliest;
98 });
99}
100
101function getDeepestCommonAncestorFrom(paths, filter) {
102 if (!paths.length) {
103 return this;
104 }
105
106 if (paths.length === 1) {
107 return paths[0];
108 }
109
110 let minDepth = Infinity;
111 let lastCommonIndex, lastCommon;
112 const ancestries = paths.map(path => {
113 const ancestry = [];
114
115 do {
116 ancestry.unshift(path);
117 } while ((path = path.parentPath) && path !== this);
118
119 if (ancestry.length < minDepth) {
120 minDepth = ancestry.length;
121 }
122
123 return ancestry;
124 });
125 const first = ancestries[0];
126
127 depthLoop: for (let i = 0; i < minDepth; i++) {
128 const shouldMatch = first[i];
129
130 for (const ancestry of ancestries) {
131 if (ancestry[i] !== shouldMatch) {
132 break depthLoop;
133 }
134 }
135
136 lastCommonIndex = i;
137 lastCommon = shouldMatch;
138 }
139
140 if (lastCommon) {
141 if (filter) {
142 return filter(lastCommon, lastCommonIndex, ancestries);
143 } else {
144 return lastCommon;
145 }
146 } else {
147 throw new Error("Couldn't find intersection");
148 }
149}
150
151function getAncestry() {
152 let path = this;
153 const paths = [];
154
155 do {
156 paths.push(path);
157 } while (path = path.parentPath);
158
159 return paths;
160}
161
162function isAncestor(maybeDescendant) {
163 return maybeDescendant.isDescendant(this);
164}
165
166function isDescendant(maybeAncestor) {
167 return !!this.findParent(parent => parent === maybeAncestor);
168}
169
170function inType() {
171 let path = this;
172
173 while (path) {
174 for (const type of arguments) {
175 if (path.node.type === type) return true;
176 }
177
178 path = path.parentPath;
179 }
180
181 return false;
182}
\No newline at end of file