@babel/traverse 7.0.0-beta.46 → 7.0.0-beta.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @babel/traverse might be problematic. Click here for more details.
- package/lib/cache.js +2 -2
- package/lib/context.js +34 -38
- package/lib/hub.js +6 -3
- package/lib/index.js +7 -7
- package/lib/path/ancestry.js +25 -31
- package/lib/path/comments.js +8 -8
- package/lib/path/context.js +17 -21
- package/lib/path/conversion.js +119 -126
- package/lib/path/evaluation.js +87 -99
- package/lib/path/family.js +26 -36
- package/lib/path/index.js +59 -77
- package/lib/path/inference/index.js +11 -11
- package/lib/path/inference/inferer-reference.js +36 -38
- package/lib/path/inference/inferers.js +14 -14
- package/lib/path/introspection.js +51 -57
- package/lib/path/lib/hoister.js +48 -50
- package/lib/path/lib/removal-hooks.js +2 -2
- package/lib/path/lib/virtual-types.js +75 -45
- package/lib/path/modification.js +33 -42
- package/lib/path/removal.js +3 -7
- package/lib/path/replacement.js +29 -32
- package/lib/scope/binding.js +20 -22
- package/lib/scope/index.js +271 -284
- package/lib/scope/lib/renamer.js +31 -33
- package/lib/visitors.js +59 -73
- package/package.json +9 -9
@@ -25,7 +25,7 @@ exports.isInStrictMode = isInStrictMode;
|
|
25
25
|
exports.is = void 0;
|
26
26
|
|
27
27
|
function _includes() {
|
28
|
-
|
28
|
+
const data = _interopRequireDefault(require("lodash/includes"));
|
29
29
|
|
30
30
|
_includes = function _includes() {
|
31
31
|
return data;
|
@@ -35,7 +35,7 @@ function _includes() {
|
|
35
35
|
}
|
36
36
|
|
37
37
|
function t() {
|
38
|
-
|
38
|
+
const data = _interopRequireWildcard(require("@babel/types"));
|
39
39
|
|
40
40
|
t = function t() {
|
41
41
|
return data;
|
@@ -53,7 +53,7 @@ function matchesPattern(pattern, allowPartial) {
|
|
53
53
|
}
|
54
54
|
|
55
55
|
function has(key) {
|
56
|
-
|
56
|
+
const val = this.node && this.node[key];
|
57
57
|
|
58
58
|
if (val && Array.isArray(val)) {
|
59
59
|
return !!val.length;
|
@@ -66,7 +66,7 @@ function isStatic() {
|
|
66
66
|
return this.scope.isStatic(this.node);
|
67
67
|
}
|
68
68
|
|
69
|
-
|
69
|
+
const is = has;
|
70
70
|
exports.is = is;
|
71
71
|
|
72
72
|
function isnt(key) {
|
@@ -100,11 +100,11 @@ function canSwapBetweenExpressionAndStatement(replacement) {
|
|
100
100
|
}
|
101
101
|
|
102
102
|
function isCompletionRecord(allowInsideFunction) {
|
103
|
-
|
104
|
-
|
103
|
+
let path = this;
|
104
|
+
let first = true;
|
105
105
|
|
106
106
|
do {
|
107
|
-
|
107
|
+
const container = path.container;
|
108
108
|
|
109
109
|
if (path.isFunction() && !first) {
|
110
110
|
return !!allowInsideFunction;
|
@@ -130,10 +130,10 @@ function isStatementOrBlock() {
|
|
130
130
|
|
131
131
|
function referencesImport(moduleSource, importName) {
|
132
132
|
if (!this.isReferencedIdentifier()) return false;
|
133
|
-
|
133
|
+
const binding = this.scope.getBinding(this.node.name);
|
134
134
|
if (!binding || binding.kind !== "module") return false;
|
135
|
-
|
136
|
-
|
135
|
+
const path = binding.path;
|
136
|
+
const parent = path.parentPath;
|
137
137
|
if (!parent.isImportDeclaration()) return false;
|
138
138
|
|
139
139
|
if (parent.node.source.value === moduleSource) {
|
@@ -158,7 +158,7 @@ function referencesImport(moduleSource, importName) {
|
|
158
158
|
}
|
159
159
|
|
160
160
|
function getSource() {
|
161
|
-
|
161
|
+
const node = this.node;
|
162
162
|
|
163
163
|
if (node.end) {
|
164
164
|
return this.hub.file.code.slice(node.start, node.end);
|
@@ -172,11 +172,11 @@ function willIMaybeExecuteBefore(target) {
|
|
172
172
|
}
|
173
173
|
|
174
174
|
function _guessExecutionStatusRelativeTo(target) {
|
175
|
-
|
176
|
-
|
175
|
+
const targetFuncParent = target.scope.getFunctionParent() || target.scope.getProgramParent();
|
176
|
+
const selfFuncParent = this.scope.getFunctionParent() || target.scope.getProgramParent();
|
177
177
|
|
178
178
|
if (targetFuncParent.node !== selfFuncParent.node) {
|
179
|
-
|
179
|
+
const status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
|
180
180
|
|
181
181
|
if (status) {
|
182
182
|
return status;
|
@@ -185,15 +185,15 @@ function _guessExecutionStatusRelativeTo(target) {
|
|
185
185
|
}
|
186
186
|
}
|
187
187
|
|
188
|
-
|
188
|
+
const targetPaths = target.getAncestry();
|
189
189
|
if (targetPaths.indexOf(this) >= 0) return "after";
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
const selfPaths = this.getAncestry();
|
191
|
+
let commonPath;
|
192
|
+
let targetIndex;
|
193
|
+
let selfIndex;
|
194
194
|
|
195
195
|
for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
|
196
|
-
|
196
|
+
const selfPath = selfPaths[selfIndex];
|
197
197
|
targetIndex = targetPaths.indexOf(selfPath);
|
198
198
|
|
199
199
|
if (targetIndex >= 0) {
|
@@ -206,8 +206,8 @@ function _guessExecutionStatusRelativeTo(target) {
|
|
206
206
|
return "before";
|
207
207
|
}
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
const targetRelationship = targetPaths[targetIndex - 1];
|
210
|
+
const selfRelationship = selfPaths[selfIndex - 1];
|
211
211
|
|
212
212
|
if (!targetRelationship || !selfRelationship) {
|
213
213
|
return "before";
|
@@ -217,18 +217,18 @@ function _guessExecutionStatusRelativeTo(target) {
|
|
217
217
|
return targetRelationship.key > selfRelationship.key ? "before" : "after";
|
218
218
|
}
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
|
220
|
+
const keys = t().VISITOR_KEYS[commonPath.type];
|
221
|
+
const targetKeyPosition = keys.indexOf(targetRelationship.key);
|
222
|
+
const selfKeyPosition = keys.indexOf(selfRelationship.key);
|
223
223
|
return targetKeyPosition > selfKeyPosition ? "before" : "after";
|
224
224
|
}
|
225
225
|
|
226
226
|
function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
|
227
|
-
|
227
|
+
const targetFuncPath = targetFuncParent.path;
|
228
228
|
if (!targetFuncPath.isFunctionDeclaration()) return;
|
229
|
-
|
229
|
+
const binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);
|
230
230
|
if (!binding.references) return "before";
|
231
|
-
|
231
|
+
const referencePaths = binding.referencePaths;
|
232
232
|
|
233
233
|
for (var _iterator = referencePaths, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
234
234
|
var _ref;
|
@@ -242,14 +242,14 @@ function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
|
|
242
242
|
_ref = _i.value;
|
243
243
|
}
|
244
244
|
|
245
|
-
|
245
|
+
const path = _ref;
|
246
246
|
|
247
247
|
if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
|
248
248
|
return;
|
249
249
|
}
|
250
250
|
}
|
251
251
|
|
252
|
-
|
252
|
+
let allStatus;
|
253
253
|
|
254
254
|
for (var _iterator2 = referencePaths, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
255
255
|
var _ref2;
|
@@ -263,13 +263,11 @@ function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
|
|
263
263
|
_ref2 = _i2.value;
|
264
264
|
}
|
265
265
|
|
266
|
-
|
267
|
-
|
268
|
-
return path.node === targetFuncPath.node;
|
269
|
-
});
|
266
|
+
const path = _ref2;
|
267
|
+
const childOfFunction = !!path.find(path => path.node === targetFuncPath.node);
|
270
268
|
if (childOfFunction) continue;
|
271
269
|
|
272
|
-
|
270
|
+
const status = this._guessExecutionStatusRelativeTo(path);
|
273
271
|
|
274
272
|
if (allStatus) {
|
275
273
|
if (allStatus !== status) return;
|
@@ -295,35 +293,33 @@ function _resolve(dangerous, resolved) {
|
|
295
293
|
return this.get("init").resolve(dangerous, resolved);
|
296
294
|
} else {}
|
297
295
|
} else if (this.isReferencedIdentifier()) {
|
298
|
-
|
296
|
+
const binding = this.scope.getBinding(this.node.name);
|
299
297
|
if (!binding) return;
|
300
298
|
if (!binding.constant) return;
|
301
299
|
if (binding.kind === "module") return;
|
302
300
|
|
303
301
|
if (binding.path !== this) {
|
304
|
-
|
305
|
-
if (this.find(
|
306
|
-
return parent.node === ret.node;
|
307
|
-
})) return;
|
302
|
+
const ret = binding.path.resolve(dangerous, resolved);
|
303
|
+
if (this.find(parent => parent.node === ret.node)) return;
|
308
304
|
return ret;
|
309
305
|
}
|
310
306
|
} else if (this.isTypeCastExpression()) {
|
311
307
|
return this.get("expression").resolve(dangerous, resolved);
|
312
308
|
} else if (dangerous && this.isMemberExpression()) {
|
313
|
-
|
309
|
+
const targetKey = this.toComputedKey();
|
314
310
|
if (!t().isLiteral(targetKey)) return;
|
315
|
-
|
316
|
-
|
311
|
+
const targetName = targetKey.value;
|
312
|
+
const target = this.get("object").resolve(dangerous, resolved);
|
317
313
|
|
318
314
|
if (target.isObjectExpression()) {
|
319
|
-
|
315
|
+
const props = target.get("properties");
|
320
316
|
var _arr = props;
|
321
317
|
|
322
318
|
for (var _i3 = 0; _i3 < _arr.length; _i3++) {
|
323
|
-
|
319
|
+
const prop = _arr[_i3];
|
324
320
|
if (!prop.isProperty()) continue;
|
325
|
-
|
326
|
-
|
321
|
+
const key = prop.get("key");
|
322
|
+
let match = prop.isnt("computed") && key.isIdentifier({
|
327
323
|
name: targetName
|
328
324
|
});
|
329
325
|
match = match || key.isLiteral({
|
@@ -332,8 +328,8 @@ function _resolve(dangerous, resolved) {
|
|
332
328
|
if (match) return prop.get("value").resolve(dangerous, resolved);
|
333
329
|
}
|
334
330
|
} else if (target.isArrayExpression() && !isNaN(+targetName)) {
|
335
|
-
|
336
|
-
|
331
|
+
const elems = target.get("elements");
|
332
|
+
const elem = elems[targetName];
|
337
333
|
if (elem) return elem.resolve(dangerous, resolved);
|
338
334
|
}
|
339
335
|
}
|
@@ -341,7 +337,7 @@ function _resolve(dangerous, resolved) {
|
|
341
337
|
|
342
338
|
function isConstantExpression() {
|
343
339
|
if (this.isIdentifier()) {
|
344
|
-
|
340
|
+
const binding = this.scope.getBinding(this.node.name);
|
345
341
|
|
346
342
|
if (!binding) {
|
347
343
|
return false;
|
@@ -356,9 +352,7 @@ function isConstantExpression() {
|
|
356
352
|
}
|
357
353
|
|
358
354
|
if (this.isTemplateLiteral()) {
|
359
|
-
return this.get("expressions").every(
|
360
|
-
return expression.isConstantExpression();
|
361
|
-
});
|
355
|
+
return this.get("expressions").every(expression => expression.isConstantExpression());
|
362
356
|
}
|
363
357
|
|
364
358
|
return true;
|
@@ -380,8 +374,8 @@ function isConstantExpression() {
|
|
380
374
|
}
|
381
375
|
|
382
376
|
function isInStrictMode() {
|
383
|
-
|
384
|
-
|
377
|
+
const start = this.isProgram() ? this : this.parentPath;
|
378
|
+
const strictParent = start.find(path => {
|
385
379
|
if (path.isProgram({
|
386
380
|
sourceType: "module"
|
387
381
|
})) return true;
|
@@ -392,7 +386,7 @@ function isInStrictMode() {
|
|
392
386
|
return false;
|
393
387
|
}
|
394
388
|
|
395
|
-
|
389
|
+
let node = path.node;
|
396
390
|
if (path.isFunction()) node = node.body;
|
397
391
|
|
398
392
|
for (var _iterator3 = node.directives, _isArray3 = Array.isArray(_iterator3), _i4 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
|
@@ -407,7 +401,7 @@ function isInStrictMode() {
|
|
407
401
|
_ref3 = _i4.value;
|
408
402
|
}
|
409
403
|
|
410
|
-
|
404
|
+
const directive = _ref3;
|
411
405
|
|
412
406
|
if (directive.value.value === "use strict") {
|
413
407
|
return true;
|
package/lib/path/lib/hoister.js
CHANGED
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
exports.default = void 0;
|
7
7
|
|
8
8
|
function t() {
|
9
|
-
|
9
|
+
const data = _interopRequireWildcard(require("@babel/types"));
|
10
10
|
|
11
11
|
t = function t() {
|
12
12
|
return data;
|
@@ -17,14 +17,14 @@ function t() {
|
|
17
17
|
|
18
18
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
|
19
19
|
|
20
|
-
|
21
|
-
ReferencedIdentifier
|
20
|
+
const referenceVisitor = {
|
21
|
+
ReferencedIdentifier(path, state) {
|
22
22
|
if (path.isJSXIdentifier() && t().react.isCompatTag(path.node.name) && !path.parentPath.isJSXMemberExpression()) {
|
23
23
|
return;
|
24
24
|
}
|
25
25
|
|
26
26
|
if (path.node.name === "this") {
|
27
|
-
|
27
|
+
let scope = path.scope;
|
28
28
|
|
29
29
|
do {
|
30
30
|
if (scope.path.isFunction() && !scope.path.isArrowFunctionExpression()) {
|
@@ -35,15 +35,16 @@ var referenceVisitor = {
|
|
35
35
|
if (scope) state.breakOnScopePaths.push(scope.path);
|
36
36
|
}
|
37
37
|
|
38
|
-
|
38
|
+
const binding = path.scope.getBinding(path.node.name);
|
39
39
|
if (!binding) return;
|
40
40
|
if (binding !== state.scope.getBinding(path.node.name)) return;
|
41
41
|
state.bindings[path.node.name] = binding;
|
42
42
|
}
|
43
|
+
|
43
44
|
};
|
44
45
|
|
45
|
-
|
46
|
-
|
46
|
+
class PathHoister {
|
47
|
+
constructor(path, scope) {
|
47
48
|
this.breakOnScopePaths = [];
|
48
49
|
this.bindings = {};
|
49
50
|
this.scopes = [];
|
@@ -52,11 +53,9 @@ var PathHoister = function () {
|
|
52
53
|
this.attachAfter = false;
|
53
54
|
}
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
for (var key in this.bindings) {
|
59
|
-
var binding = this.bindings[key];
|
56
|
+
isCompatibleScope(scope) {
|
57
|
+
for (const key in this.bindings) {
|
58
|
+
const binding = this.bindings[key];
|
60
59
|
|
61
60
|
if (!scope.bindingIdentifierEquals(key, binding.identifier)) {
|
62
61
|
return false;
|
@@ -64,10 +63,10 @@ var PathHoister = function () {
|
|
64
63
|
}
|
65
64
|
|
66
65
|
return true;
|
67
|
-
}
|
66
|
+
}
|
68
67
|
|
69
|
-
|
70
|
-
|
68
|
+
getCompatibleScopes() {
|
69
|
+
let scope = this.path.scope;
|
71
70
|
|
72
71
|
do {
|
73
72
|
if (this.isCompatibleScope(scope)) {
|
@@ -80,28 +79,28 @@ var PathHoister = function () {
|
|
80
79
|
break;
|
81
80
|
}
|
82
81
|
} while (scope = scope.parent);
|
83
|
-
}
|
82
|
+
}
|
84
83
|
|
85
|
-
|
86
|
-
|
84
|
+
getAttachmentPath() {
|
85
|
+
let path = this._getAttachmentPath();
|
87
86
|
|
88
87
|
if (!path) return;
|
89
|
-
|
88
|
+
let targetScope = path.scope;
|
90
89
|
|
91
90
|
if (targetScope.path === path) {
|
92
91
|
targetScope = path.scope.parent;
|
93
92
|
}
|
94
93
|
|
95
94
|
if (targetScope.path.isProgram() || targetScope.path.isFunction()) {
|
96
|
-
for (
|
95
|
+
for (const name in this.bindings) {
|
97
96
|
if (!targetScope.hasOwnBinding(name)) continue;
|
98
|
-
|
97
|
+
const binding = this.bindings[name];
|
99
98
|
|
100
99
|
if (binding.kind === "param" || binding.path.parentKey === "params") {
|
101
100
|
continue;
|
102
101
|
}
|
103
102
|
|
104
|
-
|
103
|
+
const bindingParentPath = this.getAttachmentParentForPath(binding.path);
|
105
104
|
|
106
105
|
if (bindingParentPath.key >= path.key) {
|
107
106
|
this.attachAfter = true;
|
@@ -109,7 +108,7 @@ var PathHoister = function () {
|
|
109
108
|
var _arr = binding.constantViolations;
|
110
109
|
|
111
110
|
for (var _i = 0; _i < _arr.length; _i++) {
|
112
|
-
|
111
|
+
const violationPath = _arr[_i];
|
113
112
|
|
114
113
|
if (this.getAttachmentParentForPath(violationPath).key > path.key) {
|
115
114
|
path = violationPath;
|
@@ -120,19 +119,19 @@ var PathHoister = function () {
|
|
120
119
|
}
|
121
120
|
|
122
121
|
return path;
|
123
|
-
}
|
122
|
+
}
|
124
123
|
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
_getAttachmentPath() {
|
125
|
+
const scopes = this.scopes;
|
126
|
+
const scope = scopes.pop();
|
128
127
|
if (!scope) return;
|
129
128
|
|
130
129
|
if (scope.path.isFunction()) {
|
131
130
|
if (this.hasOwnParamBindings(scope)) {
|
132
131
|
if (this.scope === scope) return;
|
133
|
-
|
132
|
+
const bodies = scope.path.get("body").get("body");
|
134
133
|
|
135
|
-
for (
|
134
|
+
for (let i = 0; i < bodies.length; i++) {
|
136
135
|
if (bodies[i].node._blockHoist) continue;
|
137
136
|
return bodies[i];
|
138
137
|
}
|
@@ -142,45 +141,45 @@ var PathHoister = function () {
|
|
142
141
|
} else if (scope.path.isProgram()) {
|
143
142
|
return this.getNextScopeAttachmentParent();
|
144
143
|
}
|
145
|
-
}
|
144
|
+
}
|
146
145
|
|
147
|
-
|
148
|
-
|
146
|
+
getNextScopeAttachmentParent() {
|
147
|
+
const scope = this.scopes.pop();
|
149
148
|
if (scope) return this.getAttachmentParentForPath(scope.path);
|
150
|
-
}
|
149
|
+
}
|
151
150
|
|
152
|
-
|
151
|
+
getAttachmentParentForPath(path) {
|
153
152
|
do {
|
154
153
|
if (!path.parentPath || Array.isArray(path.container) && path.isStatement()) {
|
155
154
|
return path;
|
156
155
|
}
|
157
156
|
} while (path = path.parentPath);
|
158
|
-
}
|
157
|
+
}
|
159
158
|
|
160
|
-
|
161
|
-
for (
|
159
|
+
hasOwnParamBindings(scope) {
|
160
|
+
for (const name in this.bindings) {
|
162
161
|
if (!scope.hasOwnBinding(name)) continue;
|
163
|
-
|
162
|
+
const binding = this.bindings[name];
|
164
163
|
if (binding.kind === "param" && binding.constant) return true;
|
165
164
|
}
|
166
165
|
|
167
166
|
return false;
|
168
|
-
}
|
167
|
+
}
|
169
168
|
|
170
|
-
|
169
|
+
run() {
|
171
170
|
this.path.traverse(referenceVisitor, this);
|
172
171
|
this.getCompatibleScopes();
|
173
|
-
|
172
|
+
const attachTo = this.getAttachmentPath();
|
174
173
|
if (!attachTo) return;
|
175
174
|
if (attachTo.getFunctionParent() === this.path.getFunctionParent()) return;
|
176
|
-
|
177
|
-
|
178
|
-
|
175
|
+
let uid = attachTo.scope.generateUidIdentifier("ref");
|
176
|
+
const declarator = t().variableDeclarator(uid, this.path.node);
|
177
|
+
const insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
|
179
178
|
|
180
|
-
|
181
|
-
|
179
|
+
const _attachTo$insertFn = attachTo[insertFn]([attachTo.isVariableDeclarator() ? declarator : t().variableDeclaration("var", [declarator])]),
|
180
|
+
attached = _attachTo$insertFn[0];
|
182
181
|
|
183
|
-
|
182
|
+
const parent = this.path.parentPath;
|
184
183
|
|
185
184
|
if (parent.isJSXElement() && this.path.container === parent.node.children) {
|
186
185
|
uid = t().JSXExpressionContainer(uid);
|
@@ -188,9 +187,8 @@ var PathHoister = function () {
|
|
188
187
|
|
189
188
|
this.path.replaceWith(t().cloneNode(uid));
|
190
189
|
return attachTo.isVariableDeclarator() ? attached.get("init") : attached.get("declarations.0.init");
|
191
|
-
}
|
190
|
+
}
|
192
191
|
|
193
|
-
|
194
|
-
}();
|
192
|
+
}
|
195
193
|
|
196
194
|
exports.default = PathHoister;
|
@@ -4,8 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
5
5
|
});
|
6
6
|
exports.hooks = void 0;
|
7
|
-
|
8
|
-
|
7
|
+
const hooks = [function (self, parent) {
|
8
|
+
const removeParent = self.key === "test" && (parent.isWhile() || parent.isSwitchCase()) || self.key === "declaration" && parent.isExportDeclaration() || self.key === "body" && parent.isLabeledStatement() || self.listKey === "declarations" && parent.isVariableDeclaration() && parent.node.declarations.length === 1 || self.key === "expression" && parent.isExpressionStatement();
|
9
9
|
|
10
10
|
if (removeParent) {
|
11
11
|
parent.remove();
|