Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / utils / ast-utils.js
1 /**
2  * @fileoverview Common utils for AST.
3  * @author Gyandeep Singh
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const esutils = require("esutils");
13 const espree = require("espree");
14 const lodash = require("lodash");
15 const {
16     breakableTypePattern,
17     createGlobalLinebreakMatcher,
18     lineBreakPattern,
19     shebangPattern
20 } = require("../../shared/ast-utils");
21
22 //------------------------------------------------------------------------------
23 // Helpers
24 //------------------------------------------------------------------------------
25
26 const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/u;
27 const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/u;
28 const arrayOrTypedArrayPattern = /Array$/u;
29 const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/u;
30 const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/u;
31 const thisTagPattern = /^[\s*]*@this/mu;
32
33
34 const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u;
35 const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
36
37 // A set of node types that can contain a list of statements
38 const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
39
40 const DECIMAL_INTEGER_PATTERN = /^(0|[1-9]\d*)$/u;
41 const OCTAL_ESCAPE_PATTERN = /^(?:[^\\]|\\[^0-7]|\\0(?![0-9]))*\\(?:[1-7]|0[0-9])/u;
42
43 /**
44  * Checks reference if is non initializer and writable.
45  * @param {Reference} reference A reference to check.
46  * @param {int} index The index of the reference in the references.
47  * @param {Reference[]} references The array that the reference belongs to.
48  * @returns {boolean} Success/Failure
49  * @private
50  */
51 function isModifyingReference(reference, index, references) {
52     const identifier = reference.identifier;
53
54     /*
55      * Destructuring assignments can have multiple default value, so
56      * possibly there are multiple writeable references for the same
57      * identifier.
58      */
59     const modifyingDifferentIdentifier = index === 0 ||
60         references[index - 1].identifier !== identifier;
61
62     return (identifier &&
63         reference.init === false &&
64         reference.isWrite() &&
65         modifyingDifferentIdentifier
66     );
67 }
68
69 /**
70  * Checks whether the given string starts with uppercase or not.
71  * @param {string} s The string to check.
72  * @returns {boolean} `true` if the string starts with uppercase.
73  */
74 function startsWithUpperCase(s) {
75     return s[0] !== s[0].toLocaleLowerCase();
76 }
77
78 /**
79  * Checks whether or not a node is a constructor.
80  * @param {ASTNode} node A function node to check.
81  * @returns {boolean} Wehether or not a node is a constructor.
82  */
83 function isES5Constructor(node) {
84     return (node.id && startsWithUpperCase(node.id.name));
85 }
86
87 /**
88  * Finds a function node from ancestors of a node.
89  * @param {ASTNode} node A start node to find.
90  * @returns {Node|null} A found function node.
91  */
92 function getUpperFunction(node) {
93     for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
94         if (anyFunctionPattern.test(currentNode.type)) {
95             return currentNode;
96         }
97     }
98     return null;
99 }
100
101 /**
102  * Checks whether a given node is a function node or not.
103  * The following types are function nodes:
104  *
105  * - ArrowFunctionExpression
106  * - FunctionDeclaration
107  * - FunctionExpression
108  * @param {ASTNode|null} node A node to check.
109  * @returns {boolean} `true` if the node is a function node.
110  */
111 function isFunction(node) {
112     return Boolean(node && anyFunctionPattern.test(node.type));
113 }
114
115 /**
116  * Checks whether a given node is a loop node or not.
117  * The following types are loop nodes:
118  *
119  * - DoWhileStatement
120  * - ForInStatement
121  * - ForOfStatement
122  * - ForStatement
123  * - WhileStatement
124  * @param {ASTNode|null} node A node to check.
125  * @returns {boolean} `true` if the node is a loop node.
126  */
127 function isLoop(node) {
128     return Boolean(node && anyLoopPattern.test(node.type));
129 }
130
131 /**
132  * Checks whether the given node is in a loop or not.
133  * @param {ASTNode} node The node to check.
134  * @returns {boolean} `true` if the node is in a loop.
135  */
136 function isInLoop(node) {
137     for (let currentNode = node; currentNode && !isFunction(currentNode); currentNode = currentNode.parent) {
138         if (isLoop(currentNode)) {
139             return true;
140         }
141     }
142
143     return false;
144 }
145
146 /**
147  * Checks whether or not a node is `null` or `undefined`.
148  * @param {ASTNode} node A node to check.
149  * @returns {boolean} Whether or not the node is a `null` or `undefined`.
150  * @public
151  */
152 function isNullOrUndefined(node) {
153     return (
154         module.exports.isNullLiteral(node) ||
155         (node.type === "Identifier" && node.name === "undefined") ||
156         (node.type === "UnaryExpression" && node.operator === "void")
157     );
158 }
159
160 /**
161  * Checks whether or not a node is callee.
162  * @param {ASTNode} node A node to check.
163  * @returns {boolean} Whether or not the node is callee.
164  */
165 function isCallee(node) {
166     return node.parent.type === "CallExpression" && node.parent.callee === node;
167 }
168
169 /**
170  * Checks whether or not a node is `Reflect.apply`.
171  * @param {ASTNode} node A node to check.
172  * @returns {boolean} Whether or not the node is a `Reflect.apply`.
173  */
174 function isReflectApply(node) {
175     return (
176         node.type === "MemberExpression" &&
177         node.object.type === "Identifier" &&
178         node.object.name === "Reflect" &&
179         node.property.type === "Identifier" &&
180         node.property.name === "apply" &&
181         node.computed === false
182     );
183 }
184
185 /**
186  * Checks whether or not a node is `Array.from`.
187  * @param {ASTNode} node A node to check.
188  * @returns {boolean} Whether or not the node is a `Array.from`.
189  */
190 function isArrayFromMethod(node) {
191     return (
192         node.type === "MemberExpression" &&
193         node.object.type === "Identifier" &&
194         arrayOrTypedArrayPattern.test(node.object.name) &&
195         node.property.type === "Identifier" &&
196         node.property.name === "from" &&
197         node.computed === false
198     );
199 }
200
201 /**
202  * Checks whether or not a node is a method which has `thisArg`.
203  * @param {ASTNode} node A node to check.
204  * @returns {boolean} Whether or not the node is a method which has `thisArg`.
205  */
206 function isMethodWhichHasThisArg(node) {
207     for (
208         let currentNode = node;
209         currentNode.type === "MemberExpression" && !currentNode.computed;
210         currentNode = currentNode.property
211     ) {
212         if (currentNode.property.type === "Identifier") {
213             return arrayMethodPattern.test(currentNode.property.name);
214         }
215     }
216
217     return false;
218 }
219
220 /**
221  * Creates the negate function of the given function.
222  * @param {Function} f The function to negate.
223  * @returns {Function} Negated function.
224  */
225 function negate(f) {
226     return token => !f(token);
227 }
228
229 /**
230  * Checks whether or not a node has a `@this` tag in its comments.
231  * @param {ASTNode} node A node to check.
232  * @param {SourceCode} sourceCode A SourceCode instance to get comments.
233  * @returns {boolean} Whether or not the node has a `@this` tag in its comments.
234  */
235 function hasJSDocThisTag(node, sourceCode) {
236     const jsdocComment = sourceCode.getJSDocComment(node);
237
238     if (jsdocComment && thisTagPattern.test(jsdocComment.value)) {
239         return true;
240     }
241
242     // Checks `@this` in its leading comments for callbacks,
243     // because callbacks don't have its JSDoc comment.
244     // e.g.
245     //     sinon.test(/* @this sinon.Sandbox */function() { this.spy(); });
246     return sourceCode.getCommentsBefore(node).some(comment => thisTagPattern.test(comment.value));
247 }
248
249 /**
250  * Determines if a node is surrounded by parentheses.
251  * @param {SourceCode} sourceCode The ESLint source code object
252  * @param {ASTNode} node The node to be checked.
253  * @returns {boolean} True if the node is parenthesised.
254  * @private
255  */
256 function isParenthesised(sourceCode, node) {
257     const previousToken = sourceCode.getTokenBefore(node),
258         nextToken = sourceCode.getTokenAfter(node);
259
260     return Boolean(previousToken && nextToken) &&
261         previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
262         nextToken.value === ")" && nextToken.range[0] >= node.range[1];
263 }
264
265 /**
266  * Checks if the given token is an arrow token or not.
267  * @param {Token} token The token to check.
268  * @returns {boolean} `true` if the token is an arrow token.
269  */
270 function isArrowToken(token) {
271     return token.value === "=>" && token.type === "Punctuator";
272 }
273
274 /**
275  * Checks if the given token is a comma token or not.
276  * @param {Token} token The token to check.
277  * @returns {boolean} `true` if the token is a comma token.
278  */
279 function isCommaToken(token) {
280     return token.value === "," && token.type === "Punctuator";
281 }
282
283 /**
284  * Checks if the given token is a dot token or not.
285  * @param {Token} token The token to check.
286  * @returns {boolean} `true` if the token is a dot token.
287  */
288 function isDotToken(token) {
289     return token.value === "." && token.type === "Punctuator";
290 }
291
292 /**
293  * Checks if the given token is a semicolon token or not.
294  * @param {Token} token The token to check.
295  * @returns {boolean} `true` if the token is a semicolon token.
296  */
297 function isSemicolonToken(token) {
298     return token.value === ";" && token.type === "Punctuator";
299 }
300
301 /**
302  * Checks if the given token is a colon token or not.
303  * @param {Token} token The token to check.
304  * @returns {boolean} `true` if the token is a colon token.
305  */
306 function isColonToken(token) {
307     return token.value === ":" && token.type === "Punctuator";
308 }
309
310 /**
311  * Checks if the given token is an opening parenthesis token or not.
312  * @param {Token} token The token to check.
313  * @returns {boolean} `true` if the token is an opening parenthesis token.
314  */
315 function isOpeningParenToken(token) {
316     return token.value === "(" && token.type === "Punctuator";
317 }
318
319 /**
320  * Checks if the given token is a closing parenthesis token or not.
321  * @param {Token} token The token to check.
322  * @returns {boolean} `true` if the token is a closing parenthesis token.
323  */
324 function isClosingParenToken(token) {
325     return token.value === ")" && token.type === "Punctuator";
326 }
327
328 /**
329  * Checks if the given token is an opening square bracket token or not.
330  * @param {Token} token The token to check.
331  * @returns {boolean} `true` if the token is an opening square bracket token.
332  */
333 function isOpeningBracketToken(token) {
334     return token.value === "[" && token.type === "Punctuator";
335 }
336
337 /**
338  * Checks if the given token is a closing square bracket token or not.
339  * @param {Token} token The token to check.
340  * @returns {boolean} `true` if the token is a closing square bracket token.
341  */
342 function isClosingBracketToken(token) {
343     return token.value === "]" && token.type === "Punctuator";
344 }
345
346 /**
347  * Checks if the given token is an opening brace token or not.
348  * @param {Token} token The token to check.
349  * @returns {boolean} `true` if the token is an opening brace token.
350  */
351 function isOpeningBraceToken(token) {
352     return token.value === "{" && token.type === "Punctuator";
353 }
354
355 /**
356  * Checks if the given token is a closing brace token or not.
357  * @param {Token} token The token to check.
358  * @returns {boolean} `true` if the token is a closing brace token.
359  */
360 function isClosingBraceToken(token) {
361     return token.value === "}" && token.type === "Punctuator";
362 }
363
364 /**
365  * Checks if the given token is a comment token or not.
366  * @param {Token} token The token to check.
367  * @returns {boolean} `true` if the token is a comment token.
368  */
369 function isCommentToken(token) {
370     return token.type === "Line" || token.type === "Block" || token.type === "Shebang";
371 }
372
373 /**
374  * Checks if the given token is a keyword token or not.
375  * @param {Token} token The token to check.
376  * @returns {boolean} `true` if the token is a keyword token.
377  */
378 function isKeywordToken(token) {
379     return token.type === "Keyword";
380 }
381
382 /**
383  * Gets the `(` token of the given function node.
384  * @param {ASTNode} node The function node to get.
385  * @param {SourceCode} sourceCode The source code object to get tokens.
386  * @returns {Token} `(` token.
387  */
388 function getOpeningParenOfParams(node, sourceCode) {
389     return node.id
390         ? sourceCode.getTokenAfter(node.id, isOpeningParenToken)
391         : sourceCode.getFirstToken(node, isOpeningParenToken);
392 }
393
394 /**
395  * Checks whether or not the tokens of two given nodes are same.
396  * @param {ASTNode} left A node 1 to compare.
397  * @param {ASTNode} right A node 2 to compare.
398  * @param {SourceCode} sourceCode The ESLint source code object.
399  * @returns {boolean} the source code for the given node.
400  */
401 function equalTokens(left, right, sourceCode) {
402     const tokensL = sourceCode.getTokens(left);
403     const tokensR = sourceCode.getTokens(right);
404
405     if (tokensL.length !== tokensR.length) {
406         return false;
407     }
408     for (let i = 0; i < tokensL.length; ++i) {
409         if (tokensL[i].type !== tokensR[i].type ||
410             tokensL[i].value !== tokensR[i].value
411         ) {
412             return false;
413         }
414     }
415
416     return true;
417 }
418
419 //------------------------------------------------------------------------------
420 // Public Interface
421 //------------------------------------------------------------------------------
422
423 module.exports = {
424     COMMENTS_IGNORE_PATTERN,
425     LINEBREAKS,
426     LINEBREAK_MATCHER: lineBreakPattern,
427     SHEBANG_MATCHER: shebangPattern,
428     STATEMENT_LIST_PARENTS,
429
430     /**
431      * Determines whether two adjacent tokens are on the same line.
432      * @param {Object} left The left token object.
433      * @param {Object} right The right token object.
434      * @returns {boolean} Whether or not the tokens are on the same line.
435      * @public
436      */
437     isTokenOnSameLine(left, right) {
438         return left.loc.end.line === right.loc.start.line;
439     },
440
441     isNullOrUndefined,
442     isCallee,
443     isES5Constructor,
444     getUpperFunction,
445     isFunction,
446     isLoop,
447     isInLoop,
448     isArrayFromMethod,
449     isParenthesised,
450     createGlobalLinebreakMatcher,
451     equalTokens,
452
453     isArrowToken,
454     isClosingBraceToken,
455     isClosingBracketToken,
456     isClosingParenToken,
457     isColonToken,
458     isCommaToken,
459     isCommentToken,
460     isDotToken,
461     isKeywordToken,
462     isNotClosingBraceToken: negate(isClosingBraceToken),
463     isNotClosingBracketToken: negate(isClosingBracketToken),
464     isNotClosingParenToken: negate(isClosingParenToken),
465     isNotColonToken: negate(isColonToken),
466     isNotCommaToken: negate(isCommaToken),
467     isNotDotToken: negate(isDotToken),
468     isNotOpeningBraceToken: negate(isOpeningBraceToken),
469     isNotOpeningBracketToken: negate(isOpeningBracketToken),
470     isNotOpeningParenToken: negate(isOpeningParenToken),
471     isNotSemicolonToken: negate(isSemicolonToken),
472     isOpeningBraceToken,
473     isOpeningBracketToken,
474     isOpeningParenToken,
475     isSemicolonToken,
476
477     /**
478      * Checks whether or not a given node is a string literal.
479      * @param {ASTNode} node A node to check.
480      * @returns {boolean} `true` if the node is a string literal.
481      */
482     isStringLiteral(node) {
483         return (
484             (node.type === "Literal" && typeof node.value === "string") ||
485             node.type === "TemplateLiteral"
486         );
487     },
488
489     /**
490      * Checks whether a given node is a breakable statement or not.
491      * The node is breakable if the node is one of the following type:
492      *
493      * - DoWhileStatement
494      * - ForInStatement
495      * - ForOfStatement
496      * - ForStatement
497      * - SwitchStatement
498      * - WhileStatement
499      * @param {ASTNode} node A node to check.
500      * @returns {boolean} `true` if the node is breakable.
501      */
502     isBreakableStatement(node) {
503         return breakableTypePattern.test(node.type);
504     },
505
506     /**
507      * Gets references which are non initializer and writable.
508      * @param {Reference[]} references An array of references.
509      * @returns {Reference[]} An array of only references which are non initializer and writable.
510      * @public
511      */
512     getModifyingReferences(references) {
513         return references.filter(isModifyingReference);
514     },
515
516     /**
517      * Validate that a string passed in is surrounded by the specified character
518      * @param  {string} val The text to check.
519      * @param  {string} character The character to see if it's surrounded by.
520      * @returns {boolean} True if the text is surrounded by the character, false if not.
521      * @private
522      */
523     isSurroundedBy(val, character) {
524         return val[0] === character && val[val.length - 1] === character;
525     },
526
527     /**
528      * Returns whether the provided node is an ESLint directive comment or not
529      * @param {Line|Block} node The comment token to be checked
530      * @returns {boolean} `true` if the node is an ESLint directive comment
531      */
532     isDirectiveComment(node) {
533         const comment = node.value.trim();
534
535         return (
536             node.type === "Line" && comment.indexOf("eslint-") === 0 ||
537             node.type === "Block" && (
538                 comment.indexOf("global ") === 0 ||
539                 comment.indexOf("eslint ") === 0 ||
540                 comment.indexOf("eslint-") === 0
541             )
542         );
543     },
544
545     /**
546      * Gets the trailing statement of a given node.
547      *
548      *     if (code)
549      *         consequent;
550      *
551      * When taking this `IfStatement`, returns `consequent;` statement.
552      * @param {ASTNode} A node to get.
553      * @returns {ASTNode|null} The trailing statement's node.
554      */
555     getTrailingStatement: esutils.ast.trailingStatement,
556
557     /**
558      * Finds the variable by a given name in a given scope and its upper scopes.
559      * @param {eslint-scope.Scope} initScope A scope to start find.
560      * @param {string} name A variable name to find.
561      * @returns {eslint-scope.Variable|null} A found variable or `null`.
562      */
563     getVariableByName(initScope, name) {
564         let scope = initScope;
565
566         while (scope) {
567             const variable = scope.set.get(name);
568
569             if (variable) {
570                 return variable;
571             }
572
573             scope = scope.upper;
574         }
575
576         return null;
577     },
578
579     /**
580      * Checks whether or not a given function node is the default `this` binding.
581      *
582      * First, this checks the node:
583      *
584      * - The function name does not start with uppercase. It's a convention to capitalize the names
585      *   of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
586      * - The function does not have a JSDoc comment that has a @this tag.
587      *
588      * Next, this checks the location of the node.
589      * If the location is below, this judges `this` is valid.
590      *
591      * - The location is not on an object literal.
592      * - The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous
593      *   functions only, as the name of the variable is considered to be the name of the function in this case.
594      *   This check is not performed if `capIsConstructor` is set to `false`.
595      * - The location is not on an ES2015 class.
596      * - Its `bind`/`call`/`apply` method is not called directly.
597      * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
598      * @param {ASTNode} node A function node to check.
599      * @param {SourceCode} sourceCode A SourceCode instance to get comments.
600      * @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
601      * with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
602      * @returns {boolean} The function node is the default `this` binding.
603      */
604     isDefaultThisBinding(node, sourceCode, { capIsConstructor = true } = {}) {
605         if (
606             (capIsConstructor && isES5Constructor(node)) ||
607             hasJSDocThisTag(node, sourceCode)
608         ) {
609             return false;
610         }
611         const isAnonymous = node.id === null;
612         let currentNode = node;
613
614         while (currentNode) {
615             const parent = currentNode.parent;
616
617             switch (parent.type) {
618
619                 /*
620                  * Looks up the destination.
621                  * e.g., obj.foo = nativeFoo || function foo() { ... };
622                  */
623                 case "LogicalExpression":
624                 case "ConditionalExpression":
625                     currentNode = parent;
626                     break;
627
628                 /*
629                  * If the upper function is IIFE, checks the destination of the return value.
630                  * e.g.
631                  *   obj.foo = (function() {
632                  *     // setup...
633                  *     return function foo() { ... };
634                  *   })();
635                  *   obj.foo = (() =>
636                  *     function foo() { ... }
637                  *   )();
638                  */
639                 case "ReturnStatement": {
640                     const func = getUpperFunction(parent);
641
642                     if (func === null || !isCallee(func)) {
643                         return true;
644                     }
645                     currentNode = func.parent;
646                     break;
647                 }
648                 case "ArrowFunctionExpression":
649                     if (currentNode !== parent.body || !isCallee(parent)) {
650                         return true;
651                     }
652                     currentNode = parent.parent;
653                     break;
654
655                 /*
656                  * e.g.
657                  *   var obj = { foo() { ... } };
658                  *   var obj = { foo: function() { ... } };
659                  *   class A { constructor() { ... } }
660                  *   class A { foo() { ... } }
661                  *   class A { get foo() { ... } }
662                  *   class A { set foo() { ... } }
663                  *   class A { static foo() { ... } }
664                  */
665                 case "Property":
666                 case "MethodDefinition":
667                     return parent.value !== currentNode;
668
669                 /*
670                  * e.g.
671                  *   obj.foo = function foo() { ... };
672                  *   Foo = function() { ... };
673                  *   [obj.foo = function foo() { ... }] = a;
674                  *   [Foo = function() { ... }] = a;
675                  */
676                 case "AssignmentExpression":
677                 case "AssignmentPattern":
678                     if (parent.left.type === "MemberExpression") {
679                         return false;
680                     }
681                     if (
682                         capIsConstructor &&
683                         isAnonymous &&
684                         parent.left.type === "Identifier" &&
685                         startsWithUpperCase(parent.left.name)
686                     ) {
687                         return false;
688                     }
689                     return true;
690
691                 /*
692                  * e.g.
693                  *   var Foo = function() { ... };
694                  */
695                 case "VariableDeclarator":
696                     return !(
697                         capIsConstructor &&
698                         isAnonymous &&
699                         parent.init === currentNode &&
700                         parent.id.type === "Identifier" &&
701                         startsWithUpperCase(parent.id.name)
702                     );
703
704                 /*
705                  * e.g.
706                  *   var foo = function foo() { ... }.bind(obj);
707                  *   (function foo() { ... }).call(obj);
708                  *   (function foo() { ... }).apply(obj, []);
709                  */
710                 case "MemberExpression":
711                     return (
712                         parent.object !== currentNode ||
713                         parent.property.type !== "Identifier" ||
714                         !bindOrCallOrApplyPattern.test(parent.property.name) ||
715                         !isCallee(parent) ||
716                         parent.parent.arguments.length === 0 ||
717                         isNullOrUndefined(parent.parent.arguments[0])
718                     );
719
720                 /*
721                  * e.g.
722                  *   Reflect.apply(function() {}, obj, []);
723                  *   Array.from([], function() {}, obj);
724                  *   list.forEach(function() {}, obj);
725                  */
726                 case "CallExpression":
727                     if (isReflectApply(parent.callee)) {
728                         return (
729                             parent.arguments.length !== 3 ||
730                             parent.arguments[0] !== currentNode ||
731                             isNullOrUndefined(parent.arguments[1])
732                         );
733                     }
734                     if (isArrayFromMethod(parent.callee)) {
735                         return (
736                             parent.arguments.length !== 3 ||
737                             parent.arguments[1] !== currentNode ||
738                             isNullOrUndefined(parent.arguments[2])
739                         );
740                     }
741                     if (isMethodWhichHasThisArg(parent.callee)) {
742                         return (
743                             parent.arguments.length !== 2 ||
744                             parent.arguments[0] !== currentNode ||
745                             isNullOrUndefined(parent.arguments[1])
746                         );
747                     }
748                     return true;
749
750                 // Otherwise `this` is default.
751                 default:
752                     return true;
753             }
754         }
755
756         /* istanbul ignore next */
757         return true;
758     },
759
760     /**
761      * Get the precedence level based on the node type
762      * @param {ASTNode} node node to evaluate
763      * @returns {int} precedence level
764      * @private
765      */
766     getPrecedence(node) {
767         switch (node.type) {
768             case "SequenceExpression":
769                 return 0;
770
771             case "AssignmentExpression":
772             case "ArrowFunctionExpression":
773             case "YieldExpression":
774                 return 1;
775
776             case "ConditionalExpression":
777                 return 3;
778
779             case "LogicalExpression":
780                 switch (node.operator) {
781                     case "||":
782                         return 4;
783                     case "&&":
784                         return 5;
785
786                     // no default
787                 }
788
789                 /* falls through */
790
791             case "BinaryExpression":
792
793                 switch (node.operator) {
794                     case "|":
795                         return 6;
796                     case "^":
797                         return 7;
798                     case "&":
799                         return 8;
800                     case "==":
801                     case "!=":
802                     case "===":
803                     case "!==":
804                         return 9;
805                     case "<":
806                     case "<=":
807                     case ">":
808                     case ">=":
809                     case "in":
810                     case "instanceof":
811                         return 10;
812                     case "<<":
813                     case ">>":
814                     case ">>>":
815                         return 11;
816                     case "+":
817                     case "-":
818                         return 12;
819                     case "*":
820                     case "/":
821                     case "%":
822                         return 13;
823                     case "**":
824                         return 15;
825
826                     // no default
827                 }
828
829                 /* falls through */
830
831             case "UnaryExpression":
832             case "AwaitExpression":
833                 return 16;
834
835             case "UpdateExpression":
836                 return 17;
837
838             case "CallExpression":
839             case "ImportExpression":
840                 return 18;
841
842             case "NewExpression":
843                 return 19;
844
845             default:
846                 return 20;
847         }
848     },
849
850     /**
851      * Checks whether the given node is an empty block node or not.
852      * @param {ASTNode|null} node The node to check.
853      * @returns {boolean} `true` if the node is an empty block.
854      */
855     isEmptyBlock(node) {
856         return Boolean(node && node.type === "BlockStatement" && node.body.length === 0);
857     },
858
859     /**
860      * Checks whether the given node is an empty function node or not.
861      * @param {ASTNode|null} node The node to check.
862      * @returns {boolean} `true` if the node is an empty function.
863      */
864     isEmptyFunction(node) {
865         return isFunction(node) && module.exports.isEmptyBlock(node.body);
866     },
867
868     /**
869      * Gets the property name of a given node.
870      * The node can be a MemberExpression, a Property, or a MethodDefinition.
871      *
872      * If the name is dynamic, this returns `null`.
873      *
874      * For examples:
875      *
876      *     a.b           // => "b"
877      *     a["b"]        // => "b"
878      *     a['b']        // => "b"
879      *     a[`b`]        // => "b"
880      *     a[100]        // => "100"
881      *     a[b]          // => null
882      *     a["a" + "b"]  // => null
883      *     a[tag`b`]     // => null
884      *     a[`${b}`]     // => null
885      *
886      *     let a = {b: 1}            // => "b"
887      *     let a = {["b"]: 1}        // => "b"
888      *     let a = {['b']: 1}        // => "b"
889      *     let a = {[`b`]: 1}        // => "b"
890      *     let a = {[100]: 1}        // => "100"
891      *     let a = {[b]: 1}          // => null
892      *     let a = {["a" + "b"]: 1}  // => null
893      *     let a = {[tag`b`]: 1}     // => null
894      *     let a = {[`${b}`]: 1}     // => null
895      * @param {ASTNode} node The node to get.
896      * @returns {string|null} The property name if static. Otherwise, null.
897      */
898     getStaticPropertyName(node) {
899         let prop;
900
901         switch (node && node.type) {
902             case "Property":
903             case "MethodDefinition":
904                 prop = node.key;
905                 break;
906
907             case "MemberExpression":
908                 prop = node.property;
909                 break;
910
911             // no default
912         }
913
914         switch (prop && prop.type) {
915             case "Literal":
916                 return String(prop.value);
917
918             case "TemplateLiteral":
919                 if (prop.expressions.length === 0 && prop.quasis.length === 1) {
920                     return prop.quasis[0].value.cooked;
921                 }
922                 break;
923
924             case "Identifier":
925                 if (!node.computed) {
926                     return prop.name;
927                 }
928                 break;
929
930             // no default
931         }
932
933         return null;
934     },
935
936     /**
937      * Get directives from directive prologue of a Program or Function node.
938      * @param {ASTNode} node The node to check.
939      * @returns {ASTNode[]} The directives found in the directive prologue.
940      */
941     getDirectivePrologue(node) {
942         const directives = [];
943
944         // Directive prologues only occur at the top of files or functions.
945         if (
946             node.type === "Program" ||
947             node.type === "FunctionDeclaration" ||
948             node.type === "FunctionExpression" ||
949
950             /*
951              * Do not check arrow functions with implicit return.
952              * `() => "use strict";` returns the string `"use strict"`.
953              */
954             (node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
955         ) {
956             const statements = node.type === "Program" ? node.body : node.body.body;
957
958             for (const statement of statements) {
959                 if (
960                     statement.type === "ExpressionStatement" &&
961                     statement.expression.type === "Literal"
962                 ) {
963                     directives.push(statement);
964                 } else {
965                     break;
966                 }
967             }
968         }
969
970         return directives;
971     },
972
973
974     /**
975      * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
976      * after the node will be parsed as a decimal point, rather than a property-access dot.
977      * @param {ASTNode} node The node to check.
978      * @returns {boolean} `true` if this node is a decimal integer.
979      * @example
980      *
981      * 5       // true
982      * 5.      // false
983      * 5.0     // false
984      * 05      // false
985      * 0x5     // false
986      * 0b101   // false
987      * 0o5     // false
988      * 5e0     // false
989      * '5'     // false
990      */
991     isDecimalInteger(node) {
992         return node.type === "Literal" && typeof node.value === "number" &&
993             DECIMAL_INTEGER_PATTERN.test(node.raw);
994     },
995
996     /**
997      * Determines whether this token is a decimal integer numeric token.
998      * This is similar to isDecimalInteger(), but for tokens.
999      * @param {Token} token The token to check.
1000      * @returns {boolean} `true` if this token is a decimal integer.
1001      */
1002     isDecimalIntegerNumericToken(token) {
1003         return token.type === "Numeric" && DECIMAL_INTEGER_PATTERN.test(token.value);
1004     },
1005
1006     /**
1007      * Gets the name and kind of the given function node.
1008      *
1009      * - `function foo() {}`  .................... `function 'foo'`
1010      * - `(function foo() {})`  .................. `function 'foo'`
1011      * - `(function() {})`  ...................... `function`
1012      * - `function* foo() {}`  ................... `generator function 'foo'`
1013      * - `(function* foo() {})`  ................. `generator function 'foo'`
1014      * - `(function*() {})`  ..................... `generator function`
1015      * - `() => {}`  ............................. `arrow function`
1016      * - `async () => {}`  ....................... `async arrow function`
1017      * - `({ foo: function foo() {} })`  ......... `method 'foo'`
1018      * - `({ foo: function() {} })`  ............. `method 'foo'`
1019      * - `({ ['foo']: function() {} })`  ......... `method 'foo'`
1020      * - `({ [foo]: function() {} })`  ........... `method`
1021      * - `({ foo() {} })`  ....................... `method 'foo'`
1022      * - `({ foo: function* foo() {} })`  ........ `generator method 'foo'`
1023      * - `({ foo: function*() {} })`  ............ `generator method 'foo'`
1024      * - `({ ['foo']: function*() {} })`  ........ `generator method 'foo'`
1025      * - `({ [foo]: function*() {} })`  .......... `generator method`
1026      * - `({ *foo() {} })`  ...................... `generator method 'foo'`
1027      * - `({ foo: async function foo() {} })`  ... `async method 'foo'`
1028      * - `({ foo: async function() {} })`  ....... `async method 'foo'`
1029      * - `({ ['foo']: async function() {} })`  ... `async method 'foo'`
1030      * - `({ [foo]: async function() {} })`  ..... `async method`
1031      * - `({ async foo() {} })`  ................. `async method 'foo'`
1032      * - `({ get foo() {} })`  ................... `getter 'foo'`
1033      * - `({ set foo(a) {} })`  .................. `setter 'foo'`
1034      * - `class A { constructor() {} }`  ......... `constructor`
1035      * - `class A { foo() {} }`  ................. `method 'foo'`
1036      * - `class A { *foo() {} }`  ................ `generator method 'foo'`
1037      * - `class A { async foo() {} }`  ........... `async method 'foo'`
1038      * - `class A { ['foo']() {} }`  ............. `method 'foo'`
1039      * - `class A { *['foo']() {} }`  ............ `generator method 'foo'`
1040      * - `class A { async ['foo']() {} }`  ....... `async method 'foo'`
1041      * - `class A { [foo]() {} }`  ............... `method`
1042      * - `class A { *[foo]() {} }`  .............. `generator method`
1043      * - `class A { async [foo]() {} }`  ......... `async method`
1044      * - `class A { get foo() {} }`  ............. `getter 'foo'`
1045      * - `class A { set foo(a) {} }`  ............ `setter 'foo'`
1046      * - `class A { static foo() {} }`  .......... `static method 'foo'`
1047      * - `class A { static *foo() {} }`  ......... `static generator method 'foo'`
1048      * - `class A { static async foo() {} }`  .... `static async method 'foo'`
1049      * - `class A { static get foo() {} }`  ...... `static getter 'foo'`
1050      * - `class A { static set foo(a) {} }`  ..... `static setter 'foo'`
1051      * @param {ASTNode} node The function node to get.
1052      * @returns {string} The name and kind of the function node.
1053      */
1054     getFunctionNameWithKind(node) {
1055         const parent = node.parent;
1056         const tokens = [];
1057
1058         if (parent.type === "MethodDefinition" && parent.static) {
1059             tokens.push("static");
1060         }
1061         if (node.async) {
1062             tokens.push("async");
1063         }
1064         if (node.generator) {
1065             tokens.push("generator");
1066         }
1067
1068         if (node.type === "ArrowFunctionExpression") {
1069             tokens.push("arrow", "function");
1070         } else if (parent.type === "Property" || parent.type === "MethodDefinition") {
1071             if (parent.kind === "constructor") {
1072                 return "constructor";
1073             }
1074             if (parent.kind === "get") {
1075                 tokens.push("getter");
1076             } else if (parent.kind === "set") {
1077                 tokens.push("setter");
1078             } else {
1079                 tokens.push("method");
1080             }
1081         } else {
1082             tokens.push("function");
1083         }
1084
1085         if (node.id) {
1086             tokens.push(`'${node.id.name}'`);
1087         } else {
1088             const name = module.exports.getStaticPropertyName(parent);
1089
1090             if (name !== null) {
1091                 tokens.push(`'${name}'`);
1092             }
1093         }
1094
1095         return tokens.join(" ");
1096     },
1097
1098     /**
1099      * Gets the location of the given function node for reporting.
1100      *
1101      * - `function foo() {}`
1102      *    ^^^^^^^^^^^^
1103      * - `(function foo() {})`
1104      *     ^^^^^^^^^^^^
1105      * - `(function() {})`
1106      *     ^^^^^^^^
1107      * - `function* foo() {}`
1108      *    ^^^^^^^^^^^^^
1109      * - `(function* foo() {})`
1110      *     ^^^^^^^^^^^^^
1111      * - `(function*() {})`
1112      *     ^^^^^^^^^
1113      * - `() => {}`
1114      *       ^^
1115      * - `async () => {}`
1116      *             ^^
1117      * - `({ foo: function foo() {} })`
1118      *       ^^^^^^^^^^^^^^^^^
1119      * - `({ foo: function() {} })`
1120      *       ^^^^^^^^^^^^^
1121      * - `({ ['foo']: function() {} })`
1122      *       ^^^^^^^^^^^^^^^^^
1123      * - `({ [foo]: function() {} })`
1124      *       ^^^^^^^^^^^^^^^
1125      * - `({ foo() {} })`
1126      *       ^^^
1127      * - `({ foo: function* foo() {} })`
1128      *       ^^^^^^^^^^^^^^^^^^
1129      * - `({ foo: function*() {} })`
1130      *       ^^^^^^^^^^^^^^
1131      * - `({ ['foo']: function*() {} })`
1132      *       ^^^^^^^^^^^^^^^^^^
1133      * - `({ [foo]: function*() {} })`
1134      *       ^^^^^^^^^^^^^^^^
1135      * - `({ *foo() {} })`
1136      *       ^^^^
1137      * - `({ foo: async function foo() {} })`
1138      *       ^^^^^^^^^^^^^^^^^^^^^^^
1139      * - `({ foo: async function() {} })`
1140      *       ^^^^^^^^^^^^^^^^^^^
1141      * - `({ ['foo']: async function() {} })`
1142      *       ^^^^^^^^^^^^^^^^^^^^^^^
1143      * - `({ [foo]: async function() {} })`
1144      *       ^^^^^^^^^^^^^^^^^^^^^
1145      * - `({ async foo() {} })`
1146      *       ^^^^^^^^^
1147      * - `({ get foo() {} })`
1148      *       ^^^^^^^
1149      * - `({ set foo(a) {} })`
1150      *       ^^^^^^^
1151      * - `class A { constructor() {} }`
1152      *              ^^^^^^^^^^^
1153      * - `class A { foo() {} }`
1154      *              ^^^
1155      * - `class A { *foo() {} }`
1156      *              ^^^^
1157      * - `class A { async foo() {} }`
1158      *              ^^^^^^^^^
1159      * - `class A { ['foo']() {} }`
1160      *              ^^^^^^^
1161      * - `class A { *['foo']() {} }`
1162      *              ^^^^^^^^
1163      * - `class A { async ['foo']() {} }`
1164      *              ^^^^^^^^^^^^^
1165      * - `class A { [foo]() {} }`
1166      *              ^^^^^
1167      * - `class A { *[foo]() {} }`
1168      *              ^^^^^^
1169      * - `class A { async [foo]() {} }`
1170      *              ^^^^^^^^^^^
1171      * - `class A { get foo() {} }`
1172      *              ^^^^^^^
1173      * - `class A { set foo(a) {} }`
1174      *              ^^^^^^^
1175      * - `class A { static foo() {} }`
1176      *              ^^^^^^^^^^
1177      * - `class A { static *foo() {} }`
1178      *              ^^^^^^^^^^^
1179      * - `class A { static async foo() {} }`
1180      *              ^^^^^^^^^^^^^^^^
1181      * - `class A { static get foo() {} }`
1182      *              ^^^^^^^^^^^^^^
1183      * - `class A { static set foo(a) {} }`
1184      *              ^^^^^^^^^^^^^^
1185      * @param {ASTNode} node The function node to get.
1186      * @param {SourceCode} sourceCode The source code object to get tokens.
1187      * @returns {string} The location of the function node for reporting.
1188      */
1189     getFunctionHeadLoc(node, sourceCode) {
1190         const parent = node.parent;
1191         let start = null;
1192         let end = null;
1193
1194         if (node.type === "ArrowFunctionExpression") {
1195             const arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken);
1196
1197             start = arrowToken.loc.start;
1198             end = arrowToken.loc.end;
1199         } else if (parent.type === "Property" || parent.type === "MethodDefinition") {
1200             start = parent.loc.start;
1201             end = getOpeningParenOfParams(node, sourceCode).loc.start;
1202         } else {
1203             start = node.loc.start;
1204             end = getOpeningParenOfParams(node, sourceCode).loc.start;
1205         }
1206
1207         return {
1208             start: Object.assign({}, start),
1209             end: Object.assign({}, end)
1210         };
1211     },
1212
1213     /**
1214      * Gets next location when the result is not out of bound, otherwise returns null.
1215      * @param {SourceCode} sourceCode The sourceCode
1216      * @param {{line: number, column: number}} location The location
1217      * @returns {{line: number, column: number} | null} Next location
1218      */
1219     getNextLocation(sourceCode, location) {
1220         const index = sourceCode.getIndexFromLoc(location);
1221
1222         // Avoid out of bound location
1223         if (index + 1 > sourceCode.text.length) {
1224             return null;
1225         }
1226
1227         return sourceCode.getLocFromIndex(index + 1);
1228     },
1229
1230     /**
1231      * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
1232      * surrounding the node.
1233      * @param {SourceCode} sourceCode The source code object
1234      * @param {ASTNode} node An expression node
1235      * @returns {string} The text representing the node, with all surrounding parentheses included
1236      */
1237     getParenthesisedText(sourceCode, node) {
1238         let leftToken = sourceCode.getFirstToken(node);
1239         let rightToken = sourceCode.getLastToken(node);
1240
1241         while (
1242             sourceCode.getTokenBefore(leftToken) &&
1243             sourceCode.getTokenBefore(leftToken).type === "Punctuator" &&
1244             sourceCode.getTokenBefore(leftToken).value === "(" &&
1245             sourceCode.getTokenAfter(rightToken) &&
1246             sourceCode.getTokenAfter(rightToken).type === "Punctuator" &&
1247             sourceCode.getTokenAfter(rightToken).value === ")"
1248         ) {
1249             leftToken = sourceCode.getTokenBefore(leftToken);
1250             rightToken = sourceCode.getTokenAfter(rightToken);
1251         }
1252
1253         return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]);
1254     },
1255
1256     /*
1257      * Determine if a node has a possiblity to be an Error object
1258      * @param  {ASTNode} node  ASTNode to check
1259      * @returns {boolean} True if there is a chance it contains an Error obj
1260      */
1261     couldBeError(node) {
1262         switch (node.type) {
1263             case "Identifier":
1264             case "CallExpression":
1265             case "NewExpression":
1266             case "MemberExpression":
1267             case "TaggedTemplateExpression":
1268             case "YieldExpression":
1269             case "AwaitExpression":
1270                 return true; // possibly an error object.
1271
1272             case "AssignmentExpression":
1273                 return module.exports.couldBeError(node.right);
1274
1275             case "SequenceExpression": {
1276                 const exprs = node.expressions;
1277
1278                 return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]);
1279             }
1280
1281             case "LogicalExpression":
1282                 return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right);
1283
1284             case "ConditionalExpression":
1285                 return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate);
1286
1287             default:
1288                 return false;
1289         }
1290     },
1291
1292     /**
1293      * Determines whether the given node is a `null` literal.
1294      * @param {ASTNode} node The node to check
1295      * @returns {boolean} `true` if the node is a `null` literal
1296      */
1297     isNullLiteral(node) {
1298
1299         /*
1300          * Checking `node.value === null` does not guarantee that a literal is a null literal.
1301          * When parsing values that cannot be represented in the current environment (e.g. unicode
1302          * regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to
1303          * set `node.value` to a unicode regex. To make sure a literal is actually `null`, check
1304          * `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020
1305          */
1306         return node.type === "Literal" && node.value === null && !node.regex && !node.bigint;
1307     },
1308
1309     /**
1310      * Determines whether two tokens can safely be placed next to each other without merging into a single token
1311      * @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used.
1312      * @param {Token|string} rightValue The right token. If this is a string, it will be tokenized and the first token will be used.
1313      * @returns {boolean} If the tokens cannot be safely placed next to each other, returns `false`. If the tokens can be placed
1314      * next to each other, behavior is undefined (although it should return `true` in most cases).
1315      */
1316     canTokensBeAdjacent(leftValue, rightValue) {
1317         let leftToken;
1318
1319         if (typeof leftValue === "string") {
1320             const leftTokens = espree.tokenize(leftValue, { ecmaVersion: 2015 });
1321
1322             leftToken = leftTokens[leftTokens.length - 1];
1323         } else {
1324             leftToken = leftValue;
1325         }
1326
1327         const rightToken = typeof rightValue === "string" ? espree.tokenize(rightValue, { ecmaVersion: 2015 })[0] : rightValue;
1328
1329         if (leftToken.type === "Punctuator" || rightToken.type === "Punctuator") {
1330             if (leftToken.type === "Punctuator" && rightToken.type === "Punctuator") {
1331                 const PLUS_TOKENS = new Set(["+", "++"]);
1332                 const MINUS_TOKENS = new Set(["-", "--"]);
1333
1334                 return !(
1335                     PLUS_TOKENS.has(leftToken.value) && PLUS_TOKENS.has(rightToken.value) ||
1336                     MINUS_TOKENS.has(leftToken.value) && MINUS_TOKENS.has(rightToken.value)
1337                 );
1338             }
1339             return true;
1340         }
1341
1342         if (
1343             leftToken.type === "String" || rightToken.type === "String" ||
1344             leftToken.type === "Template" || rightToken.type === "Template"
1345         ) {
1346             return true;
1347         }
1348
1349         if (leftToken.type !== "Numeric" && rightToken.type === "Numeric" && rightToken.value.startsWith(".")) {
1350             return true;
1351         }
1352
1353         return false;
1354     },
1355
1356     /**
1357      * Get the `loc` object of a given name in a `/*globals` directive comment.
1358      * @param {SourceCode} sourceCode The source code to convert index to loc.
1359      * @param {Comment} comment The `/*globals` directive comment which include the name.
1360      * @param {string} name The name to find.
1361      * @returns {SourceLocation} The `loc` object.
1362      */
1363     getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) {
1364         const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(name)}(?:$|[\\s,:])`, "gu");
1365
1366         // To ignore the first text "global".
1367         namePattern.lastIndex = comment.value.indexOf("global") + 6;
1368
1369         // Search a given variable name.
1370         const match = namePattern.exec(comment.value);
1371
1372         // Convert the index to loc.
1373         return sourceCode.getLocFromIndex(
1374             comment.range[0] +
1375             "/*".length +
1376             (match ? match.index + 1 : 0)
1377         );
1378     },
1379
1380     /**
1381      * Determines whether the given raw string contains an octal escape sequence.
1382      *
1383      * "\1", "\2" ... "\7"
1384      * "\00", "\01" ... "\09"
1385      *
1386      * "\0", when not followed by a digit, is not an octal escape sequence.
1387      * @param {string} rawString A string in its raw representation.
1388      * @returns {boolean} `true` if the string contains at least one octal escape sequence.
1389      */
1390     hasOctalEscapeSequence(rawString) {
1391         return OCTAL_ESCAPE_PATTERN.test(rawString);
1392     }
1393 };