update socials section
This commit is contained in:
		
							
								
								
									
										346
									
								
								node_modules/eslint/lib/rules/accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								node_modules/eslint/lib/rules/accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,346 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce getter and setter pairs in objects and classes. | ||||
|  * @author Gyandeep Singh | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Typedefs | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Property name if it can be computed statically, otherwise the list of the tokens of the key node. | ||||
|  * @typedef {string|Token[]} Key | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Accessor nodes with the same key. | ||||
|  * @typedef {Object} AccessorData | ||||
|  * @property {Key} key Accessor's key | ||||
|  * @property {ASTNode[]} getters List of getter nodes. | ||||
|  * @property {ASTNode[]} setters List of setter nodes. | ||||
|  */ | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not the given lists represent the equal tokens in the same order. | ||||
|  * Tokens are compared by their properties, not by instance. | ||||
|  * @param {Token[]} left First list of tokens. | ||||
|  * @param {Token[]} right Second list of tokens. | ||||
|  * @returns {boolean} `true` if the lists have same tokens. | ||||
|  */ | ||||
| function areEqualTokenLists(left, right) { | ||||
|     if (left.length !== right.length) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     for (let i = 0; i < left.length; i++) { | ||||
|         const leftToken = left[i], | ||||
|             rightToken = right[i]; | ||||
|  | ||||
|         if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not the given keys are equal. | ||||
|  * @param {Key} left First key. | ||||
|  * @param {Key} right Second key. | ||||
|  * @returns {boolean} `true` if the keys are equal. | ||||
|  */ | ||||
| function areEqualKeys(left, right) { | ||||
|     if (typeof left === "string" && typeof right === "string") { | ||||
|  | ||||
|         // Statically computed names. | ||||
|         return left === right; | ||||
|     } | ||||
|     if (Array.isArray(left) && Array.isArray(right)) { | ||||
|  | ||||
|         // Token lists. | ||||
|         return areEqualTokenLists(left, right); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is of an accessor kind ('get' or 'set'). | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if the node is of an accessor kind. | ||||
|  */ | ||||
| function isAccessorKind(node) { | ||||
|     return node.kind === "get" || node.kind === "set"; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is an argument of a specified method call. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @param {number} index An expected index of the node in arguments. | ||||
|  * @param {string} object An expected name of the object of the method. | ||||
|  * @param {string} property An expected name of the method. | ||||
|  * @returns {boolean} `true` if the node is an argument of the specified method call. | ||||
|  */ | ||||
| function isArgumentOfMethodCall(node, index, object, property) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         parent.type === "CallExpression" && | ||||
|         astUtils.isSpecificMemberAccess(parent.callee, object, property) && | ||||
|         parent.arguments[index] === node | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is a property descriptor. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if the node is a property descriptor. | ||||
|  */ | ||||
| function isPropertyDescriptor(node) { | ||||
|  | ||||
|     // Object.defineProperty(obj, "foo", {set: ...}) | ||||
|     if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") || | ||||
|         isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty") | ||||
|     ) { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * Object.defineProperties(obj, {foo: {set: ...}}) | ||||
|      * Object.create(proto, {foo: {set: ...}}) | ||||
|      */ | ||||
|     const grandparent = node.parent.parent; | ||||
|  | ||||
|     return grandparent.type === "ObjectExpression" && ( | ||||
|         isArgumentOfMethodCall(grandparent, 1, "Object", "create") || | ||||
|         isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties") | ||||
|     ); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce getter and setter pairs in objects and classes", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/accessor-pairs" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 getWithoutSet: { | ||||
|                     type: "boolean", | ||||
|                     default: false | ||||
|                 }, | ||||
|                 setWithoutGet: { | ||||
|                     type: "boolean", | ||||
|                     default: true | ||||
|                 }, | ||||
|                 enforceForClassMembers: { | ||||
|                     type: "boolean", | ||||
|                     default: true | ||||
|                 } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.", | ||||
|             missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.", | ||||
|             missingGetterInObjectLiteral: "Getter is not present for {{ name }}.", | ||||
|             missingSetterInObjectLiteral: "Setter is not present for {{ name }}.", | ||||
|             missingGetterInClass: "Getter is not present for class {{ name }}.", | ||||
|             missingSetterInClass: "Setter is not present for class {{ name }}." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|         const config = context.options[0] || {}; | ||||
|         const checkGetWithoutSet = config.getWithoutSet === true; | ||||
|         const checkSetWithoutGet = config.setWithoutGet !== false; | ||||
|         const enforceForClassMembers = config.enforceForClassMembers !== false; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Reports the given node. | ||||
|          * @param {ASTNode} node The node to report. | ||||
|          * @param {string} messageKind "missingGetter" or "missingSetter". | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node, messageKind) { | ||||
|             if (node.type === "Property") { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: `${messageKind}InObjectLiteral`, | ||||
|                     loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), | ||||
|                     data: { name: astUtils.getFunctionNameWithKind(node.value) } | ||||
|                 }); | ||||
|             } else if (node.type === "MethodDefinition") { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: `${messageKind}InClass`, | ||||
|                     loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), | ||||
|                     data: { name: astUtils.getFunctionNameWithKind(node.value) } | ||||
|                 }); | ||||
|             } else { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: `${messageKind}InPropertyDescriptor` | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports each of the nodes in the given list using the same messageId. | ||||
|          * @param {ASTNode[]} nodes Nodes to report. | ||||
|          * @param {string} messageKind "missingGetter" or "missingSetter". | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function reportList(nodes, messageKind) { | ||||
|             for (const node of nodes) { | ||||
|                 report(node, messageKind); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks accessor pairs in the given list of nodes. | ||||
|          * @param {ASTNode[]} nodes The list to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkList(nodes) { | ||||
|             const accessors = []; | ||||
|             let found = false; | ||||
|  | ||||
|             for (let i = 0; i < nodes.length; i++) { | ||||
|                 const node = nodes[i]; | ||||
|  | ||||
|                 if (isAccessorKind(node)) { | ||||
|  | ||||
|                     // Creates a new `AccessorData` object for the given getter or setter node. | ||||
|                     const name = astUtils.getStaticPropertyName(node); | ||||
|                     const key = (name !== null) ? name : sourceCode.getTokens(node.key); | ||||
|  | ||||
|                     // Merges the given `AccessorData` object into the given accessors list. | ||||
|                     for (let j = 0; j < accessors.length; j++) { | ||||
|                         const accessor = accessors[j]; | ||||
|  | ||||
|                         if (areEqualKeys(accessor.key, key)) { | ||||
|                             accessor.getters.push(...node.kind === "get" ? [node] : []); | ||||
|                             accessor.setters.push(...node.kind === "set" ? [node] : []); | ||||
|                             found = true; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     if (!found) { | ||||
|                         accessors.push({ | ||||
|                             key, | ||||
|                             getters: node.kind === "get" ? [node] : [], | ||||
|                             setters: node.kind === "set" ? [node] : [] | ||||
|                         }); | ||||
|                     } | ||||
|                     found = false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for (const { getters, setters } of accessors) { | ||||
|                 if (checkSetWithoutGet && setters.length && !getters.length) { | ||||
|                     reportList(setters, "missingGetter"); | ||||
|                 } | ||||
|                 if (checkGetWithoutSet && getters.length && !setters.length) { | ||||
|                     reportList(getters, "missingSetter"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks accessor pairs in an object literal. | ||||
|          * @param {ASTNode} node `ObjectExpression` node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkObjectLiteral(node) { | ||||
|             checkList(node.properties.filter(p => p.type === "Property")); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks accessor pairs in a property descriptor. | ||||
|          * @param {ASTNode} node Property descriptor `ObjectExpression` node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkPropertyDescriptor(node) { | ||||
|             const namesToCheck = new Set(node.properties | ||||
|                 .filter(p => p.type === "Property" && p.kind === "init" && !p.computed) | ||||
|                 .map(({ key }) => key.name)); | ||||
|  | ||||
|             const hasGetter = namesToCheck.has("get"); | ||||
|             const hasSetter = namesToCheck.has("set"); | ||||
|  | ||||
|             if (checkSetWithoutGet && hasSetter && !hasGetter) { | ||||
|                 report(node, "missingGetter"); | ||||
|             } | ||||
|             if (checkGetWithoutSet && hasGetter && !hasSetter) { | ||||
|                 report(node, "missingSetter"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks the given object expression as an object literal and as a possible property descriptor. | ||||
|          * @param {ASTNode} node `ObjectExpression` node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkObjectExpression(node) { | ||||
|             checkObjectLiteral(node); | ||||
|             if (isPropertyDescriptor(node)) { | ||||
|                 checkPropertyDescriptor(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks the given class body. | ||||
|          * @param {ASTNode} node `ClassBody` node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkClassBody(node) { | ||||
|             const methodDefinitions = node.body.filter(m => m.type === "MethodDefinition"); | ||||
|  | ||||
|             checkList(methodDefinitions.filter(m => m.static)); | ||||
|             checkList(methodDefinitions.filter(m => !m.static)); | ||||
|         } | ||||
|  | ||||
|         const listeners = {}; | ||||
|  | ||||
|         if (checkSetWithoutGet || checkGetWithoutSet) { | ||||
|             listeners.ObjectExpression = checkObjectExpression; | ||||
|             if (enforceForClassMembers) { | ||||
|                 listeners.ClassBody = checkClassBody; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return listeners; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										261
									
								
								node_modules/eslint/lib/rules/array-bracket-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								node_modules/eslint/lib/rules/array-bracket-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce linebreaks after open and before close array brackets | ||||
|  * @author Jan Peer Stöcklmair <https://github.com/JPeer264> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce linebreaks after opening and before closing array brackets", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/array-bracket-newline" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         enum: ["always", "never", "consistent"] | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             multiline: { | ||||
|                                 type: "boolean" | ||||
|                             }, | ||||
|                             minItems: { | ||||
|                                 type: ["integer", "null"], | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedOpeningLinebreak: "There should be no linebreak after '['.", | ||||
|             unexpectedClosingLinebreak: "There should be no linebreak before ']'.", | ||||
|             missingOpeningLinebreak: "A linebreak is required after '['.", | ||||
|             missingClosingLinebreak: "A linebreak is required before ']'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Normalizes a given option value. | ||||
|          * @param {string|Object|undefined} option An option value to parse. | ||||
|          * @returns {{multiline: boolean, minItems: number}} Normalized option object. | ||||
|          */ | ||||
|         function normalizeOptionValue(option) { | ||||
|             let consistent = false; | ||||
|             let multiline = false; | ||||
|             let minItems = 0; | ||||
|  | ||||
|             if (option) { | ||||
|                 if (option === "consistent") { | ||||
|                     consistent = true; | ||||
|                     minItems = Number.POSITIVE_INFINITY; | ||||
|                 } else if (option === "always" || option.minItems === 0) { | ||||
|                     minItems = 0; | ||||
|                 } else if (option === "never") { | ||||
|                     minItems = Number.POSITIVE_INFINITY; | ||||
|                 } else { | ||||
|                     multiline = Boolean(option.multiline); | ||||
|                     minItems = option.minItems || Number.POSITIVE_INFINITY; | ||||
|                 } | ||||
|             } else { | ||||
|                 consistent = false; | ||||
|                 multiline = true; | ||||
|                 minItems = Number.POSITIVE_INFINITY; | ||||
|             } | ||||
|  | ||||
|             return { consistent, multiline, minItems }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Normalizes a given option value. | ||||
|          * @param {string|Object|undefined} options An option value to parse. | ||||
|          * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. | ||||
|          */ | ||||
|         function normalizeOptions(options) { | ||||
|             const value = normalizeOptionValue(options); | ||||
|  | ||||
|             return { ArrayExpression: value, ArrayPattern: value }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a linebreak after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoBeginningLinebreak(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "unexpectedOpeningLinebreak", | ||||
|                 fix(fixer) { | ||||
|                     const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }); | ||||
|  | ||||
|                     if (astUtils.isCommentToken(nextToken)) { | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     return fixer.removeRange([token.range[1], nextToken.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a linebreak before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoEndingLinebreak(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "unexpectedClosingLinebreak", | ||||
|                 fix(fixer) { | ||||
|                     const previousToken = sourceCode.getTokenBefore(token, { includeComments: true }); | ||||
|  | ||||
|                     if (astUtils.isCommentToken(previousToken)) { | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     return fixer.removeRange([previousToken.range[1], token.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a linebreak after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredBeginningLinebreak(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingOpeningLinebreak", | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextAfter(token, "\n"); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a linebreak before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredEndingLinebreak(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingClosingLinebreak", | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextBefore(token, "\n"); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given node if it violated this rule. | ||||
|          * @param {ASTNode} node A node to check. This is an ArrayExpression node or an ArrayPattern node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function check(node) { | ||||
|             const elements = node.elements; | ||||
|             const normalizedOptions = normalizeOptions(context.options[0]); | ||||
|             const options = normalizedOptions[node.type]; | ||||
|             const openBracket = sourceCode.getFirstToken(node); | ||||
|             const closeBracket = sourceCode.getLastToken(node); | ||||
|             const firstIncComment = sourceCode.getTokenAfter(openBracket, { includeComments: true }); | ||||
|             const lastIncComment = sourceCode.getTokenBefore(closeBracket, { includeComments: true }); | ||||
|             const first = sourceCode.getTokenAfter(openBracket); | ||||
|             const last = sourceCode.getTokenBefore(closeBracket); | ||||
|  | ||||
|             const needsLinebreaks = ( | ||||
|                 elements.length >= options.minItems || | ||||
|                 ( | ||||
|                     options.multiline && | ||||
|                     elements.length > 0 && | ||||
|                     firstIncComment.loc.start.line !== lastIncComment.loc.end.line | ||||
|                 ) || | ||||
|                 ( | ||||
|                     elements.length === 0 && | ||||
|                     firstIncComment.type === "Block" && | ||||
|                     firstIncComment.loc.start.line !== lastIncComment.loc.end.line && | ||||
|                     firstIncComment === lastIncComment | ||||
|                 ) || | ||||
|                 ( | ||||
|                     options.consistent && | ||||
|                     openBracket.loc.end.line !== first.loc.start.line | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             /* | ||||
|              * Use tokens or comments to check multiline or not. | ||||
|              * But use only tokens to check whether linebreaks are needed. | ||||
|              * This allows: | ||||
|              *     var arr = [ // eslint-disable-line foo | ||||
|              *         'a' | ||||
|              *     ] | ||||
|              */ | ||||
|  | ||||
|             if (needsLinebreaks) { | ||||
|                 if (astUtils.isTokenOnSameLine(openBracket, first)) { | ||||
|                     reportRequiredBeginningLinebreak(node, openBracket); | ||||
|                 } | ||||
|                 if (astUtils.isTokenOnSameLine(last, closeBracket)) { | ||||
|                     reportRequiredEndingLinebreak(node, closeBracket); | ||||
|                 } | ||||
|             } else { | ||||
|                 if (!astUtils.isTokenOnSameLine(openBracket, first)) { | ||||
|                     reportNoBeginningLinebreak(node, openBracket); | ||||
|                 } | ||||
|                 if (!astUtils.isTokenOnSameLine(last, closeBracket)) { | ||||
|                     reportNoEndingLinebreak(node, closeBracket); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ArrayPattern: check, | ||||
|             ArrayExpression: check | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										244
									
								
								node_modules/eslint/lib/rules/array-bracket-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								node_modules/eslint/lib/rules/array-bracket-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| /** | ||||
|  * @fileoverview Disallows or enforces spaces inside of array brackets. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing inside array brackets", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/array-bracket-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "never"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     singleValue: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     objectsInArrays: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     arraysInArrays: { | ||||
|                         type: "boolean" | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", | ||||
|             unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", | ||||
|             missingSpaceAfter: "A space is required after '{{tokenValue}}'.", | ||||
|             missingSpaceBefore: "A space is required before '{{tokenValue}}'." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|         const spaced = context.options[0] === "always", | ||||
|             sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Determines whether an option is set, relative to the spacing option. | ||||
|          * If spaced is "always", then check whether option is set to false. | ||||
|          * If spaced is "never", then check whether option is set to true. | ||||
|          * @param {Object} option The option to exclude. | ||||
|          * @returns {boolean} Whether or not the property is excluded. | ||||
|          */ | ||||
|         function isOptionSet(option) { | ||||
|             return context.options[1] ? context.options[1][option] === !spaced : false; | ||||
|         } | ||||
|  | ||||
|         const options = { | ||||
|             spaced, | ||||
|             singleElementException: isOptionSet("singleValue"), | ||||
|             objectsInArraysException: isOptionSet("objectsInArrays"), | ||||
|             arraysInArraysException: isOptionSet("arraysInArrays") | ||||
|         }; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a space after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoBeginningSpace(node, token) { | ||||
|             const nextToken = sourceCode.getTokenAfter(token); | ||||
|  | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: { start: token.loc.end, end: nextToken.loc.start }, | ||||
|                 messageId: "unexpectedSpaceAfter", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.removeRange([token.range[1], nextToken.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a space before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoEndingSpace(node, token) { | ||||
|             const previousToken = sourceCode.getTokenBefore(token); | ||||
|  | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: { start: previousToken.loc.end, end: token.loc.start }, | ||||
|                 messageId: "unexpectedSpaceBefore", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.removeRange([previousToken.range[1], token.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a space after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredBeginningSpace(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingSpaceAfter", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextAfter(token, " "); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a space before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredEndingSpace(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingSpaceBefore", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextBefore(token, " "); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines if a node is an object type | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} Whether or not the node is an object type. | ||||
|          */ | ||||
|         function isObjectType(node) { | ||||
|             return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines if a node is an array type | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} Whether or not the node is an array type. | ||||
|          */ | ||||
|         function isArrayType(node) { | ||||
|             return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates the spacing around array brackets | ||||
|          * @param {ASTNode} node The node we're checking for spacing | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateArraySpacing(node) { | ||||
|             if (options.spaced && node.elements.length === 0) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const first = sourceCode.getFirstToken(node), | ||||
|                 second = sourceCode.getFirstToken(node, 1), | ||||
|                 last = node.typeAnnotation | ||||
|                     ? sourceCode.getTokenBefore(node.typeAnnotation) | ||||
|                     : sourceCode.getLastToken(node), | ||||
|                 penultimate = sourceCode.getTokenBefore(last), | ||||
|                 firstElement = node.elements[0], | ||||
|                 lastElement = node.elements[node.elements.length - 1]; | ||||
|  | ||||
|             const openingBracketMustBeSpaced = | ||||
|                 options.objectsInArraysException && isObjectType(firstElement) || | ||||
|                 options.arraysInArraysException && isArrayType(firstElement) || | ||||
|                 options.singleElementException && node.elements.length === 1 | ||||
|                     ? !options.spaced : options.spaced; | ||||
|  | ||||
|             const closingBracketMustBeSpaced = | ||||
|                 options.objectsInArraysException && isObjectType(lastElement) || | ||||
|                 options.arraysInArraysException && isArrayType(lastElement) || | ||||
|                 options.singleElementException && node.elements.length === 1 | ||||
|                     ? !options.spaced : options.spaced; | ||||
|  | ||||
|             if (astUtils.isTokenOnSameLine(first, second)) { | ||||
|                 if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { | ||||
|                     reportRequiredBeginningSpace(node, first); | ||||
|                 } | ||||
|                 if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { | ||||
|                     reportNoBeginningSpace(node, first); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) { | ||||
|                 if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { | ||||
|                     reportRequiredEndingSpace(node, last); | ||||
|                 } | ||||
|                 if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { | ||||
|                     reportNoEndingSpace(node, last); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ArrayPattern: validateArraySpacing, | ||||
|             ArrayExpression: validateArraySpacing | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										446
									
								
								node_modules/eslint/lib/rules/array-callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								node_modules/eslint/lib/rules/array-callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,446 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce return statements in callbacks of array's methods | ||||
|  * @author Toru Nagashima | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u; | ||||
| const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u; | ||||
|  | ||||
| /** | ||||
|  * Checks a given node is a member access which has the specified name's | ||||
|  * property. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if the node is a member access which has | ||||
|  *      the specified name's property. The node may be a `(Chain|Member)Expression` node. | ||||
|  */ | ||||
| function isTargetMethod(node) { | ||||
|     return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks all segments in a set and returns true if any are reachable. | ||||
|  * @param {Set<CodePathSegment>} segments The segments to check. | ||||
|  * @returns {boolean} True if any segment is reachable; false otherwise. | ||||
|  */ | ||||
| function isAnySegmentReachable(segments) { | ||||
|  | ||||
|     for (const segment of segments) { | ||||
|         if (segment.reachable) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns a human-legible description of an array method | ||||
|  * @param {string} arrayMethodName A method name to fully qualify | ||||
|  * @returns {string} the method name prefixed with `Array.` if it is a class method, | ||||
|  *      or else `Array.prototype.` if it is an instance method. | ||||
|  */ | ||||
| function fullMethodName(arrayMethodName) { | ||||
|     if (["from", "of", "isArray"].includes(arrayMethodName)) { | ||||
|         return "Array.".concat(arrayMethodName); | ||||
|     } | ||||
|     return "Array.prototype.".concat(arrayMethodName); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is a function expression which is the | ||||
|  * callback of an array method, returning the method name. | ||||
|  * @param {ASTNode} node A node to check. This is one of | ||||
|  *      FunctionExpression or ArrowFunctionExpression. | ||||
|  * @returns {string} The method name if the node is a callback method, | ||||
|  *      null otherwise. | ||||
|  */ | ||||
| function getArrayMethodName(node) { | ||||
|     let currentNode = node; | ||||
|  | ||||
|     while (currentNode) { | ||||
|         const parent = currentNode.parent; | ||||
|  | ||||
|         switch (parent.type) { | ||||
|  | ||||
|             /* | ||||
|              * Looks up the destination. e.g., | ||||
|              * foo.every(nativeFoo || function foo() { ... }); | ||||
|              */ | ||||
|             case "LogicalExpression": | ||||
|             case "ConditionalExpression": | ||||
|             case "ChainExpression": | ||||
|                 currentNode = parent; | ||||
|                 break; | ||||
|  | ||||
|             /* | ||||
|              * If the upper function is IIFE, checks the destination of the return value. | ||||
|              * e.g. | ||||
|              *   foo.every((function() { | ||||
|              *     // setup... | ||||
|              *     return function callback() { ... }; | ||||
|              *   })()); | ||||
|              */ | ||||
|             case "ReturnStatement": { | ||||
|                 const func = astUtils.getUpperFunction(parent); | ||||
|  | ||||
|                 if (func === null || !astUtils.isCallee(func)) { | ||||
|                     return null; | ||||
|                 } | ||||
|                 currentNode = func.parent; | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * e.g. | ||||
|              *   Array.from([], function() {}); | ||||
|              *   list.every(function() {}); | ||||
|              */ | ||||
|             case "CallExpression": | ||||
|                 if (astUtils.isArrayFromMethod(parent.callee)) { | ||||
|                     if ( | ||||
|                         parent.arguments.length >= 2 && | ||||
|                         parent.arguments[1] === currentNode | ||||
|                     ) { | ||||
|                         return "from"; | ||||
|                     } | ||||
|                 } | ||||
|                 if (isTargetMethod(parent.callee)) { | ||||
|                     if ( | ||||
|                         parent.arguments.length >= 1 && | ||||
|                         parent.arguments[0] === currentNode | ||||
|                     ) { | ||||
|                         return astUtils.getStaticPropertyName(parent.callee); | ||||
|                     } | ||||
|                 } | ||||
|                 return null; | ||||
|  | ||||
|             // Otherwise this node is not target. | ||||
|             default: | ||||
|                 return null; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* c8 ignore next */ | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if the given node is a void expression. | ||||
|  * @param {ASTNode} node The node to check. | ||||
|  * @returns {boolean} - `true` if the node is a void expression | ||||
|  */ | ||||
| function isExpressionVoid(node) { | ||||
|     return node.type === "UnaryExpression" && node.operator === "void"; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Fixes the linting error by prepending "void " to the given node | ||||
|  * @param {Object} sourceCode context given by context.sourceCode | ||||
|  * @param {ASTNode} node The node to fix. | ||||
|  * @param {Object} fixer The fixer object provided by ESLint. | ||||
|  * @returns {Array<Object>} - An array of fix objects to apply to the node. | ||||
|  */ | ||||
| function voidPrependFixer(sourceCode, node, fixer) { | ||||
|  | ||||
|     const requiresParens = | ||||
|  | ||||
|         // prepending `void ` will fail if the node has a lower precedence than void | ||||
|         astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression", operator: "void" }) && | ||||
|  | ||||
|         // check if there are parentheses around the node to avoid redundant parentheses | ||||
|         !astUtils.isParenthesised(sourceCode, node); | ||||
|  | ||||
|     // avoid parentheses issues | ||||
|     const returnOrArrowToken = sourceCode.getTokenBefore( | ||||
|         node, | ||||
|         node.parent.type === "ArrowFunctionExpression" | ||||
|             ? astUtils.isArrowToken | ||||
|  | ||||
|             // isReturnToken | ||||
|             : token => token.type === "Keyword" && token.value === "return" | ||||
|     ); | ||||
|  | ||||
|     const firstToken = sourceCode.getTokenAfter(returnOrArrowToken); | ||||
|  | ||||
|     const prependSpace = | ||||
|  | ||||
|         // is return token, as => allows void to be adjacent | ||||
|         returnOrArrowToken.value === "return" && | ||||
|  | ||||
|         // If two tokens (return and "(") are adjacent | ||||
|         returnOrArrowToken.range[1] === firstToken.range[0]; | ||||
|  | ||||
|     return [ | ||||
|         fixer.insertTextBefore(firstToken, `${prependSpace ? " " : ""}void ${requiresParens ? "(" : ""}`), | ||||
|         fixer.insertTextAfter(node, requiresParens ? ")" : "") | ||||
|     ]; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Fixes the linting error by `wrapping {}` around the given node's body. | ||||
|  * @param {Object} sourceCode context given by context.sourceCode | ||||
|  * @param {ASTNode} node The node to fix. | ||||
|  * @param {Object} fixer The fixer object provided by ESLint. | ||||
|  * @returns {Array<Object>} - An array of fix objects to apply to the node. | ||||
|  */ | ||||
| function curlyWrapFixer(sourceCode, node, fixer) { | ||||
|     const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); | ||||
|     const firstToken = sourceCode.getTokenAfter(arrowToken); | ||||
|     const lastToken = sourceCode.getLastToken(node); | ||||
|  | ||||
|     return [ | ||||
|         fixer.insertTextBefore(firstToken, "{"), | ||||
|         fixer.insertTextAfter(lastToken, "}") | ||||
|     ]; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce `return` statements in callbacks of array methods", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/array-callback-return" | ||||
|         }, | ||||
|  | ||||
|         // eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- false positive | ||||
|         hasSuggestions: true, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allowImplicit: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     checkForEach: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     allowVoid: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.", | ||||
|             expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.", | ||||
|             expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.", | ||||
|             expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}.", | ||||
|             wrapBraces: "Wrap the expression in `{}`.", | ||||
|             prependVoid: "Prepend `void` to the expression." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false }; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let funcInfo = { | ||||
|             arrayMethodName: null, | ||||
|             upper: null, | ||||
|             codePath: null, | ||||
|             hasReturn: false, | ||||
|             shouldCheck: false, | ||||
|             node: null | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether or not the last code path segment is reachable. | ||||
|          * Then reports this function if the segment is reachable. | ||||
|          * | ||||
|          * If the last code path segment is reachable, there are paths which are not | ||||
|          * returned or thrown. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkLastSegment(node) { | ||||
|  | ||||
|             if (!funcInfo.shouldCheck) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const messageAndSuggestions = { messageId: "", suggest: [] }; | ||||
|  | ||||
|             if (funcInfo.arrayMethodName === "forEach") { | ||||
|                 if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) { | ||||
|  | ||||
|                     if (options.allowVoid) { | ||||
|                         if (isExpressionVoid(node.body)) { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         messageAndSuggestions.messageId = "expectedNoReturnValue"; | ||||
|                         messageAndSuggestions.suggest = [ | ||||
|                             { | ||||
|                                 messageId: "wrapBraces", | ||||
|                                 fix(fixer) { | ||||
|                                     return curlyWrapFixer(sourceCode, node, fixer); | ||||
|                                 } | ||||
|                             }, | ||||
|                             { | ||||
|                                 messageId: "prependVoid", | ||||
|                                 fix(fixer) { | ||||
|                                     return voidPrependFixer(sourceCode, node.body, fixer); | ||||
|                                 } | ||||
|                             } | ||||
|                         ]; | ||||
|                     } else { | ||||
|                         messageAndSuggestions.messageId = "expectedNoReturnValue"; | ||||
|                         messageAndSuggestions.suggest = [{ | ||||
|                             messageId: "wrapBraces", | ||||
|                             fix(fixer) { | ||||
|                                 return curlyWrapFixer(sourceCode, node, fixer); | ||||
|                             } | ||||
|                         }]; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) { | ||||
|                     messageAndSuggestions.messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside"; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (messageAndSuggestions.messageId) { | ||||
|                 const name = astUtils.getFunctionNameWithKind(node); | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: astUtils.getFunctionHeadLoc(node, sourceCode), | ||||
|                     messageId: messageAndSuggestions.messageId, | ||||
|                     data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) }, | ||||
|                     suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             // Stacks this function's information. | ||||
|             onCodePathStart(codePath, node) { | ||||
|  | ||||
|                 let methodName = null; | ||||
|  | ||||
|                 if (TARGET_NODE_TYPE.test(node.type)) { | ||||
|                     methodName = getArrayMethodName(node); | ||||
|                 } | ||||
|  | ||||
|                 funcInfo = { | ||||
|                     arrayMethodName: methodName, | ||||
|                     upper: funcInfo, | ||||
|                     codePath, | ||||
|                     hasReturn: false, | ||||
|                     shouldCheck: | ||||
|                         methodName && | ||||
|                         !node.async && | ||||
|                         !node.generator, | ||||
|                     node, | ||||
|                     currentSegments: new Set() | ||||
|                 }; | ||||
|             }, | ||||
|  | ||||
|             // Pops this function's information. | ||||
|             onCodePathEnd() { | ||||
|                 funcInfo = funcInfo.upper; | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|  | ||||
|             // Checks the return statement is valid. | ||||
|             ReturnStatement(node) { | ||||
|  | ||||
|                 if (!funcInfo.shouldCheck) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 funcInfo.hasReturn = true; | ||||
|  | ||||
|                 const messageAndSuggestions = { messageId: "", suggest: [] }; | ||||
|  | ||||
|                 if (funcInfo.arrayMethodName === "forEach") { | ||||
|  | ||||
|                     // if checkForEach: true, returning a value at any path inside a forEach is not allowed | ||||
|                     if (options.checkForEach && node.argument) { | ||||
|  | ||||
|                         if (options.allowVoid) { | ||||
|                             if (isExpressionVoid(node.argument)) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             messageAndSuggestions.messageId = "expectedNoReturnValue"; | ||||
|                             messageAndSuggestions.suggest = [{ | ||||
|                                 messageId: "prependVoid", | ||||
|                                 fix(fixer) { | ||||
|                                     return voidPrependFixer(sourceCode, node.argument, fixer); | ||||
|                                 } | ||||
|                             }]; | ||||
|                         } else { | ||||
|                             messageAndSuggestions.messageId = "expectedNoReturnValue"; | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|  | ||||
|                     // if allowImplicit: false, should also check node.argument | ||||
|                     if (!options.allowImplicit && !node.argument) { | ||||
|                         messageAndSuggestions.messageId = "expectedReturnValue"; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (messageAndSuggestions.messageId) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: messageAndSuggestions.messageId, | ||||
|                         data: { | ||||
|                             name: astUtils.getFunctionNameWithKind(funcInfo.node), | ||||
|                             arrayMethodName: fullMethodName(funcInfo.arrayMethodName) | ||||
|                         }, | ||||
|                         suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Reports a given function if the last path is reachable. | ||||
|             "FunctionExpression:exit": checkLastSegment, | ||||
|             "ArrowFunctionExpression:exit": checkLastSegment | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										311
									
								
								node_modules/eslint/lib/rules/array-element-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								node_modules/eslint/lib/rules/array-element-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,311 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce line breaks after each array element | ||||
|  * @author Jan Peer Stöcklmair <https://github.com/JPeer264> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce line breaks after each array element", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/array-element-newline" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: { | ||||
|             definitions: { | ||||
|                 basicConfig: { | ||||
|                     oneOf: [ | ||||
|                         { | ||||
|                             enum: ["always", "never", "consistent"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 multiline: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 minItems: { | ||||
|                                     type: ["integer", "null"], | ||||
|                                     minimum: 0 | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             }, | ||||
|             type: "array", | ||||
|             items: [ | ||||
|                 { | ||||
|                     oneOf: [ | ||||
|                         { | ||||
|                             $ref: "#/definitions/basicConfig" | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 ArrayExpression: { | ||||
|                                     $ref: "#/definitions/basicConfig" | ||||
|                                 }, | ||||
|                                 ArrayPattern: { | ||||
|                                     $ref: "#/definitions/basicConfig" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false, | ||||
|                             minProperties: 1 | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedLineBreak: "There should be no linebreak here.", | ||||
|             missingLineBreak: "There should be a linebreak after this element." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Normalizes a given option value. | ||||
|          * @param {string|Object|undefined} providedOption An option value to parse. | ||||
|          * @returns {{multiline: boolean, minItems: number}} Normalized option object. | ||||
|          */ | ||||
|         function normalizeOptionValue(providedOption) { | ||||
|             let consistent = false; | ||||
|             let multiline = false; | ||||
|             let minItems; | ||||
|  | ||||
|             const option = providedOption || "always"; | ||||
|  | ||||
|             if (!option || option === "always" || option.minItems === 0) { | ||||
|                 minItems = 0; | ||||
|             } else if (option === "never") { | ||||
|                 minItems = Number.POSITIVE_INFINITY; | ||||
|             } else if (option === "consistent") { | ||||
|                 consistent = true; | ||||
|                 minItems = Number.POSITIVE_INFINITY; | ||||
|             } else { | ||||
|                 multiline = Boolean(option.multiline); | ||||
|                 minItems = option.minItems || Number.POSITIVE_INFINITY; | ||||
|             } | ||||
|  | ||||
|             return { consistent, multiline, minItems }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Normalizes a given option value. | ||||
|          * @param {string|Object|undefined} options An option value to parse. | ||||
|          * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. | ||||
|          */ | ||||
|         function normalizeOptions(options) { | ||||
|             if (options && (options.ArrayExpression || options.ArrayPattern)) { | ||||
|                 let expressionOptions, patternOptions; | ||||
|  | ||||
|                 if (options.ArrayExpression) { | ||||
|                     expressionOptions = normalizeOptionValue(options.ArrayExpression); | ||||
|                 } | ||||
|  | ||||
|                 if (options.ArrayPattern) { | ||||
|                     patternOptions = normalizeOptionValue(options.ArrayPattern); | ||||
|                 } | ||||
|  | ||||
|                 return { ArrayExpression: expressionOptions, ArrayPattern: patternOptions }; | ||||
|             } | ||||
|  | ||||
|             const value = normalizeOptionValue(options); | ||||
|  | ||||
|             return { ArrayExpression: value, ArrayPattern: value }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a line break after the first token | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoLineBreak(token) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); | ||||
|  | ||||
|             context.report({ | ||||
|                 loc: { | ||||
|                     start: tokenBefore.loc.end, | ||||
|                     end: token.loc.start | ||||
|                 }, | ||||
|                 messageId: "unexpectedLineBreak", | ||||
|                 fix(fixer) { | ||||
|                     if (astUtils.isCommentToken(tokenBefore)) { | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     if (!astUtils.isTokenOnSameLine(tokenBefore, token)) { | ||||
|                         return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " "); | ||||
|                     } | ||||
|  | ||||
|                     /* | ||||
|                      * This will check if the comma is on the same line as the next element | ||||
|                      * Following array: | ||||
|                      * [ | ||||
|                      *     1 | ||||
|                      *     , 2 | ||||
|                      *     , 3 | ||||
|                      * ] | ||||
|                      * | ||||
|                      * will be fixed to: | ||||
|                      * [ | ||||
|                      *     1, 2, 3 | ||||
|                      * ] | ||||
|                      */ | ||||
|                     const twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true }); | ||||
|  | ||||
|                     if (astUtils.isCommentToken(twoTokensBefore)) { | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], ""); | ||||
|  | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a line break after the first token | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredLineBreak(token) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); | ||||
|  | ||||
|             context.report({ | ||||
|                 loc: { | ||||
|                     start: tokenBefore.loc.end, | ||||
|                     end: token.loc.start | ||||
|                 }, | ||||
|                 messageId: "missingLineBreak", | ||||
|                 fix(fixer) { | ||||
|                     return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n"); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given node if it violated this rule. | ||||
|          * @param {ASTNode} node A node to check. This is an ObjectExpression node or an ObjectPattern node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function check(node) { | ||||
|             const elements = node.elements; | ||||
|             const normalizedOptions = normalizeOptions(context.options[0]); | ||||
|             const options = normalizedOptions[node.type]; | ||||
|  | ||||
|             if (!options) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             let elementBreak = false; | ||||
|  | ||||
|             /* | ||||
|              * MULTILINE: true | ||||
|              * loop through every element and check | ||||
|              * if at least one element has linebreaks inside | ||||
|              * this ensures that following is not valid (due to elements are on the same line): | ||||
|              * | ||||
|              * [ | ||||
|              *      1, | ||||
|              *      2, | ||||
|              *      3 | ||||
|              * ] | ||||
|              */ | ||||
|             if (options.multiline) { | ||||
|                 elementBreak = elements | ||||
|                     .filter(element => element !== null) | ||||
|                     .some(element => element.loc.start.line !== element.loc.end.line); | ||||
|             } | ||||
|  | ||||
|             let linebreaksCount = 0; | ||||
|  | ||||
|             for (let i = 0; i < node.elements.length; i++) { | ||||
|                 const element = node.elements[i]; | ||||
|  | ||||
|                 const previousElement = elements[i - 1]; | ||||
|  | ||||
|                 if (i === 0 || element === null || previousElement === null) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); | ||||
|                 const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); | ||||
|                 const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); | ||||
|  | ||||
|                 if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { | ||||
|                     linebreaksCount++; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             const needsLinebreaks = ( | ||||
|                 elements.length >= options.minItems || | ||||
|                 ( | ||||
|                     options.multiline && | ||||
|                     elementBreak | ||||
|                 ) || | ||||
|                 ( | ||||
|                     options.consistent && | ||||
|                     linebreaksCount > 0 && | ||||
|                     linebreaksCount < node.elements.length | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             elements.forEach((element, i) => { | ||||
|                 const previousElement = elements[i - 1]; | ||||
|  | ||||
|                 if (i === 0 || element === null || previousElement === null) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); | ||||
|                 const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); | ||||
|                 const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); | ||||
|  | ||||
|                 if (needsLinebreaks) { | ||||
|                     if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { | ||||
|                         reportRequiredLineBreak(firstTokenOfCurrentElement); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { | ||||
|                         reportNoLineBreak(firstTokenOfCurrentElement); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ArrayPattern: check, | ||||
|             ArrayExpression: check | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										296
									
								
								node_modules/eslint/lib/rules/arrow-body-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								node_modules/eslint/lib/rules/arrow-body-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,296 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to require braces in arrow function body. | ||||
|  * @author Alberto Rodríguez | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require braces around arrow function bodies", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/arrow-body-style" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["always", "never"] | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 1 | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["as-needed"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 requireReturnForObjectLiteral: { type: "boolean" } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 2 | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.", | ||||
|             unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.", | ||||
|             unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.", | ||||
|             unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.", | ||||
|             expectedBlock: "Expected block statement surrounding arrow body." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options; | ||||
|         const always = options[0] === "always"; | ||||
|         const asNeeded = !options[0] || options[0] === "as-needed"; | ||||
|         const never = options[0] === "never"; | ||||
|         const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; | ||||
|         const sourceCode = context.sourceCode; | ||||
|         let funcInfo = null; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given node has ASI problem or not. | ||||
|          * @param {Token} token The token to check. | ||||
|          * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed. | ||||
|          */ | ||||
|         function hasASIProblem(token) { | ||||
|             return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the closing parenthesis by the given node. | ||||
|          * @param {ASTNode} node first node after an opening parenthesis. | ||||
|          * @returns {Token} The found closing parenthesis token. | ||||
|          */ | ||||
|         function findClosingParen(node) { | ||||
|             let nodeToCheck = node; | ||||
|  | ||||
|             while (!astUtils.isParenthesised(sourceCode, nodeToCheck)) { | ||||
|                 nodeToCheck = nodeToCheck.parent; | ||||
|             } | ||||
|             return sourceCode.getTokenAfter(nodeToCheck); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check whether the node is inside of a for loop's init | ||||
|          * @param {ASTNode} node node is inside for loop | ||||
|          * @returns {boolean} `true` if the node is inside of a for loop, else `false` | ||||
|          */ | ||||
|         function isInsideForLoopInitializer(node) { | ||||
|             if (node && node.parent) { | ||||
|                 if (node.parent.type === "ForStatement" && node.parent.init === node) { | ||||
|                     return true; | ||||
|                 } | ||||
|                 return isInsideForLoopInitializer(node.parent); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether a arrow function body needs braces | ||||
|          * @param {ASTNode} node The arrow function node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validate(node) { | ||||
|             const arrowBody = node.body; | ||||
|  | ||||
|             if (arrowBody.type === "BlockStatement") { | ||||
|                 const blockBody = arrowBody.body; | ||||
|  | ||||
|                 if (blockBody.length !== 1 && !never) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && | ||||
|                     blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (never || asNeeded && blockBody[0].type === "ReturnStatement") { | ||||
|                     let messageId; | ||||
|  | ||||
|                     if (blockBody.length === 0) { | ||||
|                         messageId = "unexpectedEmptyBlock"; | ||||
|                     } else if (blockBody.length > 1) { | ||||
|                         messageId = "unexpectedOtherBlock"; | ||||
|                     } else if (blockBody[0].argument === null) { | ||||
|                         messageId = "unexpectedSingleBlock"; | ||||
|                     } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) { | ||||
|                         messageId = "unexpectedObjectBlock"; | ||||
|                     } else { | ||||
|                         messageId = "unexpectedSingleBlock"; | ||||
|                     } | ||||
|  | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: arrowBody.loc, | ||||
|                         messageId, | ||||
|                         fix(fixer) { | ||||
|                             const fixes = []; | ||||
|  | ||||
|                             if (blockBody.length !== 1 || | ||||
|                                 blockBody[0].type !== "ReturnStatement" || | ||||
|                                 !blockBody[0].argument || | ||||
|                                 hasASIProblem(sourceCode.getTokenAfter(arrowBody)) | ||||
|                             ) { | ||||
|                                 return fixes; | ||||
|                             } | ||||
|  | ||||
|                             const openingBrace = sourceCode.getFirstToken(arrowBody); | ||||
|                             const closingBrace = sourceCode.getLastToken(arrowBody); | ||||
|                             const firstValueToken = sourceCode.getFirstToken(blockBody[0], 1); | ||||
|                             const lastValueToken = sourceCode.getLastToken(blockBody[0]); | ||||
|                             const commentsExist = | ||||
|                                 sourceCode.commentsExistBetween(openingBrace, firstValueToken) || | ||||
|                                 sourceCode.commentsExistBetween(lastValueToken, closingBrace); | ||||
|  | ||||
|                             /* | ||||
|                              * Remove tokens around the return value. | ||||
|                              * If comments don't exist, remove extra spaces as well. | ||||
|                              */ | ||||
|                             if (commentsExist) { | ||||
|                                 fixes.push( | ||||
|                                     fixer.remove(openingBrace), | ||||
|                                     fixer.remove(closingBrace), | ||||
|                                     fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword | ||||
|                                 ); | ||||
|                             } else { | ||||
|                                 fixes.push( | ||||
|                                     fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]), | ||||
|                                     fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]]) | ||||
|                                 ); | ||||
|                             } | ||||
|  | ||||
|                             /* | ||||
|                              * If the first token of the return value is `{` or the return value is a sequence expression, | ||||
|                              * enclose the return value by parentheses to avoid syntax error. | ||||
|                              */ | ||||
|                             if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) { | ||||
|                                 if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) { | ||||
|                                     fixes.push( | ||||
|                                         fixer.insertTextBefore(firstValueToken, "("), | ||||
|                                         fixer.insertTextAfter(lastValueToken, ")") | ||||
|                                     ); | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             /* | ||||
|                              * If the last token of the return statement is semicolon, remove it. | ||||
|                              * Non-block arrow body is an expression, not a statement. | ||||
|                              */ | ||||
|                             if (astUtils.isSemicolonToken(lastValueToken)) { | ||||
|                                 fixes.push(fixer.remove(lastValueToken)); | ||||
|                             } | ||||
|  | ||||
|                             return fixes; | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } else { | ||||
|                 if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: arrowBody.loc, | ||||
|                         messageId: "expectedBlock", | ||||
|                         fix(fixer) { | ||||
|                             const fixes = []; | ||||
|                             const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken); | ||||
|                             const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 }); | ||||
|                             const lastToken = sourceCode.getLastToken(node); | ||||
|  | ||||
|                             let parenthesisedObjectLiteral = null; | ||||
|  | ||||
|                             if ( | ||||
|                                 astUtils.isOpeningParenToken(firstTokenAfterArrow) && | ||||
|                                 astUtils.isOpeningBraceToken(secondTokenAfterArrow) | ||||
|                             ) { | ||||
|                                 const braceNode = sourceCode.getNodeByRangeIndex(secondTokenAfterArrow.range[0]); | ||||
|  | ||||
|                                 if (braceNode.type === "ObjectExpression") { | ||||
|                                     parenthesisedObjectLiteral = braceNode; | ||||
|                                 } | ||||
|                             } | ||||
|  | ||||
|                             // If the value is object literal, remove parentheses which were forced by syntax. | ||||
|                             if (parenthesisedObjectLiteral) { | ||||
|                                 const openingParenToken = firstTokenAfterArrow; | ||||
|                                 const openingBraceToken = secondTokenAfterArrow; | ||||
|  | ||||
|                                 if (astUtils.isTokenOnSameLine(openingParenToken, openingBraceToken)) { | ||||
|                                     fixes.push(fixer.replaceText(openingParenToken, "{return ")); | ||||
|                                 } else { | ||||
|  | ||||
|                                     // Avoid ASI | ||||
|                                     fixes.push( | ||||
|                                         fixer.replaceText(openingParenToken, "{"), | ||||
|                                         fixer.insertTextBefore(openingBraceToken, "return ") | ||||
|                                     ); | ||||
|                                 } | ||||
|  | ||||
|                                 // Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo() | ||||
|                                 fixes.push(fixer.remove(findClosingParen(parenthesisedObjectLiteral))); | ||||
|                                 fixes.push(fixer.insertTextAfter(lastToken, "}")); | ||||
|  | ||||
|                             } else { | ||||
|                                 fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return ")); | ||||
|                                 fixes.push(fixer.insertTextAfter(lastToken, "}")); | ||||
|                             } | ||||
|  | ||||
|                             return fixes; | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "BinaryExpression[operator='in']"() { | ||||
|                 let info = funcInfo; | ||||
|  | ||||
|                 while (info) { | ||||
|                     info.hasInOperator = true; | ||||
|                     info = info.upper; | ||||
|                 } | ||||
|             }, | ||||
|             ArrowFunctionExpression() { | ||||
|                 funcInfo = { | ||||
|                     upper: funcInfo, | ||||
|                     hasInOperator: false | ||||
|                 }; | ||||
|             }, | ||||
|             "ArrowFunctionExpression:exit"(node) { | ||||
|                 validate(node); | ||||
|                 funcInfo = funcInfo.upper; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										186
									
								
								node_modules/eslint/lib/rules/arrow-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								node_modules/eslint/lib/rules/arrow-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to require parens in arrow function arguments. | ||||
|  * @author Jxck | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Determines if the given arrow function has block body. | ||||
|  * @param {ASTNode} node `ArrowFunctionExpression` node. | ||||
|  * @returns {boolean} `true` if the function has block body. | ||||
|  */ | ||||
| function hasBlockBody(node) { | ||||
|     return node.body.type === "BlockStatement"; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require parentheses around arrow function arguments", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/arrow-parens" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "as-needed"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     requireForBlockBody: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedParens: "Unexpected parentheses around single function argument.", | ||||
|             expectedParens: "Expected parentheses around arrow function argument.", | ||||
|  | ||||
|             unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.", | ||||
|             expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const asNeeded = context.options[0] === "as-needed"; | ||||
|         const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Finds opening paren of parameters for the given arrow function, if it exists. | ||||
|          * It is assumed that the given arrow function has exactly one parameter. | ||||
|          * @param {ASTNode} node `ArrowFunctionExpression` node. | ||||
|          * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters. | ||||
|          */ | ||||
|         function findOpeningParenOfParams(node) { | ||||
|             const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]); | ||||
|  | ||||
|             if ( | ||||
|                 tokenBeforeParams && | ||||
|                 astUtils.isOpeningParenToken(tokenBeforeParams) && | ||||
|                 node.range[0] <= tokenBeforeParams.range[0] | ||||
|             ) { | ||||
|                 return tokenBeforeParams; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Finds closing paren of parameters for the given arrow function. | ||||
|          * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter. | ||||
|          * @param {ASTNode} node `ArrowFunctionExpression` node. | ||||
|          * @returns {Token} the closing paren of parameters. | ||||
|          */ | ||||
|         function getClosingParenOfParams(node) { | ||||
|             return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the given arrow function has comments inside parens of parameters. | ||||
|          * It is assumed that the given arrow function has parens of parameters. | ||||
|          * @param {ASTNode} node `ArrowFunctionExpression` node. | ||||
|          * @param {Token} openingParen Opening paren of parameters. | ||||
|          * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters. | ||||
|          */ | ||||
|         function hasCommentsInParensOfParams(node, openingParen) { | ||||
|             return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the given arrow function has unexpected tokens before opening paren of parameters, | ||||
|          * in which case it will be assumed that the existing parens of parameters are necessary. | ||||
|          * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account. | ||||
|          * Example: <T>(a) => b | ||||
|          * @param {ASTNode} node `ArrowFunctionExpression` node. | ||||
|          * @param {Token} openingParen Opening paren of parameters. | ||||
|          * @returns {boolean} `true` if the function has at least one unexpected token. | ||||
|          */ | ||||
|         function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) { | ||||
|             const expectedCount = node.async ? 1 : 0; | ||||
|  | ||||
|             return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "ArrowFunctionExpression[params.length=1]"(node) { | ||||
|                 const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node); | ||||
|                 const openingParen = findOpeningParenOfParams(node); | ||||
|                 const hasParens = openingParen !== null; | ||||
|                 const [param] = node.params; | ||||
|  | ||||
|                 if (shouldHaveParens && !hasParens) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens", | ||||
|                         loc: param.loc, | ||||
|                         *fix(fixer) { | ||||
|                             yield fixer.insertTextBefore(param, "("); | ||||
|                             yield fixer.insertTextAfter(param, ")"); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 if ( | ||||
|                     !shouldHaveParens && | ||||
|                     hasParens && | ||||
|                     param.type === "Identifier" && | ||||
|                     !param.typeAnnotation && | ||||
|                     !node.returnType && | ||||
|                     !hasCommentsInParensOfParams(node, openingParen) && | ||||
|                     !hasUnexpectedTokensBeforeOpeningParen(node, openingParen) | ||||
|                 ) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens", | ||||
|                         loc: param.loc, | ||||
|                         *fix(fixer) { | ||||
|                             const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen); | ||||
|                             const closingParen = getClosingParenOfParams(node); | ||||
|  | ||||
|                             if ( | ||||
|                                 tokenBeforeOpeningParen && | ||||
|                                 tokenBeforeOpeningParen.range[1] === openingParen.range[0] && | ||||
|                                 !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param)) | ||||
|                             ) { | ||||
|                                 yield fixer.insertTextBefore(openingParen, " "); | ||||
|                             } | ||||
|  | ||||
|                             // remove parens, whitespace inside parens, and possible trailing comma | ||||
|                             yield fixer.removeRange([openingParen.range[0], param.range[0]]); | ||||
|                             yield fixer.removeRange([param.range[1], closingParen.range[1]]); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										164
									
								
								node_modules/eslint/lib/rules/arrow-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								node_modules/eslint/lib/rules/arrow-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to define spacing before/after arrow function's arrow. | ||||
|  * @author Jxck | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing before and after the arrow in arrow functions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/arrow-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     before: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     }, | ||||
|                     after: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expectedBefore: "Missing space before =>.", | ||||
|             unexpectedBefore: "Unexpected space before =>.", | ||||
|  | ||||
|             expectedAfter: "Missing space after =>.", | ||||
|             unexpectedAfter: "Unexpected space after =>." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         // merge rules with default | ||||
|         const rule = Object.assign({}, context.options[0]); | ||||
|  | ||||
|         rule.before = rule.before !== false; | ||||
|         rule.after = rule.after !== false; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Get tokens of arrow(`=>`) and before/after arrow. | ||||
|          * @param {ASTNode} node The arrow function node. | ||||
|          * @returns {Object} Tokens of arrow and before/after arrow. | ||||
|          */ | ||||
|         function getTokens(node) { | ||||
|             const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); | ||||
|  | ||||
|             return { | ||||
|                 before: sourceCode.getTokenBefore(arrow), | ||||
|                 arrow, | ||||
|                 after: sourceCode.getTokenAfter(arrow) | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Count spaces before/after arrow(`=>`) token. | ||||
|          * @param {Object} tokens Tokens before/after arrow. | ||||
|          * @returns {Object} count of space before/after arrow. | ||||
|          */ | ||||
|         function countSpaces(tokens) { | ||||
|             const before = tokens.arrow.range[0] - tokens.before.range[1]; | ||||
|             const after = tokens.after.range[0] - tokens.arrow.range[1]; | ||||
|  | ||||
|             return { before, after }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether space(s) before after arrow(`=>`) is satisfy rule. | ||||
|          * if before/after value is `true`, there should be space(s). | ||||
|          * if before/after value is `false`, there should be no space. | ||||
|          * @param {ASTNode} node The arrow function node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function spaces(node) { | ||||
|             const tokens = getTokens(node); | ||||
|             const countSpace = countSpaces(tokens); | ||||
|  | ||||
|             if (rule.before) { | ||||
|  | ||||
|                 // should be space(s) before arrow | ||||
|                 if (countSpace.before === 0) { | ||||
|                     context.report({ | ||||
|                         node: tokens.before, | ||||
|                         messageId: "expectedBefore", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.insertTextBefore(tokens.arrow, " "); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } else { | ||||
|  | ||||
|                 // should be no space before arrow | ||||
|                 if (countSpace.before > 0) { | ||||
|                     context.report({ | ||||
|                         node: tokens.before, | ||||
|                         messageId: "unexpectedBefore", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (rule.after) { | ||||
|  | ||||
|                 // should be space(s) after arrow | ||||
|                 if (countSpace.after === 0) { | ||||
|                     context.report({ | ||||
|                         node: tokens.after, | ||||
|                         messageId: "expectedAfter", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.insertTextAfter(tokens.arrow, " "); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } else { | ||||
|  | ||||
|                 // should be no space after arrow | ||||
|                 if (countSpace.after > 0) { | ||||
|                     context.report({ | ||||
|                         node: tokens.after, | ||||
|                         messageId: "unexpectedAfter", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ArrowFunctionExpression: spaces | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										135
									
								
								node_modules/eslint/lib/rules/block-scoped-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								node_modules/eslint/lib/rules/block-scoped-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to check for "block scoped" variables by binding context | ||||
|  * @author Matt DuVall <http://www.mattduvall.com> | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce the use of variables within the scope they are defined", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/block-scoped-var" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             outOfScope: "'{{name}}' declared on line {{definitionLine}} column {{definitionColumn}} is used outside of binding context." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         let stack = []; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Makes a block scope. | ||||
|          * @param {ASTNode} node A node of a scope. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function enterScope(node) { | ||||
|             stack.push(node.range); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Pops the last block scope. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function exitScope() { | ||||
|             stack.pop(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given reference. | ||||
|          * @param {eslint-scope.Reference} reference A reference to report. | ||||
|          * @param {eslint-scope.Definition} definition A definition for which to report reference. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(reference, definition) { | ||||
|             const identifier = reference.identifier; | ||||
|             const definitionPosition = definition.name.loc.start; | ||||
|  | ||||
|             context.report({ | ||||
|                 node: identifier, | ||||
|                 messageId: "outOfScope", | ||||
|                 data: { | ||||
|                     name: identifier.name, | ||||
|                     definitionLine: definitionPosition.line, | ||||
|                     definitionColumn: definitionPosition.column + 1 | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Finds and reports references which are outside of valid scopes. | ||||
|          * @param {ASTNode} node A node to get variables. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkForVariables(node) { | ||||
|             if (node.kind !== "var") { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Defines a predicate to check whether or not a given reference is outside of valid scope. | ||||
|             const scopeRange = stack[stack.length - 1]; | ||||
|  | ||||
|             /** | ||||
|              * Check if a reference is out of scope | ||||
|              * @param {ASTNode} reference node to examine | ||||
|              * @returns {boolean} True is its outside the scope | ||||
|              * @private | ||||
|              */ | ||||
|             function isOutsideOfScope(reference) { | ||||
|                 const idRange = reference.identifier.range; | ||||
|  | ||||
|                 return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; | ||||
|             } | ||||
|  | ||||
|             // Gets declared variables, and checks its references. | ||||
|             const variables = sourceCode.getDeclaredVariables(node); | ||||
|  | ||||
|             for (let i = 0; i < variables.length; ++i) { | ||||
|  | ||||
|                 // Reports. | ||||
|                 variables[i] | ||||
|                     .references | ||||
|                     .filter(isOutsideOfScope) | ||||
|                     .forEach(ref => report(ref, variables[i].defs.find(def => def.parent === node))); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             Program(node) { | ||||
|                 stack = [node.range]; | ||||
|             }, | ||||
|  | ||||
|             // Manages scopes. | ||||
|             BlockStatement: enterScope, | ||||
|             "BlockStatement:exit": exitScope, | ||||
|             ForStatement: enterScope, | ||||
|             "ForStatement:exit": exitScope, | ||||
|             ForInStatement: enterScope, | ||||
|             "ForInStatement:exit": exitScope, | ||||
|             ForOfStatement: enterScope, | ||||
|             "ForOfStatement:exit": exitScope, | ||||
|             SwitchStatement: enterScope, | ||||
|             "SwitchStatement:exit": exitScope, | ||||
|             CatchClause: enterScope, | ||||
|             "CatchClause:exit": exitScope, | ||||
|             StaticBlock: enterScope, | ||||
|             "StaticBlock:exit": exitScope, | ||||
|  | ||||
|             // Finds and reports references which are outside of valid scope. | ||||
|             VariableDeclaration: checkForVariables | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										174
									
								
								node_modules/eslint/lib/rules/block-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								node_modules/eslint/lib/rules/block-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to disallow or enforce spaces inside of single line blocks. | ||||
|  * @author Toru Nagashima | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const util = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow or enforce spaces inside of blocks after opening block and before closing block", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/block-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { enum: ["always", "never"] } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             missing: "Requires a space {{location}} '{{token}}'.", | ||||
|             extra: "Unexpected space(s) {{location}} '{{token}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const always = (context.options[0] !== "never"), | ||||
|             messageId = always ? "missing" : "extra", | ||||
|             sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Gets the open brace token from a given node. | ||||
|          * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to get. | ||||
|          * @returns {Token} The token of the open brace. | ||||
|          */ | ||||
|         function getOpenBrace(node) { | ||||
|             if (node.type === "SwitchStatement") { | ||||
|                 if (node.cases.length > 0) { | ||||
|                     return sourceCode.getTokenBefore(node.cases[0]); | ||||
|                 } | ||||
|                 return sourceCode.getLastToken(node, 1); | ||||
|             } | ||||
|  | ||||
|             if (node.type === "StaticBlock") { | ||||
|                 return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token | ||||
|             } | ||||
|  | ||||
|             // "BlockStatement" | ||||
|             return sourceCode.getFirstToken(node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether or not: | ||||
|          *   - given tokens are on same line. | ||||
|          *   - there is/isn't a space between given tokens. | ||||
|          * @param {Token} left A token to check. | ||||
|          * @param {Token} right The token which is next to `left`. | ||||
|          * @returns {boolean} | ||||
|          *    When the option is `"always"`, `true` if there are one or more spaces between given tokens. | ||||
|          *    When the option is `"never"`, `true` if there are not any spaces between given tokens. | ||||
|          *    If given tokens are not on same line, it's always `true`. | ||||
|          */ | ||||
|         function isValid(left, right) { | ||||
|             return ( | ||||
|                 !util.isTokenOnSameLine(left, right) || | ||||
|                 sourceCode.isSpaceBetweenTokens(left, right) === always | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks and reports invalid spacing style inside braces. | ||||
|          * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingInsideBraces(node) { | ||||
|  | ||||
|             // Gets braces and the first/last token of content. | ||||
|             const openBrace = getOpenBrace(node); | ||||
|             const closeBrace = sourceCode.getLastToken(node); | ||||
|             const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true }); | ||||
|             const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); | ||||
|  | ||||
|             // Skip if the node is invalid or empty. | ||||
|             if (openBrace.type !== "Punctuator" || | ||||
|                 openBrace.value !== "{" || | ||||
|                 closeBrace.type !== "Punctuator" || | ||||
|                 closeBrace.value !== "}" || | ||||
|                 firstToken === closeBrace | ||||
|             ) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Skip line comments for option never | ||||
|             if (!always && firstToken.type === "Line") { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Check. | ||||
|             if (!isValid(openBrace, firstToken)) { | ||||
|                 let loc = openBrace.loc; | ||||
|  | ||||
|                 if (messageId === "extra") { | ||||
|                     loc = { | ||||
|                         start: openBrace.loc.end, | ||||
|                         end: firstToken.loc.start | ||||
|                     }; | ||||
|                 } | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc, | ||||
|                     messageId, | ||||
|                     data: { | ||||
|                         location: "after", | ||||
|                         token: openBrace.value | ||||
|                     }, | ||||
|                     fix(fixer) { | ||||
|                         if (always) { | ||||
|                             return fixer.insertTextBefore(firstToken, " "); | ||||
|                         } | ||||
|  | ||||
|                         return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             if (!isValid(lastToken, closeBrace)) { | ||||
|                 let loc = closeBrace.loc; | ||||
|  | ||||
|                 if (messageId === "extra") { | ||||
|                     loc = { | ||||
|                         start: lastToken.loc.end, | ||||
|                         end: closeBrace.loc.start | ||||
|                     }; | ||||
|                 } | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc, | ||||
|                     messageId, | ||||
|                     data: { | ||||
|                         location: "before", | ||||
|                         token: closeBrace.value | ||||
|                     }, | ||||
|                     fix(fixer) { | ||||
|                         if (always) { | ||||
|                             return fixer.insertTextAfter(lastToken, " "); | ||||
|                         } | ||||
|  | ||||
|                         return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             BlockStatement: checkSpacingInsideBraces, | ||||
|             StaticBlock: checkSpacingInsideBraces, | ||||
|             SwitchStatement: checkSpacingInsideBraces | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										197
									
								
								node_modules/eslint/lib/rules/brace-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								node_modules/eslint/lib/rules/brace-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag block statements that do not use the one true brace style | ||||
|  * @author Ian Christian Myers | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent brace style for blocks", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/brace-style" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["1tbs", "stroustrup", "allman"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allowSingleLine: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         messages: { | ||||
|             nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.", | ||||
|             sameLineOpen: "Opening curly brace appears on the same line as controlling statement.", | ||||
|             blockSameLine: "Statement inside of curly braces should be on next line.", | ||||
|             nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.", | ||||
|             singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", | ||||
|             sameLineClose: "Closing curly brace appears on the same line as the subsequent block." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const style = context.options[0] || "1tbs", | ||||
|             params = context.options[1] || {}, | ||||
|             sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Fixes a place where a newline unexpectedly appears | ||||
|          * @param {Token} firstToken The token before the unexpected newline | ||||
|          * @param {Token} secondToken The token after the unexpected newline | ||||
|          * @returns {Function} A fixer function to remove the newlines between the tokens | ||||
|          */ | ||||
|         function removeNewlineBetween(firstToken, secondToken) { | ||||
|             const textRange = [firstToken.range[1], secondToken.range[0]]; | ||||
|             const textBetween = sourceCode.text.slice(textRange[0], textRange[1]); | ||||
|  | ||||
|             // Don't do a fix if there is a comment between the tokens | ||||
|             if (textBetween.trim()) { | ||||
|                 return null; | ||||
|             } | ||||
|             return fixer => fixer.replaceTextRange(textRange, " "); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates a pair of curly brackets based on the user's config | ||||
|          * @param {Token} openingCurly The opening curly bracket | ||||
|          * @param {Token} closingCurly The closing curly bracket | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateCurlyPair(openingCurly, closingCurly) { | ||||
|             const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly); | ||||
|             const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly); | ||||
|             const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly); | ||||
|             const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly); | ||||
|  | ||||
|             if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) { | ||||
|                 context.report({ | ||||
|                     node: openingCurly, | ||||
|                     messageId: "nextLineOpen", | ||||
|                     fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly) | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) { | ||||
|                 context.report({ | ||||
|                     node: openingCurly, | ||||
|                     messageId: "sameLineOpen", | ||||
|                     fix: fixer => fixer.insertTextBefore(openingCurly, "\n") | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) { | ||||
|                 context.report({ | ||||
|                     node: openingCurly, | ||||
|                     messageId: "blockSameLine", | ||||
|                     fix: fixer => fixer.insertTextAfter(openingCurly, "\n") | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) { | ||||
|                 context.report({ | ||||
|                     node: closingCurly, | ||||
|                     messageId: "singleLineClose", | ||||
|                     fix: fixer => fixer.insertTextBefore(closingCurly, "\n") | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates the location of a token that appears before a keyword (e.g. a newline before `else`) | ||||
|          * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`). | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateCurlyBeforeKeyword(curlyToken) { | ||||
|             const keywordToken = sourceCode.getTokenAfter(curlyToken); | ||||
|  | ||||
|             if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { | ||||
|                 context.report({ | ||||
|                     node: curlyToken, | ||||
|                     messageId: "nextLineClose", | ||||
|                     fix: removeNewlineBetween(curlyToken, keywordToken) | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { | ||||
|                 context.report({ | ||||
|                     node: curlyToken, | ||||
|                     messageId: "sameLineClose", | ||||
|                     fix: fixer => fixer.insertTextAfter(curlyToken, "\n") | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             BlockStatement(node) { | ||||
|                 if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { | ||||
|                     validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); | ||||
|                 } | ||||
|             }, | ||||
|             StaticBlock(node) { | ||||
|                 validateCurlyPair( | ||||
|                     sourceCode.getFirstToken(node, { skip: 1 }), // skip the `static` token | ||||
|                     sourceCode.getLastToken(node) | ||||
|                 ); | ||||
|             }, | ||||
|             ClassBody(node) { | ||||
|                 validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); | ||||
|             }, | ||||
|             SwitchStatement(node) { | ||||
|                 const closingCurly = sourceCode.getLastToken(node); | ||||
|                 const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly); | ||||
|  | ||||
|                 validateCurlyPair(openingCurly, closingCurly); | ||||
|             }, | ||||
|             IfStatement(node) { | ||||
|                 if (node.consequent.type === "BlockStatement" && node.alternate) { | ||||
|  | ||||
|                     // Handle the keyword after the `if` block (before `else`) | ||||
|                     validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent)); | ||||
|                 } | ||||
|             }, | ||||
|             TryStatement(node) { | ||||
|  | ||||
|                 // Handle the keyword after the `try` block (before `catch` or `finally`) | ||||
|                 validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block)); | ||||
|  | ||||
|                 if (node.handler && node.finalizer) { | ||||
|  | ||||
|                     // Handle the keyword after the `catch` block (before `finally`) | ||||
|                     validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body)); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										187
									
								
								node_modules/eslint/lib/rules/callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								node_modules/eslint/lib/rules/callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| /** | ||||
|  * @fileoverview Enforce return after a callback. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v7.0.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|  | ||||
|         replacedBy: [], | ||||
|  | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `return` statements after callbacks", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/callback-return" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "array", | ||||
|             items: { type: "string" } | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             missingReturn: "Expected return with your callback function." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const callbacks = context.options[0] || ["callback", "cb", "next"], | ||||
|             sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Find the closest parent matching a list of types. | ||||
|          * @param {ASTNode} node The node whose parents we are searching | ||||
|          * @param {Array} types The node types to match | ||||
|          * @returns {ASTNode} The matched node or undefined. | ||||
|          */ | ||||
|         function findClosestParentOfType(node, types) { | ||||
|             if (!node.parent) { | ||||
|                 return null; | ||||
|             } | ||||
|             if (!types.includes(node.parent.type)) { | ||||
|                 return findClosestParentOfType(node.parent, types); | ||||
|             } | ||||
|             return node.parent; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check to see if a node contains only identifiers | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} Whether or not the node contains only identifiers | ||||
|          */ | ||||
|         function containsOnlyIdentifiers(node) { | ||||
|             if (node.type === "Identifier") { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             if (node.type === "MemberExpression") { | ||||
|                 if (node.object.type === "Identifier") { | ||||
|                     return true; | ||||
|                 } | ||||
|                 if (node.object.type === "MemberExpression") { | ||||
|                     return containsOnlyIdentifiers(node.object); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check to see if a CallExpression is in our callback list. | ||||
|          * @param {ASTNode} node The node to check against our callback names list. | ||||
|          * @returns {boolean} Whether or not this function matches our callback name. | ||||
|          */ | ||||
|         function isCallback(node) { | ||||
|             return containsOnlyIdentifiers(node.callee) && callbacks.includes(sourceCode.getText(node.callee)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether or not the callback is part of a callback expression. | ||||
|          * @param {ASTNode} node The callback node | ||||
|          * @param {ASTNode} parentNode The expression node | ||||
|          * @returns {boolean} Whether or not this is part of a callback expression | ||||
|          */ | ||||
|         function isCallbackExpression(node, parentNode) { | ||||
|  | ||||
|             // ensure the parent node exists and is an expression | ||||
|             if (!parentNode || parentNode.type !== "ExpressionStatement") { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // cb() | ||||
|             if (parentNode.expression === node) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // special case for cb && cb() and similar | ||||
|             if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") { | ||||
|                 if (parentNode.expression.right === node) { | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             CallExpression(node) { | ||||
|  | ||||
|                 // if we're not a callback we can return | ||||
|                 if (!isCallback(node)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // find the closest block, return or loop | ||||
|                 const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}; | ||||
|  | ||||
|                 // if our parent is a return we know we're ok | ||||
|                 if (closestBlock.type === "ReturnStatement") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // arrow functions don't always have blocks and implicitly return | ||||
|                 if (closestBlock.type === "ArrowFunctionExpression") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // block statements are part of functions and most if statements | ||||
|                 if (closestBlock.type === "BlockStatement") { | ||||
|  | ||||
|                     // find the last item in the block | ||||
|                     const lastItem = closestBlock.body[closestBlock.body.length - 1]; | ||||
|  | ||||
|                     // if the callback is the last thing in a block that might be ok | ||||
|                     if (isCallbackExpression(node, lastItem)) { | ||||
|  | ||||
|                         const parentType = closestBlock.parent.type; | ||||
|  | ||||
|                         // but only if the block is part of a function | ||||
|                         if (parentType === "FunctionExpression" || | ||||
|                             parentType === "FunctionDeclaration" || | ||||
|                             parentType === "ArrowFunctionExpression" | ||||
|                         ) { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|  | ||||
|                     // ending a block with a return is also ok | ||||
|                     if (lastItem.type === "ReturnStatement") { | ||||
|  | ||||
|                         // but only if the callback is immediately before | ||||
|                         if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) { | ||||
|                             return; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 // as long as you're the child of a function at this point you should be asked to return | ||||
|                 if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { | ||||
|                     context.report({ node, messageId: "missingReturn" }); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|  | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										399
									
								
								node_modules/eslint/lib/rules/camelcase.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								node_modules/eslint/lib/rules/camelcase.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,399 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag non-camelcased identifiers | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce camelcase naming convention", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/camelcase" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     ignoreDestructuring: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     ignoreImports: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     ignoreGlobals: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     properties: { | ||||
|                         enum: ["always", "never"] | ||||
|                     }, | ||||
|                     allow: { | ||||
|                         type: "array", | ||||
|                         items: [ | ||||
|                             { | ||||
|                                 type: "string" | ||||
|                             } | ||||
|                         ], | ||||
|                         minItems: 0, | ||||
|                         uniqueItems: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             notCamelCase: "Identifier '{{name}}' is not in camel case.", | ||||
|             notCamelCasePrivate: "#{{name}} is not in camel case." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const properties = options.properties === "never" ? "never" : "always"; | ||||
|         const ignoreDestructuring = options.ignoreDestructuring; | ||||
|         const ignoreImports = options.ignoreImports; | ||||
|         const ignoreGlobals = options.ignoreGlobals; | ||||
|         const allow = options.allow || []; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         // contains reported nodes to avoid reporting twice on destructuring with shorthand notation | ||||
|         const reported = new Set(); | ||||
|  | ||||
|         /** | ||||
|          * Checks if a string contains an underscore and isn't all upper-case | ||||
|          * @param {string} name The string to check. | ||||
|          * @returns {boolean} if the string is underscored | ||||
|          * @private | ||||
|          */ | ||||
|         function isUnderscored(name) { | ||||
|             const nameBody = name.replace(/^_+|_+$/gu, ""); | ||||
|  | ||||
|             // if there's an underscore, it might be A_CONSTANT, which is okay | ||||
|             return nameBody.includes("_") && nameBody !== nameBody.toUpperCase(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a string match the ignore list | ||||
|          * @param {string} name The string to check. | ||||
|          * @returns {boolean} if the string is ignored | ||||
|          * @private | ||||
|          */ | ||||
|         function isAllowed(name) { | ||||
|             return allow.some( | ||||
|                 entry => name === entry || name.match(new RegExp(entry, "u")) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a given name is good or not. | ||||
|          * @param {string} name The name to check. | ||||
|          * @returns {boolean} `true` if the name is good. | ||||
|          * @private | ||||
|          */ | ||||
|         function isGoodName(name) { | ||||
|             return !isUnderscored(name) || isAllowed(name); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a given identifier reference or member expression is an assignment | ||||
|          * target. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} `true` if the node is an assignment target. | ||||
|          */ | ||||
|         function isAssignmentTarget(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             switch (parent.type) { | ||||
|                 case "AssignmentExpression": | ||||
|                 case "AssignmentPattern": | ||||
|                     return parent.left === node; | ||||
|  | ||||
|                 case "Property": | ||||
|                     return ( | ||||
|                         parent.parent.type === "ObjectPattern" && | ||||
|                         parent.value === node | ||||
|                     ); | ||||
|                 case "ArrayPattern": | ||||
|                 case "RestElement": | ||||
|                     return true; | ||||
|  | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a given binding identifier uses the original name as-is. | ||||
|          * - If it's in object destructuring or object expression, the original name is its property name. | ||||
|          * - If it's in import declaration, the original name is its exported name. | ||||
|          * @param {ASTNode} node The `Identifier` node to check. | ||||
|          * @returns {boolean} `true` if the identifier uses the original name as-is. | ||||
|          */ | ||||
|         function equalsToOriginalName(node) { | ||||
|             const localName = node.name; | ||||
|             const valueNode = node.parent.type === "AssignmentPattern" | ||||
|                 ? node.parent | ||||
|                 : node; | ||||
|             const parent = valueNode.parent; | ||||
|  | ||||
|             switch (parent.type) { | ||||
|                 case "Property": | ||||
|                     return ( | ||||
|                         (parent.parent.type === "ObjectPattern" || parent.parent.type === "ObjectExpression") && | ||||
|                         parent.value === valueNode && | ||||
|                         !parent.computed && | ||||
|                         parent.key.type === "Identifier" && | ||||
|                         parent.key.name === localName | ||||
|                     ); | ||||
|  | ||||
|                 case "ImportSpecifier": | ||||
|                     return ( | ||||
|                         parent.local === node && | ||||
|                         astUtils.getModuleExportName(parent.imported) === localName | ||||
|                     ); | ||||
|  | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an AST node as a rule violation. | ||||
|          * @param {ASTNode} node The node to report. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node) { | ||||
|             if (reported.has(node.range[0])) { | ||||
|                 return; | ||||
|             } | ||||
|             reported.add(node.range[0]); | ||||
|  | ||||
|             // Report it. | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId: node.type === "PrivateIdentifier" | ||||
|                     ? "notCamelCasePrivate" | ||||
|                     : "notCamelCase", | ||||
|                 data: { name: node.name } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an identifier reference or a binding identifier. | ||||
|          * @param {ASTNode} node The `Identifier` node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportReferenceId(node) { | ||||
|  | ||||
|             /* | ||||
|              * For backward compatibility, if it's in callings then ignore it. | ||||
|              * Not sure why it is. | ||||
|              */ | ||||
|             if ( | ||||
|                 node.parent.type === "CallExpression" || | ||||
|                 node.parent.type === "NewExpression" | ||||
|             ) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * For backward compatibility, if it's a default value of | ||||
|              * destructuring/parameters then ignore it. | ||||
|              * Not sure why it is. | ||||
|              */ | ||||
|             if ( | ||||
|                 node.parent.type === "AssignmentPattern" && | ||||
|                 node.parent.right === node | ||||
|             ) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * The `ignoreDestructuring` flag skips the identifiers that uses | ||||
|              * the property name as-is. | ||||
|              */ | ||||
|             if (ignoreDestructuring && equalsToOriginalName(node)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             report(node); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             // Report camelcase of global variable references ------------------ | ||||
|             Program(node) { | ||||
|                 const scope = sourceCode.getScope(node); | ||||
|  | ||||
|                 if (!ignoreGlobals) { | ||||
|  | ||||
|                     // Defined globals in config files or directive comments. | ||||
|                     for (const variable of scope.variables) { | ||||
|                         if ( | ||||
|                             variable.identifiers.length > 0 || | ||||
|                             isGoodName(variable.name) | ||||
|                         ) { | ||||
|                             continue; | ||||
|                         } | ||||
|                         for (const reference of variable.references) { | ||||
|  | ||||
|                             /* | ||||
|                              * For backward compatibility, this rule reports read-only | ||||
|                              * references as well. | ||||
|                              */ | ||||
|                             reportReferenceId(reference.identifier); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Undefined globals. | ||||
|                 for (const reference of scope.through) { | ||||
|                     const id = reference.identifier; | ||||
|  | ||||
|                     if (isGoodName(id.name)) { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     /* | ||||
|                      * For backward compatibility, this rule reports read-only | ||||
|                      * references as well. | ||||
|                      */ | ||||
|                     reportReferenceId(id); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Report camelcase of declared variables -------------------------- | ||||
|             [[ | ||||
|                 "VariableDeclaration", | ||||
|                 "FunctionDeclaration", | ||||
|                 "FunctionExpression", | ||||
|                 "ArrowFunctionExpression", | ||||
|                 "ClassDeclaration", | ||||
|                 "ClassExpression", | ||||
|                 "CatchClause" | ||||
|             ]](node) { | ||||
|                 for (const variable of sourceCode.getDeclaredVariables(node)) { | ||||
|                     if (isGoodName(variable.name)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     const id = variable.identifiers[0]; | ||||
|  | ||||
|                     // Report declaration. | ||||
|                     if (!(ignoreDestructuring && equalsToOriginalName(id))) { | ||||
|                         report(id); | ||||
|                     } | ||||
|  | ||||
|                     /* | ||||
|                      * For backward compatibility, report references as well. | ||||
|                      * It looks unnecessary because declarations are reported. | ||||
|                      */ | ||||
|                     for (const reference of variable.references) { | ||||
|                         if (reference.init) { | ||||
|                             continue; // Skip the write references of initializers. | ||||
|                         } | ||||
|                         reportReferenceId(reference.identifier); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Report camelcase in properties ---------------------------------- | ||||
|             [[ | ||||
|                 "ObjectExpression > Property[computed!=true] > Identifier.key", | ||||
|                 "MethodDefinition[computed!=true] > Identifier.key", | ||||
|                 "PropertyDefinition[computed!=true] > Identifier.key", | ||||
|                 "MethodDefinition > PrivateIdentifier.key", | ||||
|                 "PropertyDefinition > PrivateIdentifier.key" | ||||
|             ]](node) { | ||||
|                 if (properties === "never" || isGoodName(node.name)) { | ||||
|                     return; | ||||
|                 } | ||||
|                 report(node); | ||||
|             }, | ||||
|             "MemberExpression[computed!=true] > Identifier.property"(node) { | ||||
|                 if ( | ||||
|                     properties === "never" || | ||||
|                     !isAssignmentTarget(node.parent) || // ← ignore read-only references. | ||||
|                     isGoodName(node.name) | ||||
|                 ) { | ||||
|                     return; | ||||
|                 } | ||||
|                 report(node); | ||||
|             }, | ||||
|  | ||||
|             // Report camelcase in import -------------------------------------- | ||||
|             ImportDeclaration(node) { | ||||
|                 for (const variable of sourceCode.getDeclaredVariables(node)) { | ||||
|                     if (isGoodName(variable.name)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     const id = variable.identifiers[0]; | ||||
|  | ||||
|                     // Report declaration. | ||||
|                     if (!(ignoreImports && equalsToOriginalName(id))) { | ||||
|                         report(id); | ||||
|                     } | ||||
|  | ||||
|                     /* | ||||
|                      * For backward compatibility, report references as well. | ||||
|                      * It looks unnecessary because declarations are reported. | ||||
|                      */ | ||||
|                     for (const reference of variable.references) { | ||||
|                         reportReferenceId(reference.identifier); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Report camelcase in re-export ----------------------------------- | ||||
|             [[ | ||||
|                 "ExportAllDeclaration > Identifier.exported", | ||||
|                 "ExportSpecifier > Identifier.exported" | ||||
|             ]](node) { | ||||
|                 if (isGoodName(node.name)) { | ||||
|                     return; | ||||
|                 } | ||||
|                 report(node); | ||||
|             }, | ||||
|  | ||||
|             // Report camelcase in labels -------------------------------------- | ||||
|             [[ | ||||
|                 "LabeledStatement > Identifier.label", | ||||
|  | ||||
|                 /* | ||||
|                  * For backward compatibility, report references as well. | ||||
|                  * It looks unnecessary because declarations are reported. | ||||
|                  */ | ||||
|                 "BreakStatement > Identifier.label", | ||||
|                 "ContinueStatement > Identifier.label" | ||||
|             ]](node) { | ||||
|                 if (isGoodName(node.name)) { | ||||
|                     return; | ||||
|                 } | ||||
|                 report(node); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										300
									
								
								node_modules/eslint/lib/rules/capitalized-comments.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								node_modules/eslint/lib/rules/capitalized-comments.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,300 @@ | ||||
| /** | ||||
|  * @fileoverview enforce or disallow capitalization of the first letter of a comment | ||||
|  * @author Kevin Partington | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const LETTER_PATTERN = require("./utils/patterns/letters"); | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN, | ||||
|     WHITESPACE = /\s/gu, | ||||
|     MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern? | ||||
|  | ||||
| /* | ||||
|  * Base schema body for defining the basic capitalization rule, ignorePattern, | ||||
|  * and ignoreInlineComments values. | ||||
|  * This can be used in a few different ways in the actual schema. | ||||
|  */ | ||||
| const SCHEMA_BODY = { | ||||
|     type: "object", | ||||
|     properties: { | ||||
|         ignorePattern: { | ||||
|             type: "string" | ||||
|         }, | ||||
|         ignoreInlineComments: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreConsecutiveComments: { | ||||
|             type: "boolean" | ||||
|         } | ||||
|     }, | ||||
|     additionalProperties: false | ||||
| }; | ||||
| const DEFAULTS = { | ||||
|     ignorePattern: "", | ||||
|     ignoreInlineComments: false, | ||||
|     ignoreConsecutiveComments: false | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Get normalized options for either block or line comments from the given | ||||
|  * user-provided options. | ||||
|  * - If the user-provided options is just a string, returns a normalized | ||||
|  *   set of options using default values for all other options. | ||||
|  * - If the user-provided options is an object, then a normalized option | ||||
|  *   set is returned. Options specified in overrides will take priority | ||||
|  *   over options specified in the main options object, which will in | ||||
|  *   turn take priority over the rule's defaults. | ||||
|  * @param {Object|string} rawOptions The user-provided options. | ||||
|  * @param {string} which Either "line" or "block". | ||||
|  * @returns {Object} The normalized options. | ||||
|  */ | ||||
| function getNormalizedOptions(rawOptions, which) { | ||||
|     return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Get normalized options for block and line comments. | ||||
|  * @param {Object|string} rawOptions The user-provided options. | ||||
|  * @returns {Object} An object with "Line" and "Block" keys and corresponding | ||||
|  * normalized options objects. | ||||
|  */ | ||||
| function getAllNormalizedOptions(rawOptions = {}) { | ||||
|     return { | ||||
|         Line: getNormalizedOptions(rawOptions, "line"), | ||||
|         Block: getNormalizedOptions(rawOptions, "block") | ||||
|     }; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Creates a regular expression for each ignorePattern defined in the rule | ||||
|  * options. | ||||
|  * | ||||
|  * This is done in order to avoid invoking the RegExp constructor repeatedly. | ||||
|  * @param {Object} normalizedOptions The normalized rule options. | ||||
|  * @returns {void} | ||||
|  */ | ||||
| function createRegExpForIgnorePatterns(normalizedOptions) { | ||||
|     Object.keys(normalizedOptions).forEach(key => { | ||||
|         const ignorePatternStr = normalizedOptions[key].ignorePattern; | ||||
|  | ||||
|         if (ignorePatternStr) { | ||||
|             const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u"); | ||||
|  | ||||
|             normalizedOptions[key].ignorePatternRegExp = regExp; | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce or disallow capitalization of the first letter of a comment", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/capitalized-comments" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         schema: [ | ||||
|             { enum: ["always", "never"] }, | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     SCHEMA_BODY, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             line: SCHEMA_BODY, | ||||
|                             block: SCHEMA_BODY | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedLowercaseComment: "Comments should not begin with a lowercase character.", | ||||
|             unexpectedUppercaseComment: "Comments should not begin with an uppercase character." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const capitalize = context.options[0] || "always", | ||||
|             normalizedOptions = getAllNormalizedOptions(context.options[1]), | ||||
|             sourceCode = context.sourceCode; | ||||
|  | ||||
|         createRegExpForIgnorePatterns(normalizedOptions); | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Checks whether a comment is an inline comment. | ||||
|          * | ||||
|          * For the purpose of this rule, a comment is inline if: | ||||
|          * 1. The comment is preceded by a token on the same line; and | ||||
|          * 2. The command is followed by a token on the same line. | ||||
|          * | ||||
|          * Note that the comment itself need not be single-line! | ||||
|          * | ||||
|          * Also, it follows from this definition that only block comments can | ||||
|          * be considered as possibly inline. This is because line comments | ||||
|          * would consume any following tokens on the same line as the comment. | ||||
|          * @param {ASTNode} comment The comment node to check. | ||||
|          * @returns {boolean} True if the comment is an inline comment, false | ||||
|          * otherwise. | ||||
|          */ | ||||
|         function isInlineComment(comment) { | ||||
|             const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }), | ||||
|                 nextToken = sourceCode.getTokenAfter(comment, { includeComments: true }); | ||||
|  | ||||
|             return Boolean( | ||||
|                 previousToken && | ||||
|                 nextToken && | ||||
|                 comment.loc.start.line === previousToken.loc.end.line && | ||||
|                 comment.loc.end.line === nextToken.loc.start.line | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if a comment follows another comment. | ||||
|          * @param {ASTNode} comment The comment to check. | ||||
|          * @returns {boolean} True if the comment follows a valid comment. | ||||
|          */ | ||||
|         function isConsecutiveComment(comment) { | ||||
|             const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true }); | ||||
|  | ||||
|             return Boolean( | ||||
|                 previousTokenOrComment && | ||||
|                 ["Block", "Line"].includes(previousTokenOrComment.type) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check a comment to determine if it is valid for this rule. | ||||
|          * @param {ASTNode} comment The comment node to process. | ||||
|          * @param {Object} options The options for checking this comment. | ||||
|          * @returns {boolean} True if the comment is valid, false otherwise. | ||||
|          */ | ||||
|         function isCommentValid(comment, options) { | ||||
|  | ||||
|             // 1. Check for default ignore pattern. | ||||
|             if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 2. Check for custom ignore pattern. | ||||
|             const commentWithoutAsterisks = comment.value | ||||
|                 .replace(/\*/gu, ""); | ||||
|  | ||||
|             if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 3. Check for inline comments. | ||||
|             if (options.ignoreInlineComments && isInlineComment(comment)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 4. Is this a consecutive comment (and are we tolerating those)? | ||||
|             if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 5. Does the comment start with a possible URL? | ||||
|             if (MAYBE_URL.test(commentWithoutAsterisks)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 6. Is the initial word character a letter? | ||||
|             const commentWordCharsOnly = commentWithoutAsterisks | ||||
|                 .replace(WHITESPACE, ""); | ||||
|  | ||||
|             if (commentWordCharsOnly.length === 0) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             const firstWordChar = commentWordCharsOnly[0]; | ||||
|  | ||||
|             if (!LETTER_PATTERN.test(firstWordChar)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // 7. Check the case of the initial word character. | ||||
|             const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), | ||||
|                 isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); | ||||
|  | ||||
|             if (capitalize === "always" && isLowercase) { | ||||
|                 return false; | ||||
|             } | ||||
|             if (capitalize === "never" && isUppercase) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Process a comment to determine if it needs to be reported. | ||||
|          * @param {ASTNode} comment The comment node to process. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function processComment(comment) { | ||||
|             const options = normalizedOptions[comment.type], | ||||
|                 commentValid = isCommentValid(comment, options); | ||||
|  | ||||
|             if (!commentValid) { | ||||
|                 const messageId = capitalize === "always" | ||||
|                     ? "unexpectedLowercaseComment" | ||||
|                     : "unexpectedUppercaseComment"; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: null, // Intentionally using loc instead | ||||
|                     loc: comment.loc, | ||||
|                     messageId, | ||||
|                     fix(fixer) { | ||||
|                         const match = comment.value.match(LETTER_PATTERN); | ||||
|  | ||||
|                         return fixer.replaceTextRange( | ||||
|  | ||||
|                             // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) | ||||
|                             [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], | ||||
|                             capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase() | ||||
|                         ); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program() { | ||||
|                 const comments = sourceCode.getAllComments(); | ||||
|  | ||||
|                 comments.filter(token => token.type !== "Shebang").forEach(processComment); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										187
									
								
								node_modules/eslint/lib/rules/class-methods-use-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								node_modules/eslint/lib/rules/class-methods-use-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce that all class methods use 'this'. | ||||
|  * @author Patrick Williams | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce that class methods utilize `this`", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/class-methods-use-this" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 exceptMethods: { | ||||
|                     type: "array", | ||||
|                     items: { | ||||
|                         type: "string" | ||||
|                     } | ||||
|                 }, | ||||
|                 enforceForClassFields: { | ||||
|                     type: "boolean", | ||||
|                     default: true | ||||
|                 } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             missingThis: "Expected 'this' to be used by class {{name}}." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|         const config = Object.assign({}, context.options[0]); | ||||
|         const enforceForClassFields = config.enforceForClassFields !== false; | ||||
|         const exceptMethods = new Set(config.exceptMethods || []); | ||||
|  | ||||
|         const stack = []; | ||||
|  | ||||
|         /** | ||||
|          * Push `this` used flag initialized with `false` onto the stack. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function pushContext() { | ||||
|             stack.push(false); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Pop `this` used flag from the stack. | ||||
|          * @returns {boolean | undefined} `this` used flag | ||||
|          */ | ||||
|         function popContext() { | ||||
|             return stack.pop(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Initializes the current context to false and pushes it onto the stack. | ||||
|          * These booleans represent whether 'this' has been used in the context. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function enterFunction() { | ||||
|             pushContext(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if the node is an instance method | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @returns {boolean} True if its an instance method | ||||
|          * @private | ||||
|          */ | ||||
|         function isInstanceMethod(node) { | ||||
|             switch (node.type) { | ||||
|                 case "MethodDefinition": | ||||
|                     return !node.static && node.kind !== "constructor"; | ||||
|                 case "PropertyDefinition": | ||||
|                     return !node.static && enforceForClassFields; | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if the node is an instance method not excluded by config | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @returns {boolean} True if it is an instance method, and not excluded by config | ||||
|          * @private | ||||
|          */ | ||||
|         function isIncludedInstanceMethod(node) { | ||||
|             if (isInstanceMethod(node)) { | ||||
|                 if (node.computed) { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 const hashIfNeeded = node.key.type === "PrivateIdentifier" ? "#" : ""; | ||||
|                 const name = node.key.type === "Literal" | ||||
|                     ? astUtils.getStaticStringValue(node.key) | ||||
|                     : (node.key.name || ""); | ||||
|  | ||||
|                 return !exceptMethods.has(hashIfNeeded + name); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if we are leaving a function that is a method, and reports if 'this' has not been used. | ||||
|          * Static methods and the constructor are exempt. | ||||
|          * Then pops the context off the stack. | ||||
|          * @param {ASTNode} node A function node that was entered. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function exitFunction(node) { | ||||
|             const methodUsesThis = popContext(); | ||||
|  | ||||
|             if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: astUtils.getFunctionHeadLoc(node, context.sourceCode), | ||||
|                     messageId: "missingThis", | ||||
|                     data: { | ||||
|                         name: astUtils.getFunctionNameWithKind(node) | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Mark the current context as having used 'this'. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function markThisUsed() { | ||||
|             if (stack.length) { | ||||
|                 stack[stack.length - 1] = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: enterFunction, | ||||
|             "FunctionDeclaration:exit": exitFunction, | ||||
|             FunctionExpression: enterFunction, | ||||
|             "FunctionExpression:exit": exitFunction, | ||||
|  | ||||
|             /* | ||||
|              * Class field value are implicit functions. | ||||
|              */ | ||||
|             "PropertyDefinition > *.key:exit": pushContext, | ||||
|             "PropertyDefinition:exit": popContext, | ||||
|  | ||||
|             /* | ||||
|              * Class static blocks are implicit functions. They aren't required to use `this`, | ||||
|              * but we have to push context so that it captures any use of `this` in the static block | ||||
|              * separately from enclosing contexts, because static blocks have their own `this` and it | ||||
|              * shouldn't count as used `this` in enclosing contexts. | ||||
|              */ | ||||
|             StaticBlock: pushContext, | ||||
|             "StaticBlock:exit": popContext, | ||||
|  | ||||
|             ThisExpression: markThisUsed, | ||||
|             Super: markThisUsed, | ||||
|             ...( | ||||
|                 enforceForClassFields && { | ||||
|                     "PropertyDefinition > ArrowFunctionExpression.value": enterFunction, | ||||
|                     "PropertyDefinition > ArrowFunctionExpression.value:exit": exitFunction | ||||
|                 } | ||||
|             ) | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										373
									
								
								node_modules/eslint/lib/rules/comma-dangle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								node_modules/eslint/lib/rules/comma-dangle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,373 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to forbid or enforce dangling commas. | ||||
|  * @author Ian Christian Myers | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const DEFAULT_OPTIONS = Object.freeze({ | ||||
|     arrays: "never", | ||||
|     objects: "never", | ||||
|     imports: "never", | ||||
|     exports: "never", | ||||
|     functions: "never" | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a trailing comma is allowed in a given node. | ||||
|  * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas. | ||||
|  * @param {ASTNode} lastItem The node of the last element in the given node. | ||||
|  * @returns {boolean} `true` if a trailing comma is allowed. | ||||
|  */ | ||||
| function isTrailingCommaAllowed(lastItem) { | ||||
|     return !( | ||||
|         lastItem.type === "RestElement" || | ||||
|         lastItem.type === "RestProperty" || | ||||
|         lastItem.type === "ExperimentalRestProperty" | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Normalize option value. | ||||
|  * @param {string|Object|undefined} optionValue The 1st option value to normalize. | ||||
|  * @param {number} ecmaVersion The normalized ECMAScript version. | ||||
|  * @returns {Object} The normalized option value. | ||||
|  */ | ||||
| function normalizeOptions(optionValue, ecmaVersion) { | ||||
|     if (typeof optionValue === "string") { | ||||
|         return { | ||||
|             arrays: optionValue, | ||||
|             objects: optionValue, | ||||
|             imports: optionValue, | ||||
|             exports: optionValue, | ||||
|             functions: ecmaVersion < 2017 ? "ignore" : optionValue | ||||
|         }; | ||||
|     } | ||||
|     if (typeof optionValue === "object" && optionValue !== null) { | ||||
|         return { | ||||
|             arrays: optionValue.arrays || DEFAULT_OPTIONS.arrays, | ||||
|             objects: optionValue.objects || DEFAULT_OPTIONS.objects, | ||||
|             imports: optionValue.imports || DEFAULT_OPTIONS.imports, | ||||
|             exports: optionValue.exports || DEFAULT_OPTIONS.exports, | ||||
|             functions: optionValue.functions || DEFAULT_OPTIONS.functions | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return DEFAULT_OPTIONS; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow trailing commas", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/comma-dangle" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         schema: { | ||||
|             definitions: { | ||||
|                 value: { | ||||
|                     enum: [ | ||||
|                         "always-multiline", | ||||
|                         "always", | ||||
|                         "never", | ||||
|                         "only-multiline" | ||||
|                     ] | ||||
|                 }, | ||||
|                 valueWithIgnore: { | ||||
|                     enum: [ | ||||
|                         "always-multiline", | ||||
|                         "always", | ||||
|                         "ignore", | ||||
|                         "never", | ||||
|                         "only-multiline" | ||||
|                     ] | ||||
|                 } | ||||
|             }, | ||||
|             type: "array", | ||||
|             items: [ | ||||
|                 { | ||||
|                     oneOf: [ | ||||
|                         { | ||||
|                             $ref: "#/definitions/value" | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 arrays: { $ref: "#/definitions/valueWithIgnore" }, | ||||
|                                 objects: { $ref: "#/definitions/valueWithIgnore" }, | ||||
|                                 imports: { $ref: "#/definitions/valueWithIgnore" }, | ||||
|                                 exports: { $ref: "#/definitions/valueWithIgnore" }, | ||||
|                                 functions: { $ref: "#/definitions/valueWithIgnore" } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             additionalItems: false | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected trailing comma.", | ||||
|             missing: "Missing trailing comma." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = normalizeOptions(context.options[0], context.languageOptions.ecmaVersion); | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Gets the last item of the given node. | ||||
|          * @param {ASTNode} node The node to get. | ||||
|          * @returns {ASTNode|null} The last node or null. | ||||
|          */ | ||||
|         function getLastItem(node) { | ||||
|  | ||||
|             /** | ||||
|              * Returns the last element of an array | ||||
|              * @param {any[]} array The input array | ||||
|              * @returns {any} The last element | ||||
|              */ | ||||
|             function last(array) { | ||||
|                 return array[array.length - 1]; | ||||
|             } | ||||
|  | ||||
|             switch (node.type) { | ||||
|                 case "ObjectExpression": | ||||
|                 case "ObjectPattern": | ||||
|                     return last(node.properties); | ||||
|                 case "ArrayExpression": | ||||
|                 case "ArrayPattern": | ||||
|                     return last(node.elements); | ||||
|                 case "ImportDeclaration": | ||||
|                 case "ExportNamedDeclaration": | ||||
|                     return last(node.specifiers); | ||||
|                 case "FunctionDeclaration": | ||||
|                 case "FunctionExpression": | ||||
|                 case "ArrowFunctionExpression": | ||||
|                     return last(node.params); | ||||
|                 case "CallExpression": | ||||
|                 case "NewExpression": | ||||
|                     return last(node.arguments); | ||||
|                 default: | ||||
|                     return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the trailing comma token of the given node. | ||||
|          * If the trailing comma does not exist, this returns the token which is | ||||
|          * the insertion point of the trailing comma token. | ||||
|          * @param {ASTNode} node The node to get. | ||||
|          * @param {ASTNode} lastItem The last item of the node. | ||||
|          * @returns {Token} The trailing comma token or the insertion point. | ||||
|          */ | ||||
|         function getTrailingToken(node, lastItem) { | ||||
|             switch (node.type) { | ||||
|                 case "ObjectExpression": | ||||
|                 case "ArrayExpression": | ||||
|                 case "CallExpression": | ||||
|                 case "NewExpression": | ||||
|                     return sourceCode.getLastToken(node, 1); | ||||
|                 default: { | ||||
|                     const nextToken = sourceCode.getTokenAfter(lastItem); | ||||
|  | ||||
|                     if (astUtils.isCommaToken(nextToken)) { | ||||
|                         return nextToken; | ||||
|                     } | ||||
|                     return sourceCode.getLastToken(lastItem); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether or not a given node is multiline. | ||||
|          * This rule handles a given node as multiline when the closing parenthesis | ||||
|          * and the last element are not on the same line. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {boolean} `true` if the node is multiline. | ||||
|          */ | ||||
|         function isMultiline(node) { | ||||
|             const lastItem = getLastItem(node); | ||||
|  | ||||
|             if (!lastItem) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             const penultimateToken = getTrailingToken(node, lastItem); | ||||
|             const lastToken = sourceCode.getTokenAfter(penultimateToken); | ||||
|  | ||||
|             return lastToken.loc.end.line !== penultimateToken.loc.end.line; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a trailing comma if it exists. | ||||
|          * @param {ASTNode} node A node to check. Its type is one of | ||||
|          *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, | ||||
|          *   ImportDeclaration, and ExportNamedDeclaration. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function forbidTrailingComma(node) { | ||||
|             const lastItem = getLastItem(node); | ||||
|  | ||||
|             if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const trailingToken = getTrailingToken(node, lastItem); | ||||
|  | ||||
|             if (astUtils.isCommaToken(trailingToken)) { | ||||
|                 context.report({ | ||||
|                     node: lastItem, | ||||
|                     loc: trailingToken.loc, | ||||
|                     messageId: "unexpected", | ||||
|                     *fix(fixer) { | ||||
|                         yield fixer.remove(trailingToken); | ||||
|  | ||||
|                         /* | ||||
|                          * Extend the range of the fix to include surrounding tokens to ensure | ||||
|                          * that the element after which the comma is removed stays _last_. | ||||
|                          * This intentionally makes conflicts in fix ranges with rules that may be | ||||
|                          * adding or removing elements in the same autofix pass. | ||||
|                          * https://github.com/eslint/eslint/issues/15660 | ||||
|                          */ | ||||
|                         yield fixer.insertTextBefore(sourceCode.getTokenBefore(trailingToken), ""); | ||||
|                         yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), ""); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the last element of a given node if it does not have a trailing | ||||
|          * comma. | ||||
|          * | ||||
|          * If a given node is `ArrayPattern` which has `RestElement`, the trailing | ||||
|          * comma is disallowed, so report if it exists. | ||||
|          * @param {ASTNode} node A node to check. Its type is one of | ||||
|          *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, | ||||
|          *   ImportDeclaration, and ExportNamedDeclaration. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function forceTrailingComma(node) { | ||||
|             const lastItem = getLastItem(node); | ||||
|  | ||||
|             if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { | ||||
|                 return; | ||||
|             } | ||||
|             if (!isTrailingCommaAllowed(lastItem)) { | ||||
|                 forbidTrailingComma(node); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const trailingToken = getTrailingToken(node, lastItem); | ||||
|  | ||||
|             if (trailingToken.value !== ",") { | ||||
|                 context.report({ | ||||
|                     node: lastItem, | ||||
|                     loc: { | ||||
|                         start: trailingToken.loc.end, | ||||
|                         end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end) | ||||
|                     }, | ||||
|                     messageId: "missing", | ||||
|                     *fix(fixer) { | ||||
|                         yield fixer.insertTextAfter(trailingToken, ","); | ||||
|  | ||||
|                         /* | ||||
|                          * Extend the range of the fix to include surrounding tokens to ensure | ||||
|                          * that the element after which the comma is inserted stays _last_. | ||||
|                          * This intentionally makes conflicts in fix ranges with rules that may be | ||||
|                          * adding or removing elements in the same autofix pass. | ||||
|                          * https://github.com/eslint/eslint/issues/15660 | ||||
|                          */ | ||||
|                         yield fixer.insertTextBefore(trailingToken, ""); | ||||
|                         yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), ""); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * If a given node is multiline, reports the last element of a given node | ||||
|          * when it does not have a trailing comma. | ||||
|          * Otherwise, reports a trailing comma if it exists. | ||||
|          * @param {ASTNode} node A node to check. Its type is one of | ||||
|          *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, | ||||
|          *   ImportDeclaration, and ExportNamedDeclaration. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function forceTrailingCommaIfMultiline(node) { | ||||
|             if (isMultiline(node)) { | ||||
|                 forceTrailingComma(node); | ||||
|             } else { | ||||
|                 forbidTrailingComma(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Only if a given node is not multiline, reports the last element of a given node | ||||
|          * when it does not have a trailing comma. | ||||
|          * Otherwise, reports a trailing comma if it exists. | ||||
|          * @param {ASTNode} node A node to check. Its type is one of | ||||
|          *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, | ||||
|          *   ImportDeclaration, and ExportNamedDeclaration. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function allowTrailingCommaIfMultiline(node) { | ||||
|             if (!isMultiline(node)) { | ||||
|                 forbidTrailingComma(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const predicate = { | ||||
|             always: forceTrailingComma, | ||||
|             "always-multiline": forceTrailingCommaIfMultiline, | ||||
|             "only-multiline": allowTrailingCommaIfMultiline, | ||||
|             never: forbidTrailingComma, | ||||
|             ignore() {} | ||||
|         }; | ||||
|  | ||||
|         return { | ||||
|             ObjectExpression: predicate[options.objects], | ||||
|             ObjectPattern: predicate[options.objects], | ||||
|  | ||||
|             ArrayExpression: predicate[options.arrays], | ||||
|             ArrayPattern: predicate[options.arrays], | ||||
|  | ||||
|             ImportDeclaration: predicate[options.imports], | ||||
|  | ||||
|             ExportNamedDeclaration: predicate[options.exports], | ||||
|  | ||||
|             FunctionDeclaration: predicate[options.functions], | ||||
|             FunctionExpression: predicate[options.functions], | ||||
|             ArrowFunctionExpression: predicate[options.functions], | ||||
|             CallExpression: predicate[options.functions], | ||||
|             NewExpression: predicate[options.functions] | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										192
									
								
								node_modules/eslint/lib/rules/comma-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								node_modules/eslint/lib/rules/comma-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,192 @@ | ||||
| /** | ||||
|  * @fileoverview Comma spacing - validates spacing before and after comma | ||||
|  * @author Vignesh Anand aka vegetableman. | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing before and after commas", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/comma-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     before: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     after: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             missing: "A space is required {{loc}} ','.", | ||||
|             unexpected: "There should be no space {{loc}} ','." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const tokensAndComments = sourceCode.tokensAndComments; | ||||
|  | ||||
|         const options = { | ||||
|             before: context.options[0] ? context.options[0].before : false, | ||||
|             after: context.options[0] ? context.options[0].after : true | ||||
|         }; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         // list of comma tokens to ignore for the check of leading whitespace | ||||
|         const commaTokensToIgnore = []; | ||||
|  | ||||
|         /** | ||||
|          * Reports a spacing error with an appropriate message. | ||||
|          * @param {ASTNode} node The binary expression node to report. | ||||
|          * @param {string} loc Is the error "before" or "after" the comma? | ||||
|          * @param {ASTNode} otherNode The node at the left or right of `node` | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node, loc, otherNode) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 fix(fixer) { | ||||
|                     if (options[loc]) { | ||||
|                         if (loc === "before") { | ||||
|                             return fixer.insertTextBefore(node, " "); | ||||
|                         } | ||||
|                         return fixer.insertTextAfter(node, " "); | ||||
|  | ||||
|                     } | ||||
|                     let start, end; | ||||
|                     const newText = ""; | ||||
|  | ||||
|                     if (loc === "before") { | ||||
|                         start = otherNode.range[1]; | ||||
|                         end = node.range[0]; | ||||
|                     } else { | ||||
|                         start = node.range[1]; | ||||
|                         end = otherNode.range[0]; | ||||
|                     } | ||||
|  | ||||
|                     return fixer.replaceTextRange([start, end], newText); | ||||
|  | ||||
|                 }, | ||||
|                 messageId: options[loc] ? "missing" : "unexpected", | ||||
|                 data: { | ||||
|                     loc | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list. | ||||
|          * @param {ASTNode} node An ArrayExpression or ArrayPattern node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function addNullElementsToIgnoreList(node) { | ||||
|             let previousToken = sourceCode.getFirstToken(node); | ||||
|  | ||||
|             node.elements.forEach(element => { | ||||
|                 let token; | ||||
|  | ||||
|                 if (element === null) { | ||||
|                     token = sourceCode.getTokenAfter(previousToken); | ||||
|  | ||||
|                     if (astUtils.isCommaToken(token)) { | ||||
|                         commaTokensToIgnore.push(token); | ||||
|                     } | ||||
|                 } else { | ||||
|                     token = sourceCode.getTokenAfter(element); | ||||
|                 } | ||||
|  | ||||
|                 previousToken = token; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             "Program:exit"() { | ||||
|                 tokensAndComments.forEach((token, i) => { | ||||
|  | ||||
|                     if (!astUtils.isCommaToken(token)) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     const previousToken = tokensAndComments[i - 1]; | ||||
|                     const nextToken = tokensAndComments[i + 1]; | ||||
|  | ||||
|                     if ( | ||||
|                         previousToken && | ||||
|                         !astUtils.isCommaToken(previousToken) && // ignore spacing between two commas | ||||
|  | ||||
|                         /* | ||||
|                          * `commaTokensToIgnore` are ending commas of `null` elements (array holes/elisions). | ||||
|                          * In addition to spacing between two commas, this can also ignore: | ||||
|                          * | ||||
|                          *   - Spacing after `[` (controlled by array-bracket-spacing) | ||||
|                          *       Example: [ , ] | ||||
|                          *                 ^ | ||||
|                          *   - Spacing after a comment (for backwards compatibility, this was possibly unintentional) | ||||
|                          *       Example: [a, /* * / ,] | ||||
|                          *                          ^ | ||||
|                          */ | ||||
|                         !commaTokensToIgnore.includes(token) && | ||||
|  | ||||
|                         astUtils.isTokenOnSameLine(previousToken, token) && | ||||
|                         options.before !== sourceCode.isSpaceBetweenTokens(previousToken, token) | ||||
|                     ) { | ||||
|                         report(token, "before", previousToken); | ||||
|                     } | ||||
|  | ||||
|                     if ( | ||||
|                         nextToken && | ||||
|                         !astUtils.isCommaToken(nextToken) && // ignore spacing between two commas | ||||
|                         !astUtils.isClosingParenToken(nextToken) && // controlled by space-in-parens | ||||
|                         !astUtils.isClosingBracketToken(nextToken) && // controlled by array-bracket-spacing | ||||
|                         !astUtils.isClosingBraceToken(nextToken) && // controlled by object-curly-spacing | ||||
|                         !(!options.after && nextToken.type === "Line") && // special case, allow space before line comment | ||||
|                         astUtils.isTokenOnSameLine(token, nextToken) && | ||||
|                         options.after !== sourceCode.isSpaceBetweenTokens(token, nextToken) | ||||
|                     ) { | ||||
|                         report(token, "after", nextToken); | ||||
|                     } | ||||
|                 }); | ||||
|             }, | ||||
|             ArrayExpression: addNullElementsToIgnoreList, | ||||
|             ArrayPattern: addNullElementsToIgnoreList | ||||
|  | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										314
									
								
								node_modules/eslint/lib/rules/comma-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								node_modules/eslint/lib/rules/comma-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,314 @@ | ||||
| /** | ||||
|  * @fileoverview Comma style - enforces comma styles of two types: last and first | ||||
|  * @author Vignesh Anand aka vegetableman | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent comma style", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/comma-style" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["first", "last"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     exceptions: { | ||||
|                         type: "object", | ||||
|                         additionalProperties: { | ||||
|                             type: "boolean" | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.", | ||||
|             expectedCommaFirst: "',' should be placed first.", | ||||
|             expectedCommaLast: "',' should be placed last." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const style = context.options[0] || "last", | ||||
|             sourceCode = context.sourceCode; | ||||
|         const exceptions = { | ||||
|             ArrayPattern: true, | ||||
|             ArrowFunctionExpression: true, | ||||
|             CallExpression: true, | ||||
|             FunctionDeclaration: true, | ||||
|             FunctionExpression: true, | ||||
|             ImportDeclaration: true, | ||||
|             ObjectPattern: true, | ||||
|             NewExpression: true | ||||
|         }; | ||||
|  | ||||
|         if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) { | ||||
|             const keys = Object.keys(context.options[1].exceptions); | ||||
|  | ||||
|             for (let i = 0; i < keys.length; i++) { | ||||
|                 exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Modified text based on the style | ||||
|          * @param {string} styleType Style type | ||||
|          * @param {string} text Source code text | ||||
|          * @returns {string} modified text | ||||
|          * @private | ||||
|          */ | ||||
|         function getReplacedText(styleType, text) { | ||||
|             switch (styleType) { | ||||
|                 case "between": | ||||
|                     return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`; | ||||
|  | ||||
|                 case "first": | ||||
|                     return `${text},`; | ||||
|  | ||||
|                 case "last": | ||||
|                     return `,${text}`; | ||||
|  | ||||
|                 default: | ||||
|                     return ""; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines the fixer function for a given style. | ||||
|          * @param {string} styleType comma style | ||||
|          * @param {ASTNode} previousItemToken The token to check. | ||||
|          * @param {ASTNode} commaToken The token to check. | ||||
|          * @param {ASTNode} currentItemToken The token to check. | ||||
|          * @returns {Function} Fixer function | ||||
|          * @private | ||||
|          */ | ||||
|         function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) { | ||||
|             const text = | ||||
|                 sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) + | ||||
|                 sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]); | ||||
|             const range = [previousItemToken.range[1], currentItemToken.range[0]]; | ||||
|  | ||||
|             return function(fixer) { | ||||
|                 return fixer.replaceTextRange(range, getReplacedText(styleType, text)); | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates the spacing around single items in lists. | ||||
|          * @param {Token} previousItemToken The last token from the previous item. | ||||
|          * @param {Token} commaToken The token representing the comma. | ||||
|          * @param {Token} currentItemToken The first token of the current item. | ||||
|          * @param {Token} reportItem The item to use when reporting an error. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) { | ||||
|  | ||||
|             // if single line | ||||
|             if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && | ||||
|                     astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { | ||||
|  | ||||
|                 // do nothing. | ||||
|  | ||||
|             } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && | ||||
|                     !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { | ||||
|  | ||||
|                 const comment = sourceCode.getCommentsAfter(commaToken)[0]; | ||||
|                 const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment) | ||||
|                     ? style | ||||
|                     : "between"; | ||||
|  | ||||
|                 // lone comma | ||||
|                 context.report({ | ||||
|                     node: reportItem, | ||||
|                     loc: commaToken.loc, | ||||
|                     messageId: "unexpectedLineBeforeAndAfterComma", | ||||
|                     fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) | ||||
|                 }); | ||||
|  | ||||
|             } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: reportItem, | ||||
|                     loc: commaToken.loc, | ||||
|                     messageId: "expectedCommaFirst", | ||||
|                     fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) | ||||
|                 }); | ||||
|  | ||||
|             } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: reportItem, | ||||
|                     loc: commaToken.loc, | ||||
|                     messageId: "expectedCommaLast", | ||||
|                     fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks the comma placement with regards to a declaration/property/element | ||||
|          * @param {ASTNode} node The binary expression node to check | ||||
|          * @param {string} property The property of the node containing child nodes. | ||||
|          * @private | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateComma(node, property) { | ||||
|             const items = node[property], | ||||
|                 arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern"); | ||||
|  | ||||
|             if (items.length > 1 || arrayLiteral) { | ||||
|  | ||||
|                 // seed as opening [ | ||||
|                 let previousItemToken = sourceCode.getFirstToken(node); | ||||
|  | ||||
|                 items.forEach(item => { | ||||
|                     const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, | ||||
|                         currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), | ||||
|                         reportItem = item || currentItemToken; | ||||
|  | ||||
|                     /* | ||||
|                      * This works by comparing three token locations: | ||||
|                      * - previousItemToken is the last token of the previous item | ||||
|                      * - commaToken is the location of the comma before the current item | ||||
|                      * - currentItemToken is the first token of the current item | ||||
|                      * | ||||
|                      * These values get switched around if item is undefined. | ||||
|                      * previousItemToken will refer to the last token not belonging | ||||
|                      * to the current item, which could be a comma or an opening | ||||
|                      * square bracket. currentItemToken could be a comma. | ||||
|                      * | ||||
|                      * All comparisons are done based on these tokens directly, so | ||||
|                      * they are always valid regardless of an undefined item. | ||||
|                      */ | ||||
|                     if (astUtils.isCommaToken(commaToken)) { | ||||
|                         validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem); | ||||
|                     } | ||||
|  | ||||
|                     if (item) { | ||||
|                         const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken); | ||||
|  | ||||
|                         previousItemToken = tokenAfterItem | ||||
|                             ? sourceCode.getTokenBefore(tokenAfterItem) | ||||
|                             : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1]; | ||||
|                     } else { | ||||
|                         previousItemToken = currentItemToken; | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 /* | ||||
|                  * Special case for array literals that have empty last items, such | ||||
|                  * as [ 1, 2, ]. These arrays only have two items show up in the | ||||
|                  * AST, so we need to look at the token to verify that there's no | ||||
|                  * dangling comma. | ||||
|                  */ | ||||
|                 if (arrayLiteral) { | ||||
|  | ||||
|                     const lastToken = sourceCode.getLastToken(node), | ||||
|                         nextToLastToken = sourceCode.getTokenBefore(lastToken); | ||||
|  | ||||
|                     if (astUtils.isCommaToken(nextToLastToken)) { | ||||
|                         validateCommaItemSpacing( | ||||
|                             sourceCode.getTokenBefore(nextToLastToken), | ||||
|                             nextToLastToken, | ||||
|                             lastToken, | ||||
|                             lastToken | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const nodes = {}; | ||||
|  | ||||
|         if (!exceptions.VariableDeclaration) { | ||||
|             nodes.VariableDeclaration = function(node) { | ||||
|                 validateComma(node, "declarations"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ObjectExpression) { | ||||
|             nodes.ObjectExpression = function(node) { | ||||
|                 validateComma(node, "properties"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ObjectPattern) { | ||||
|             nodes.ObjectPattern = function(node) { | ||||
|                 validateComma(node, "properties"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ArrayExpression) { | ||||
|             nodes.ArrayExpression = function(node) { | ||||
|                 validateComma(node, "elements"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ArrayPattern) { | ||||
|             nodes.ArrayPattern = function(node) { | ||||
|                 validateComma(node, "elements"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.FunctionDeclaration) { | ||||
|             nodes.FunctionDeclaration = function(node) { | ||||
|                 validateComma(node, "params"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.FunctionExpression) { | ||||
|             nodes.FunctionExpression = function(node) { | ||||
|                 validateComma(node, "params"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ArrowFunctionExpression) { | ||||
|             nodes.ArrowFunctionExpression = function(node) { | ||||
|                 validateComma(node, "params"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.CallExpression) { | ||||
|             nodes.CallExpression = function(node) { | ||||
|                 validateComma(node, "arguments"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.ImportDeclaration) { | ||||
|             nodes.ImportDeclaration = function(node) { | ||||
|                 validateComma(node, "specifiers"); | ||||
|             }; | ||||
|         } | ||||
|         if (!exceptions.NewExpression) { | ||||
|             nodes.NewExpression = function(node) { | ||||
|                 validateComma(node, "arguments"); | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return nodes; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										165
									
								
								node_modules/eslint/lib/rules/complexity.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								node_modules/eslint/lib/rules/complexity.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| /** | ||||
|  * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity. | ||||
|  * Counts the number of if, conditional, for, while, try, switch/case, | ||||
|  * @author Patrick Brosset | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { upperCaseFirst } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum cyclomatic complexity allowed in a program", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/complexity" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             maximum: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const option = context.options[0]; | ||||
|         let THRESHOLD = 20; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) | ||||
|         ) { | ||||
|             THRESHOLD = option.maximum || option.max; | ||||
|         } else if (typeof option === "number") { | ||||
|             THRESHOLD = option; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         // Using a stack to store complexity per code path | ||||
|         const complexities = []; | ||||
|  | ||||
|         /** | ||||
|          * Increase the complexity of the code path in context | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function increaseComplexity() { | ||||
|             complexities[complexities.length - 1]++; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             onCodePathStart() { | ||||
|  | ||||
|                 // The initial complexity is 1, representing one execution path in the CodePath | ||||
|                 complexities.push(1); | ||||
|             }, | ||||
|  | ||||
|             // Each branching in the code adds 1 to the complexity | ||||
|             CatchClause: increaseComplexity, | ||||
|             ConditionalExpression: increaseComplexity, | ||||
|             LogicalExpression: increaseComplexity, | ||||
|             ForStatement: increaseComplexity, | ||||
|             ForInStatement: increaseComplexity, | ||||
|             ForOfStatement: increaseComplexity, | ||||
|             IfStatement: increaseComplexity, | ||||
|             WhileStatement: increaseComplexity, | ||||
|             DoWhileStatement: increaseComplexity, | ||||
|  | ||||
|             // Avoid `default` | ||||
|             "SwitchCase[test]": increaseComplexity, | ||||
|  | ||||
|             // Logical assignment operators have short-circuiting behavior | ||||
|             AssignmentExpression(node) { | ||||
|                 if (astUtils.isLogicalAssignmentOperator(node.operator)) { | ||||
|                     increaseComplexity(); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onCodePathEnd(codePath, node) { | ||||
|                 const complexity = complexities.pop(); | ||||
|  | ||||
|                 /* | ||||
|                  * This rule only evaluates complexity of functions, so "program" is excluded. | ||||
|                  * Class field initializers and class static blocks are implicit functions. Therefore, | ||||
|                  * they shouldn't contribute to the enclosing function's complexity, but their | ||||
|                  * own complexity should be evaluated. | ||||
|                  */ | ||||
|                 if ( | ||||
|                     codePath.origin !== "function" && | ||||
|                     codePath.origin !== "class-field-initializer" && | ||||
|                     codePath.origin !== "class-static-block" | ||||
|                 ) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (complexity > THRESHOLD) { | ||||
|                     let name; | ||||
|  | ||||
|                     if (codePath.origin === "class-field-initializer") { | ||||
|                         name = "class field initializer"; | ||||
|                     } else if (codePath.origin === "class-static-block") { | ||||
|                         name = "class static block"; | ||||
|                     } else { | ||||
|                         name = astUtils.getFunctionNameWithKind(node); | ||||
|                     } | ||||
|  | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: "complex", | ||||
|                         data: { | ||||
|                             name: upperCaseFirst(name), | ||||
|                             complexity, | ||||
|                             max: THRESHOLD | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										208
									
								
								node_modules/eslint/lib/rules/computed-property-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								node_modules/eslint/lib/rules/computed-property-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| /** | ||||
|  * @fileoverview Disallows or enforces spaces inside computed properties. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing inside computed property brackets", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/computed-property-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "never"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     enforceForClassMembers: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", | ||||
|             unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", | ||||
|  | ||||
|             missingSpaceBefore: "A space is required before '{{tokenValue}}'.", | ||||
|             missingSpaceAfter: "A space is required after '{{tokenValue}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" | ||||
|         const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a space after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @param {Token} tokenAfter The token after `token`. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoBeginningSpace(node, token, tokenAfter) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: { start: token.loc.end, end: tokenAfter.loc.start }, | ||||
|                 messageId: "unexpectedSpaceAfter", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.removeRange([token.range[1], tokenAfter.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there shouldn't be a space before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @param {Token} tokenBefore The token before `token`. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportNoEndingSpace(node, token, tokenBefore) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: { start: tokenBefore.loc.end, end: token.loc.start }, | ||||
|                 messageId: "unexpectedSpaceBefore", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.removeRange([tokenBefore.range[1], token.range[0]]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a space after the first token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredBeginningSpace(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingSpaceAfter", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextAfter(token, " "); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that there should be a space before the last token | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @param {Token} token The token to use for the report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportRequiredEndingSpace(node, token) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: token.loc, | ||||
|                 messageId: "missingSpaceBefore", | ||||
|                 data: { | ||||
|                     tokenValue: token.value | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     return fixer.insertTextBefore(token, " "); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns a function that checks the spacing of a node on the property name | ||||
|          * that was passed in. | ||||
|          * @param {string} propertyName The property on the node to check for spacing | ||||
|          * @returns {Function} A function that will check spacing on a node | ||||
|          */ | ||||
|         function checkSpacing(propertyName) { | ||||
|             return function(node) { | ||||
|                 if (!node.computed) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const property = node[propertyName]; | ||||
|  | ||||
|                 const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken), | ||||
|                     first = sourceCode.getTokenAfter(before, { includeComments: true }), | ||||
|                     after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken), | ||||
|                     last = sourceCode.getTokenBefore(after, { includeComments: true }); | ||||
|  | ||||
|                 if (astUtils.isTokenOnSameLine(before, first)) { | ||||
|                     if (propertyNameMustBeSpaced) { | ||||
|                         if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) { | ||||
|                             reportRequiredBeginningSpace(node, before); | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (sourceCode.isSpaceBetweenTokens(before, first)) { | ||||
|                             reportNoBeginningSpace(node, before, first); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (astUtils.isTokenOnSameLine(last, after)) { | ||||
|                     if (propertyNameMustBeSpaced) { | ||||
|                         if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) { | ||||
|                             reportRequiredEndingSpace(node, after); | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (sourceCode.isSpaceBetweenTokens(last, after)) { | ||||
|                             reportNoEndingSpace(node, after, last); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const listeners = { | ||||
|             Property: checkSpacing("key"), | ||||
|             MemberExpression: checkSpacing("property") | ||||
|         }; | ||||
|  | ||||
|         if (enforceForClassMembers) { | ||||
|             listeners.MethodDefinition = | ||||
|                 listeners.PropertyDefinition = listeners.Property; | ||||
|         } | ||||
|  | ||||
|         return listeners; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										210
									
								
								node_modules/eslint/lib/rules/consistent-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								node_modules/eslint/lib/rules/consistent-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag consistent return values | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { upperCaseFirst } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks all segments in a set and returns true if all are unreachable. | ||||
|  * @param {Set<CodePathSegment>} segments The segments to check. | ||||
|  * @returns {boolean} True if all segments are unreachable; false otherwise. | ||||
|  */ | ||||
| function areAllSegmentsUnreachable(segments) { | ||||
|  | ||||
|     for (const segment of segments) { | ||||
|         if (segment.reachable) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether a given node is a `constructor` method in an ES6 class | ||||
|  * @param {ASTNode} node A node to check | ||||
|  * @returns {boolean} `true` if the node is a `constructor` method | ||||
|  */ | ||||
| function isClassConstructor(node) { | ||||
|     return node.type === "FunctionExpression" && | ||||
|         node.parent && | ||||
|         node.parent.type === "MethodDefinition" && | ||||
|         node.parent.kind === "constructor"; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `return` statements to either always or never specify values", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/consistent-return" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 treatUndefinedAsUnspecified: { | ||||
|                     type: "boolean", | ||||
|                     default: false | ||||
|                 } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             missingReturn: "Expected to return a value at the end of {{name}}.", | ||||
|             missingReturnValue: "{{name}} expected a return value.", | ||||
|             unexpectedReturnValue: "{{name}} expected no return value." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; | ||||
|         let funcInfo = null; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether of not the implicit returning is consistent if the last | ||||
|          * code path segment is reachable. | ||||
|          * @param {ASTNode} node A program/function node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkLastSegment(node) { | ||||
|             let loc, name; | ||||
|  | ||||
|             /* | ||||
|              * Skip if it expected no return value or unreachable. | ||||
|              * When unreachable, all paths are returned or thrown. | ||||
|              */ | ||||
|             if (!funcInfo.hasReturnValue || | ||||
|                 areAllSegmentsUnreachable(funcInfo.currentSegments) || | ||||
|                 astUtils.isES5Constructor(node) || | ||||
|                 isClassConstructor(node) | ||||
|             ) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Adjust a location and a message. | ||||
|             if (node.type === "Program") { | ||||
|  | ||||
|                 // The head of program. | ||||
|                 loc = { line: 1, column: 0 }; | ||||
|                 name = "program"; | ||||
|             } else if (node.type === "ArrowFunctionExpression") { | ||||
|  | ||||
|                 // `=>` token | ||||
|                 loc = context.sourceCode.getTokenBefore(node.body, astUtils.isArrowToken).loc; | ||||
|             } else if ( | ||||
|                 node.parent.type === "MethodDefinition" || | ||||
|                 (node.parent.type === "Property" && node.parent.method) | ||||
|             ) { | ||||
|  | ||||
|                 // Method name. | ||||
|                 loc = node.parent.key.loc; | ||||
|             } else { | ||||
|  | ||||
|                 // Function name or `function` keyword. | ||||
|                 loc = (node.id || context.sourceCode.getFirstToken(node)).loc; | ||||
|             } | ||||
|  | ||||
|             if (!name) { | ||||
|                 name = astUtils.getFunctionNameWithKind(node); | ||||
|             } | ||||
|  | ||||
|             // Reports. | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc, | ||||
|                 messageId: "missingReturn", | ||||
|                 data: { name } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             // Initializes/Disposes state of each code path. | ||||
|             onCodePathStart(codePath, node) { | ||||
|                 funcInfo = { | ||||
|                     upper: funcInfo, | ||||
|                     codePath, | ||||
|                     hasReturn: false, | ||||
|                     hasReturnValue: false, | ||||
|                     messageId: "", | ||||
|                     node, | ||||
|                     currentSegments: new Set() | ||||
|                 }; | ||||
|             }, | ||||
|             onCodePathEnd() { | ||||
|                 funcInfo = funcInfo.upper; | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|  | ||||
|             // Reports a given return statement if it's inconsistent. | ||||
|             ReturnStatement(node) { | ||||
|                 const argument = node.argument; | ||||
|                 let hasReturnValue = Boolean(argument); | ||||
|  | ||||
|                 if (treatUndefinedAsUnspecified && hasReturnValue) { | ||||
|                     hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void"; | ||||
|                 } | ||||
|  | ||||
|                 if (!funcInfo.hasReturn) { | ||||
|                     funcInfo.hasReturn = true; | ||||
|                     funcInfo.hasReturnValue = hasReturnValue; | ||||
|                     funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue"; | ||||
|                     funcInfo.data = { | ||||
|                         name: funcInfo.node.type === "Program" | ||||
|                             ? "Program" | ||||
|                             : upperCaseFirst(astUtils.getFunctionNameWithKind(funcInfo.node)) | ||||
|                     }; | ||||
|                 } else if (funcInfo.hasReturnValue !== hasReturnValue) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: funcInfo.messageId, | ||||
|                         data: funcInfo.data | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Reports a given program/function if the implicit returning is not consistent. | ||||
|             "Program:exit": checkLastSegment, | ||||
|             "FunctionDeclaration:exit": checkLastSegment, | ||||
|             "FunctionExpression:exit": checkLastSegment, | ||||
|             "ArrowFunctionExpression:exit": checkLastSegment | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										153
									
								
								node_modules/eslint/lib/rules/consistent-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								node_modules/eslint/lib/rules/consistent-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce consistent naming of "this" context variables | ||||
|  * @author Raphael Pigulla | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent naming when capturing the current execution context", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/consistent-this" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             type: "array", | ||||
|             items: { | ||||
|                 type: "string", | ||||
|                 minLength: 1 | ||||
|             }, | ||||
|             uniqueItems: true | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.", | ||||
|             unexpectedAlias: "Unexpected alias '{{name}}' for 'this'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         let aliases = []; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         if (context.options.length === 0) { | ||||
|             aliases.push("that"); | ||||
|         } else { | ||||
|             aliases = context.options; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that a variable declarator or assignment expression is assigning | ||||
|          * a non-'this' value to the specified alias. | ||||
|          * @param {ASTNode} node The assigning node. | ||||
|          * @param {string} name the name of the alias that was incorrectly used. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportBadAssignment(node, name) { | ||||
|             context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks that an assignment to an identifier only assigns 'this' to the | ||||
|          * appropriate alias, and the alias is only assigned to 'this'. | ||||
|          * @param {ASTNode} node The assigning node. | ||||
|          * @param {Identifier} name The name of the variable assigned to. | ||||
|          * @param {Expression} value The value of the assignment. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkAssignment(node, name, value) { | ||||
|             const isThis = value.type === "ThisExpression"; | ||||
|  | ||||
|             if (aliases.includes(name)) { | ||||
|                 if (!isThis || node.operator && node.operator !== "=") { | ||||
|                     reportBadAssignment(node, name); | ||||
|                 } | ||||
|             } else if (isThis) { | ||||
|                 context.report({ node, messageId: "unexpectedAlias", data: { name } }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Ensures that a variable declaration of the alias in a program or function | ||||
|          * is assigned to the correct value. | ||||
|          * @param {string} alias alias the check the assignment of. | ||||
|          * @param {Object} scope scope of the current code we are checking. | ||||
|          * @private | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkWasAssigned(alias, scope) { | ||||
|             const variable = scope.set.get(alias); | ||||
|  | ||||
|             if (!variable) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (variable.defs.some(def => def.node.type === "VariableDeclarator" && | ||||
|                 def.node.init !== null)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * The alias has been declared and not assigned: check it was | ||||
|              * assigned later in the same scope. | ||||
|              */ | ||||
|             if (!variable.references.some(reference => { | ||||
|                 const write = reference.writeExpr; | ||||
|  | ||||
|                 return ( | ||||
|                     reference.from === scope && | ||||
|                     write && write.type === "ThisExpression" && | ||||
|                     write.parent.operator === "=" | ||||
|                 ); | ||||
|             })) { | ||||
|                 variable.defs.map(def => def.node).forEach(node => { | ||||
|                     reportBadAssignment(node, alias); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check each alias to ensure that is was assigned to the correct value. | ||||
|          * @param {ASTNode} node The node that represents the scope to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function ensureWasAssigned(node) { | ||||
|             const scope = sourceCode.getScope(node); | ||||
|  | ||||
|             aliases.forEach(alias => { | ||||
|                 checkWasAssigned(alias, scope); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "Program:exit": ensureWasAssigned, | ||||
|             "FunctionExpression:exit": ensureWasAssigned, | ||||
|             "FunctionDeclaration:exit": ensureWasAssigned, | ||||
|  | ||||
|             VariableDeclarator(node) { | ||||
|                 const id = node.id; | ||||
|                 const isDestructuring = | ||||
|                     id.type === "ArrayPattern" || id.type === "ObjectPattern"; | ||||
|  | ||||
|                 if (node.init !== null && !isDestructuring) { | ||||
|                     checkAssignment(node, id.name, node.init); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             AssignmentExpression(node) { | ||||
|                 if (node.left.type === "Identifier") { | ||||
|                     checkAssignment(node, node.left.name, node.right); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										446
									
								
								node_modules/eslint/lib/rules/constructor-super.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								node_modules/eslint/lib/rules/constructor-super.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,446 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to verify `super()` callings in constructor. | ||||
|  * @author Toru Nagashima | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks all segments in a set and returns true if any are reachable. | ||||
|  * @param {Set<CodePathSegment>} segments The segments to check. | ||||
|  * @returns {boolean} True if any segment is reachable; false otherwise. | ||||
|  */ | ||||
| function isAnySegmentReachable(segments) { | ||||
|  | ||||
|     for (const segment of segments) { | ||||
|         if (segment.reachable) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is a constructor. | ||||
|  * @param {ASTNode} node A node to check. This node type is one of | ||||
|  *   `Program`, `FunctionDeclaration`, `FunctionExpression`, and | ||||
|  *   `ArrowFunctionExpression`. | ||||
|  * @returns {boolean} `true` if the node is a constructor. | ||||
|  */ | ||||
| function isConstructorFunction(node) { | ||||
|     return ( | ||||
|         node.type === "FunctionExpression" && | ||||
|         node.parent.type === "MethodDefinition" && | ||||
|         node.parent.kind === "constructor" | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether a given node can be a constructor or not. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if the node can be a constructor. | ||||
|  */ | ||||
| function isPossibleConstructor(node) { | ||||
|     if (!node) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     switch (node.type) { | ||||
|         case "ClassExpression": | ||||
|         case "FunctionExpression": | ||||
|         case "ThisExpression": | ||||
|         case "MemberExpression": | ||||
|         case "CallExpression": | ||||
|         case "NewExpression": | ||||
|         case "ChainExpression": | ||||
|         case "YieldExpression": | ||||
|         case "TaggedTemplateExpression": | ||||
|         case "MetaProperty": | ||||
|             return true; | ||||
|  | ||||
|         case "Identifier": | ||||
|             return node.name !== "undefined"; | ||||
|  | ||||
|         case "AssignmentExpression": | ||||
|             if (["=", "&&="].includes(node.operator)) { | ||||
|                 return isPossibleConstructor(node.right); | ||||
|             } | ||||
|  | ||||
|             if (["||=", "??="].includes(node.operator)) { | ||||
|                 return ( | ||||
|                     isPossibleConstructor(node.left) || | ||||
|                     isPossibleConstructor(node.right) | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
|             /** | ||||
|              * All other assignment operators are mathematical assignment operators (arithmetic or bitwise). | ||||
|              * An assignment expression with a mathematical operator can either evaluate to a primitive value, | ||||
|              * or throw, depending on the operands. Thus, it cannot evaluate to a constructor function. | ||||
|              */ | ||||
|             return false; | ||||
|  | ||||
|         case "LogicalExpression": | ||||
|  | ||||
|             /* | ||||
|              * If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if | ||||
|              * it doesn't short-circuit, it takes the value from the right side, so the right side must always be a | ||||
|              * possible constructor. A future improvement could verify that the left side could be truthy by | ||||
|              * excluding falsy literals. | ||||
|              */ | ||||
|             if (node.operator === "&&") { | ||||
|                 return isPossibleConstructor(node.right); | ||||
|             } | ||||
|  | ||||
|             return ( | ||||
|                 isPossibleConstructor(node.left) || | ||||
|                 isPossibleConstructor(node.right) | ||||
|             ); | ||||
|  | ||||
|         case "ConditionalExpression": | ||||
|             return ( | ||||
|                 isPossibleConstructor(node.alternate) || | ||||
|                 isPossibleConstructor(node.consequent) | ||||
|             ); | ||||
|  | ||||
|         case "SequenceExpression": { | ||||
|             const lastExpression = node.expressions[node.expressions.length - 1]; | ||||
|  | ||||
|             return isPossibleConstructor(lastExpression); | ||||
|         } | ||||
|  | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `super()` calls in constructors", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/constructor-super" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             missingSome: "Lacked a call of 'super()' in some code paths.", | ||||
|             missingAll: "Expected to call 'super()'.", | ||||
|  | ||||
|             duplicate: "Unexpected duplicate 'super()'.", | ||||
|             badSuper: "Unexpected 'super()' because 'super' is not a constructor.", | ||||
|             unexpected: "Unexpected 'super()'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /* | ||||
|          * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} | ||||
|          * Information for each constructor. | ||||
|          * - upper:      Information of the upper constructor. | ||||
|          * - hasExtends: A flag which shows whether own class has a valid `extends` | ||||
|          *               part. | ||||
|          * - scope:      The scope of own class. | ||||
|          * - codePath:   The code path object of the constructor. | ||||
|          */ | ||||
|         let funcInfo = null; | ||||
|  | ||||
|         /* | ||||
|          * {Map<string, {calledInSomePaths: boolean, calledInEveryPaths: boolean}>} | ||||
|          * Information for each code path segment. | ||||
|          * - calledInSomePaths:  A flag of be called `super()` in some code paths. | ||||
|          * - calledInEveryPaths: A flag of be called `super()` in all code paths. | ||||
|          * - validNodes: | ||||
|          */ | ||||
|         let segInfoMap = Object.create(null); | ||||
|  | ||||
|         /** | ||||
|          * Gets the flag which shows `super()` is called in some paths. | ||||
|          * @param {CodePathSegment} segment A code path segment to get. | ||||
|          * @returns {boolean} The flag which shows `super()` is called in some paths | ||||
|          */ | ||||
|         function isCalledInSomePath(segment) { | ||||
|             return segment.reachable && segInfoMap[segment.id].calledInSomePaths; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the flag which shows `super()` is called in all paths. | ||||
|          * @param {CodePathSegment} segment A code path segment to get. | ||||
|          * @returns {boolean} The flag which shows `super()` is called in all paths. | ||||
|          */ | ||||
|         function isCalledInEveryPath(segment) { | ||||
|  | ||||
|             /* | ||||
|              * If specific segment is the looped segment of the current segment, | ||||
|              * skip the segment. | ||||
|              * If not skipped, this never becomes true after a loop. | ||||
|              */ | ||||
|             if (segment.nextSegments.length === 1 && | ||||
|                 segment.nextSegments[0].isLoopedPrevSegment(segment) | ||||
|             ) { | ||||
|                 return true; | ||||
|             } | ||||
|             return segment.reachable && segInfoMap[segment.id].calledInEveryPaths; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             /** | ||||
|              * Stacks a constructor information. | ||||
|              * @param {CodePath} codePath A code path which was started. | ||||
|              * @param {ASTNode} node The current node. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             onCodePathStart(codePath, node) { | ||||
|                 if (isConstructorFunction(node)) { | ||||
|  | ||||
|                     // Class > ClassBody > MethodDefinition > FunctionExpression | ||||
|                     const classNode = node.parent.parent.parent; | ||||
|                     const superClass = classNode.superClass; | ||||
|  | ||||
|                     funcInfo = { | ||||
|                         upper: funcInfo, | ||||
|                         isConstructor: true, | ||||
|                         hasExtends: Boolean(superClass), | ||||
|                         superIsConstructor: isPossibleConstructor(superClass), | ||||
|                         codePath, | ||||
|                         currentSegments: new Set() | ||||
|                     }; | ||||
|                 } else { | ||||
|                     funcInfo = { | ||||
|                         upper: funcInfo, | ||||
|                         isConstructor: false, | ||||
|                         hasExtends: false, | ||||
|                         superIsConstructor: false, | ||||
|                         codePath, | ||||
|                         currentSegments: new Set() | ||||
|                     }; | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             /** | ||||
|              * Pops a constructor information. | ||||
|              * And reports if `super()` lacked. | ||||
|              * @param {CodePath} codePath A code path which was ended. | ||||
|              * @param {ASTNode} node The current node. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             onCodePathEnd(codePath, node) { | ||||
|                 const hasExtends = funcInfo.hasExtends; | ||||
|  | ||||
|                 // Pop. | ||||
|                 funcInfo = funcInfo.upper; | ||||
|  | ||||
|                 if (!hasExtends) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Reports if `super()` lacked. | ||||
|                 const segments = codePath.returnedSegments; | ||||
|                 const calledInEveryPaths = segments.every(isCalledInEveryPath); | ||||
|                 const calledInSomePaths = segments.some(isCalledInSomePath); | ||||
|  | ||||
|                 if (!calledInEveryPaths) { | ||||
|                     context.report({ | ||||
|                         messageId: calledInSomePaths | ||||
|                             ? "missingSome" | ||||
|                             : "missingAll", | ||||
|                         node: node.parent | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             /** | ||||
|              * Initialize information of a given code path segment. | ||||
|              * @param {CodePathSegment} segment A code path segment to initialize. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             onCodePathSegmentStart(segment) { | ||||
|  | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|  | ||||
|                 if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Initialize info. | ||||
|                 const info = segInfoMap[segment.id] = { | ||||
|                     calledInSomePaths: false, | ||||
|                     calledInEveryPaths: false, | ||||
|                     validNodes: [] | ||||
|                 }; | ||||
|  | ||||
|                 // When there are previous segments, aggregates these. | ||||
|                 const prevSegments = segment.prevSegments; | ||||
|  | ||||
|                 if (prevSegments.length > 0) { | ||||
|                     info.calledInSomePaths = prevSegments.some(isCalledInSomePath); | ||||
|                     info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|  | ||||
|             /** | ||||
|              * Update information of the code path segment when a code path was | ||||
|              * looped. | ||||
|              * @param {CodePathSegment} fromSegment The code path segment of the | ||||
|              *      end of a loop. | ||||
|              * @param {CodePathSegment} toSegment A code path segment of the head | ||||
|              *      of a loop. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             onCodePathSegmentLoop(fromSegment, toSegment) { | ||||
|                 if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Update information inside of the loop. | ||||
|                 const isRealLoop = toSegment.prevSegments.length >= 2; | ||||
|  | ||||
|                 funcInfo.codePath.traverseSegments( | ||||
|                     { first: toSegment, last: fromSegment }, | ||||
|                     segment => { | ||||
|                         const info = segInfoMap[segment.id]; | ||||
|                         const prevSegments = segment.prevSegments; | ||||
|  | ||||
|                         // Updates flags. | ||||
|                         info.calledInSomePaths = prevSegments.some(isCalledInSomePath); | ||||
|                         info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); | ||||
|  | ||||
|                         // If flags become true anew, reports the valid nodes. | ||||
|                         if (info.calledInSomePaths || isRealLoop) { | ||||
|                             const nodes = info.validNodes; | ||||
|  | ||||
|                             info.validNodes = []; | ||||
|  | ||||
|                             for (let i = 0; i < nodes.length; ++i) { | ||||
|                                 const node = nodes[i]; | ||||
|  | ||||
|                                 context.report({ | ||||
|                                     messageId: "duplicate", | ||||
|                                     node | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 ); | ||||
|             }, | ||||
|  | ||||
|             /** | ||||
|              * Checks for a call of `super()`. | ||||
|              * @param {ASTNode} node A CallExpression node to check. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             "CallExpression:exit"(node) { | ||||
|                 if (!(funcInfo && funcInfo.isConstructor)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Skips except `super()`. | ||||
|                 if (node.callee.type !== "Super") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Reports if needed. | ||||
|                 if (funcInfo.hasExtends) { | ||||
|                     const segments = funcInfo.currentSegments; | ||||
|                     let duplicate = false; | ||||
|                     let info = null; | ||||
|  | ||||
|                     for (const segment of segments) { | ||||
|  | ||||
|                         if (segment.reachable) { | ||||
|                             info = segInfoMap[segment.id]; | ||||
|  | ||||
|                             duplicate = duplicate || info.calledInSomePaths; | ||||
|                             info.calledInSomePaths = info.calledInEveryPaths = true; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     if (info) { | ||||
|                         if (duplicate) { | ||||
|                             context.report({ | ||||
|                                 messageId: "duplicate", | ||||
|                                 node | ||||
|                             }); | ||||
|                         } else if (!funcInfo.superIsConstructor) { | ||||
|                             context.report({ | ||||
|                                 messageId: "badSuper", | ||||
|                                 node | ||||
|                             }); | ||||
|                         } else { | ||||
|                             info.validNodes.push(node); | ||||
|                         } | ||||
|                     } | ||||
|                 } else if (isAnySegmentReachable(funcInfo.currentSegments)) { | ||||
|                     context.report({ | ||||
|                         messageId: "unexpected", | ||||
|                         node | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             /** | ||||
|              * Set the mark to the returned path as `super()` was called. | ||||
|              * @param {ASTNode} node A ReturnStatement node to check. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             ReturnStatement(node) { | ||||
|                 if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Skips if no argument. | ||||
|                 if (!node.argument) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Returning argument is a substitute of 'super()'. | ||||
|                 const segments = funcInfo.currentSegments; | ||||
|  | ||||
|                 for (const segment of segments) { | ||||
|  | ||||
|                     if (segment.reachable) { | ||||
|                         const info = segInfoMap[segment.id]; | ||||
|  | ||||
|                         info.calledInSomePaths = info.calledInEveryPaths = true; | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             /** | ||||
|              * Resets state. | ||||
|              * @returns {void} | ||||
|              */ | ||||
|             "Program:exit"() { | ||||
|                 segInfoMap = Object.create(null); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										486
									
								
								node_modules/eslint/lib/rules/curly.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								node_modules/eslint/lib/rules/curly.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,486 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag statements without curly braces | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent brace style for all control statements", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/curly" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["all"] | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 1 | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["multi", "multi-line", "multi-or-nest"] | ||||
|                         }, | ||||
|                         { | ||||
|                             enum: ["consistent"] | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 2 | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         messages: { | ||||
|             missingCurlyAfter: "Expected { after '{{name}}'.", | ||||
|             missingCurlyAfterCondition: "Expected { after '{{name}}' condition.", | ||||
|             unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.", | ||||
|             unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const multiOnly = (context.options[0] === "multi"); | ||||
|         const multiLine = (context.options[0] === "multi-line"); | ||||
|         const multiOrNest = (context.options[0] === "multi-or-nest"); | ||||
|         const consistent = (context.options[1] === "consistent"); | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Determines if a given node is a one-liner that's on the same line as it's preceding code. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code. | ||||
|          * @private | ||||
|          */ | ||||
|         function isCollapsedOneLiner(node) { | ||||
|             const before = sourceCode.getTokenBefore(node); | ||||
|             const last = sourceCode.getLastToken(node); | ||||
|             const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; | ||||
|  | ||||
|             return before.loc.start.line === lastExcludingSemicolon.loc.end.line; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines if a given node is a one-liner. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} True if the node is a one-liner. | ||||
|          * @private | ||||
|          */ | ||||
|         function isOneLiner(node) { | ||||
|             if (node.type === "EmptyStatement") { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             const first = sourceCode.getFirstToken(node); | ||||
|             const last = sourceCode.getLastToken(node); | ||||
|             const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; | ||||
|  | ||||
|             return first.loc.start.line === lastExcludingSemicolon.loc.end.line; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines if the given node is a lexical declaration (let, const, function, or class) | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} True if the node is a lexical declaration | ||||
|          * @private | ||||
|          */ | ||||
|         function isLexicalDeclaration(node) { | ||||
|             if (node.type === "VariableDeclaration") { | ||||
|                 return node.kind === "const" || node.kind === "let"; | ||||
|             } | ||||
|  | ||||
|             return node.type === "FunctionDeclaration" || node.type === "ClassDeclaration"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given token is an `else` token or not. | ||||
|          * @param {Token} token The token to check. | ||||
|          * @returns {boolean} `true` if the token is an `else` token. | ||||
|          */ | ||||
|         function isElseKeywordToken(token) { | ||||
|             return token.value === "else" && token.type === "Keyword"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the given node has an `else` keyword token as the first token after. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} `true` if the node is followed by an `else` keyword token. | ||||
|          */ | ||||
|         function isFollowedByElseKeyword(node) { | ||||
|             const nextToken = sourceCode.getTokenAfter(node); | ||||
|  | ||||
|             return Boolean(nextToken) && isElseKeywordToken(nextToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError. | ||||
|          * @param {Token} closingBracket The } token | ||||
|          * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block. | ||||
|          */ | ||||
|         function needsSemicolon(closingBracket) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(closingBracket); | ||||
|             const tokenAfter = sourceCode.getTokenAfter(closingBracket); | ||||
|             const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); | ||||
|  | ||||
|             if (astUtils.isSemicolonToken(tokenBefore)) { | ||||
|  | ||||
|                 // If the last statement already has a semicolon, don't add another one. | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             if (!tokenAfter) { | ||||
|  | ||||
|                 // If there are no statements after this block, there is no need to add a semicolon. | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") { | ||||
|  | ||||
|                 /* | ||||
|                  * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression), | ||||
|                  * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause | ||||
|                  * a SyntaxError if it was followed by `else`. | ||||
|                  */ | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) { | ||||
|  | ||||
|                 // If the next token is on the same line, insert a semicolon. | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             if (/^[([/`+-]/u.test(tokenAfter.value)) { | ||||
|  | ||||
|                 // If the next token starts with a character that would disrupt ASI, insert a semicolon. | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) { | ||||
|  | ||||
|                 // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI. | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             // Otherwise, do not insert a semicolon. | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the code represented by the given node contains an `if` statement | ||||
|          * that would become associated with an `else` keyword directly appended to that code. | ||||
|          * | ||||
|          * Examples where it returns `true`: | ||||
|          * | ||||
|          *    if (a) | ||||
|          *        foo(); | ||||
|          * | ||||
|          *    if (a) { | ||||
|          *        foo(); | ||||
|          *    } | ||||
|          * | ||||
|          *    if (a) | ||||
|          *        foo(); | ||||
|          *    else if (b) | ||||
|          *        bar(); | ||||
|          * | ||||
|          *    while (a) | ||||
|          *        if (b) | ||||
|          *            if(c) | ||||
|          *                foo(); | ||||
|          *            else | ||||
|          *                bar(); | ||||
|          * | ||||
|          * Examples where it returns `false`: | ||||
|          * | ||||
|          *    if (a) | ||||
|          *        foo(); | ||||
|          *    else | ||||
|          *        bar(); | ||||
|          * | ||||
|          *    while (a) { | ||||
|          *        if (b) | ||||
|          *            if(c) | ||||
|          *                foo(); | ||||
|          *            else | ||||
|          *                bar(); | ||||
|          *    } | ||||
|          * | ||||
|          *    while (a) | ||||
|          *        if (b) { | ||||
|          *            if(c) | ||||
|          *                foo(); | ||||
|          *        } | ||||
|          *        else | ||||
|          *            bar(); | ||||
|          * @param {ASTNode} node Node representing the code to check. | ||||
|          * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code. | ||||
|          */ | ||||
|         function hasUnsafeIf(node) { | ||||
|             switch (node.type) { | ||||
|                 case "IfStatement": | ||||
|                     if (!node.alternate) { | ||||
|                         return true; | ||||
|                     } | ||||
|                     return hasUnsafeIf(node.alternate); | ||||
|                 case "ForStatement": | ||||
|                 case "ForInStatement": | ||||
|                 case "ForOfStatement": | ||||
|                 case "LabeledStatement": | ||||
|                 case "WithStatement": | ||||
|                 case "WhileStatement": | ||||
|                     return hasUnsafeIf(node.body); | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code. | ||||
|          * The braces, which make the given block body, are necessary in either of the following situations: | ||||
|          * | ||||
|          * 1. The statement is a lexical declaration. | ||||
|          * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace: | ||||
|          * | ||||
|          *     if (a) { | ||||
|          *         if (b) | ||||
|          *             foo(); | ||||
|          *     } | ||||
|          *     else | ||||
|          *         bar(); | ||||
|          * | ||||
|          *     if (a) | ||||
|          *         while (b) | ||||
|          *             while (c) { | ||||
|          *                 while (d) | ||||
|          *                     if (e) | ||||
|          *                         while(f) | ||||
|          *                             foo(); | ||||
|          *            } | ||||
|          *     else | ||||
|          *         bar(); | ||||
|          * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements. | ||||
|          * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content) | ||||
|          * would change the semantics of the code or produce a syntax error. | ||||
|          */ | ||||
|         function areBracesNecessary(node) { | ||||
|             const statement = node.body[0]; | ||||
|  | ||||
|             return isLexicalDeclaration(statement) || | ||||
|                 hasUnsafeIf(statement) && isFollowedByElseKeyword(node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Prepares to check the body of a node to see if it's a block statement. | ||||
|          * @param {ASTNode} node The node to report if there's a problem. | ||||
|          * @param {ASTNode} body The body node to check for blocks. | ||||
|          * @param {string} name The name to report if there's a problem. | ||||
|          * @param {{ condition: boolean }} opts Options to pass to the report functions | ||||
|          * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. | ||||
|          *   "actual" will be `true` or `false` whether the body is already a block statement. | ||||
|          *   "expected" will be `true` or `false` if the body should be a block statement or not, or | ||||
|          *   `null` if it doesn't matter, depending on the rule options. It can be modified to change | ||||
|          *   the final behavior of "check". | ||||
|          *   "check" will be a function reporting appropriate problems depending on the other | ||||
|          *   properties. | ||||
|          */ | ||||
|         function prepareCheck(node, body, name, opts) { | ||||
|             const hasBlock = (body.type === "BlockStatement"); | ||||
|             let expected = null; | ||||
|  | ||||
|             if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) { | ||||
|                 expected = true; | ||||
|             } else if (multiOnly) { | ||||
|                 expected = false; | ||||
|             } else if (multiLine) { | ||||
|                 if (!isCollapsedOneLiner(body)) { | ||||
|                     expected = true; | ||||
|                 } | ||||
|  | ||||
|                 // otherwise, the body is allowed to have braces or not to have braces | ||||
|  | ||||
|             } else if (multiOrNest) { | ||||
|                 if (hasBlock) { | ||||
|                     const statement = body.body[0]; | ||||
|                     const leadingCommentsInBlock = sourceCode.getCommentsBefore(statement); | ||||
|  | ||||
|                     expected = !isOneLiner(statement) || leadingCommentsInBlock.length > 0; | ||||
|                 } else { | ||||
|                     expected = !isOneLiner(body); | ||||
|                 } | ||||
|             } else { | ||||
|  | ||||
|                 // default "all" | ||||
|                 expected = true; | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 actual: hasBlock, | ||||
|                 expected, | ||||
|                 check() { | ||||
|                     if (this.expected !== null && this.expected !== this.actual) { | ||||
|                         if (this.expected) { | ||||
|                             context.report({ | ||||
|                                 node, | ||||
|                                 loc: body.loc, | ||||
|                                 messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter", | ||||
|                                 data: { | ||||
|                                     name | ||||
|                                 }, | ||||
|                                 fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`) | ||||
|                             }); | ||||
|                         } else { | ||||
|                             context.report({ | ||||
|                                 node, | ||||
|                                 loc: body.loc, | ||||
|                                 messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter", | ||||
|                                 data: { | ||||
|                                     name | ||||
|                                 }, | ||||
|                                 fix(fixer) { | ||||
|  | ||||
|                                     /* | ||||
|                                      * `do while` expressions sometimes need a space to be inserted after `do`. | ||||
|                                      * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)` | ||||
|                                      */ | ||||
|                                     const needsPrecedingSpace = node.type === "DoWhileStatement" && | ||||
|                                         sourceCode.getTokenBefore(body).range[1] === body.range[0] && | ||||
|                                         !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 })); | ||||
|  | ||||
|                                     const openingBracket = sourceCode.getFirstToken(body); | ||||
|                                     const closingBracket = sourceCode.getLastToken(body); | ||||
|                                     const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket); | ||||
|  | ||||
|                                     if (needsSemicolon(closingBracket)) { | ||||
|  | ||||
|                                         /* | ||||
|                                          * If removing braces would cause a SyntaxError due to multiple statements on the same line (or | ||||
|                                          * change the semantics of the code due to ASI), don't perform a fix. | ||||
|                                          */ | ||||
|                                         return null; | ||||
|                                     } | ||||
|  | ||||
|                                     const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) + | ||||
|                                         sourceCode.getText(lastTokenInBlock) + | ||||
|                                         sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]); | ||||
|  | ||||
|                                     return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText); | ||||
|                                 } | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Prepares to check the bodies of a "if", "else if" and "else" chain. | ||||
|          * @param {ASTNode} node The first IfStatement node of the chain. | ||||
|          * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more | ||||
|          *   information. | ||||
|          */ | ||||
|         function prepareIfChecks(node) { | ||||
|             const preparedChecks = []; | ||||
|  | ||||
|             for (let currentNode = node; currentNode; currentNode = currentNode.alternate) { | ||||
|                 preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true })); | ||||
|                 if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") { | ||||
|                     preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else")); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (consistent) { | ||||
|  | ||||
|                 /* | ||||
|                  * If any node should have or already have braces, make sure they | ||||
|                  * all have braces. | ||||
|                  * If all nodes shouldn't have braces, make sure they don't. | ||||
|                  */ | ||||
|                 const expected = preparedChecks.some(preparedCheck => { | ||||
|                     if (preparedCheck.expected !== null) { | ||||
|                         return preparedCheck.expected; | ||||
|                     } | ||||
|                     return preparedCheck.actual; | ||||
|                 }); | ||||
|  | ||||
|                 preparedChecks.forEach(preparedCheck => { | ||||
|                     preparedCheck.expected = expected; | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             return preparedChecks; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             IfStatement(node) { | ||||
|                 const parent = node.parent; | ||||
|                 const isElseIf = parent.type === "IfStatement" && parent.alternate === node; | ||||
|  | ||||
|                 if (!isElseIf) { | ||||
|  | ||||
|                     // This is a top `if`, check the whole `if-else-if` chain | ||||
|                     prepareIfChecks(node).forEach(preparedCheck => { | ||||
|                         preparedCheck.check(); | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 // Skip `else if`, it's already checked (when the top `if` was visited) | ||||
|             }, | ||||
|  | ||||
|             WhileStatement(node) { | ||||
|                 prepareCheck(node, node.body, "while", { condition: true }).check(); | ||||
|             }, | ||||
|  | ||||
|             DoWhileStatement(node) { | ||||
|                 prepareCheck(node, node.body, "do").check(); | ||||
|             }, | ||||
|  | ||||
|             ForStatement(node) { | ||||
|                 prepareCheck(node, node.body, "for", { condition: true }).check(); | ||||
|             }, | ||||
|  | ||||
|             ForInStatement(node) { | ||||
|                 prepareCheck(node, node.body, "for-in").check(); | ||||
|             }, | ||||
|  | ||||
|             ForOfStatement(node) { | ||||
|                 prepareCheck(node, node.body, "for-of").check(); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										44
									
								
								node_modules/eslint/lib/rules/default-case-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								node_modules/eslint/lib/rules/default-case-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce default clauses in switch statements to be last | ||||
|  * @author Milos Djermanovic | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce default clauses in switch statements to be last", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/default-case-last" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             notLast: "Default clause should be the last clause." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         return { | ||||
|             SwitchStatement(node) { | ||||
|                 const cases = node.cases, | ||||
|                     indexOfDefault = cases.findIndex(c => c.test === null); | ||||
|  | ||||
|                 if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) { | ||||
|                     const defaultClause = cases[indexOfDefault]; | ||||
|  | ||||
|                     context.report({ node: defaultClause, messageId: "notLast" }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										97
									
								
								node_modules/eslint/lib/rules/default-case.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								node_modules/eslint/lib/rules/default-case.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| /** | ||||
|  * @fileoverview require default case in switch statements | ||||
|  * @author Aliaksei Shytkin | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const DEFAULT_COMMENT_PATTERN = /^no default$/iu; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `default` cases in `switch` statements", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/default-case" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 commentPattern: { | ||||
|                     type: "string" | ||||
|                 } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             missingDefaultCase: "Expected a default case." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const commentPattern = options.commentPattern | ||||
|             ? new RegExp(options.commentPattern, "u") | ||||
|             : DEFAULT_COMMENT_PATTERN; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Shortcut to get last element of array | ||||
|          * @param {*[]} collection Array | ||||
|          * @returns {any} Last element | ||||
|          */ | ||||
|         function last(collection) { | ||||
|             return collection[collection.length - 1]; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             SwitchStatement(node) { | ||||
|  | ||||
|                 if (!node.cases.length) { | ||||
|  | ||||
|                     /* | ||||
|                      * skip check of empty switch because there is no easy way | ||||
|                      * to extract comments inside it now | ||||
|                      */ | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const hasDefault = node.cases.some(v => v.test === null); | ||||
|  | ||||
|                 if (!hasDefault) { | ||||
|  | ||||
|                     let comment; | ||||
|  | ||||
|                     const lastCase = last(node.cases); | ||||
|                     const comments = sourceCode.getCommentsAfter(lastCase); | ||||
|  | ||||
|                     if (comments.length) { | ||||
|                         comment = last(comments); | ||||
|                     } | ||||
|  | ||||
|                     if (!comment || !commentPattern.test(comment.value.trim())) { | ||||
|                         context.report({ node, messageId: "missingDefaultCase" }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										62
									
								
								node_modules/eslint/lib/rules/default-param-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								node_modules/eslint/lib/rules/default-param-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /** | ||||
|  * @fileoverview enforce default parameters to be last | ||||
|  * @author Chiawen Chen | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce default parameters to be last", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/default-param-last" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             shouldBeLast: "Default parameters should be last." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /** | ||||
|          * Handler for function contexts. | ||||
|          * @param {ASTNode} node function node | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function handleFunction(node) { | ||||
|             let hasSeenPlainParam = false; | ||||
|  | ||||
|             for (let i = node.params.length - 1; i >= 0; i -= 1) { | ||||
|                 const param = node.params[i]; | ||||
|  | ||||
|                 if ( | ||||
|                     param.type !== "AssignmentPattern" && | ||||
|                     param.type !== "RestElement" | ||||
|                 ) { | ||||
|                     hasSeenPlainParam = true; | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (hasSeenPlainParam && param.type === "AssignmentPattern") { | ||||
|                     context.report({ | ||||
|                         node: param, | ||||
|                         messageId: "shouldBeLast" | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: handleFunction, | ||||
|             FunctionExpression: handleFunction, | ||||
|             ArrowFunctionExpression: handleFunction | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										108
									
								
								node_modules/eslint/lib/rules/dot-location.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								node_modules/eslint/lib/rules/dot-location.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /** | ||||
|  * @fileoverview Validates newlines before and after dots | ||||
|  * @author Greg Cochard | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent newlines before and after dots", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/dot-location" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["object", "property"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         messages: { | ||||
|             expectedDotAfterObject: "Expected dot to be on same line as object.", | ||||
|             expectedDotBeforeProperty: "Expected dot to be on same line as property." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const config = context.options[0]; | ||||
|  | ||||
|         // default to onObject if no preference is passed | ||||
|         const onObject = config === "object" || !config; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Reports if the dot between object and property is on the correct location. | ||||
|          * @param {ASTNode} node The `MemberExpression` node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkDotLocation(node) { | ||||
|             const property = node.property; | ||||
|             const dotToken = sourceCode.getTokenBefore(property); | ||||
|  | ||||
|             if (onObject) { | ||||
|  | ||||
|                 // `obj` expression can be parenthesized, but those paren tokens are not a part of the `obj` node. | ||||
|                 const tokenBeforeDot = sourceCode.getTokenBefore(dotToken); | ||||
|  | ||||
|                 if (!astUtils.isTokenOnSameLine(tokenBeforeDot, dotToken)) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: dotToken.loc, | ||||
|                         messageId: "expectedDotAfterObject", | ||||
|                         *fix(fixer) { | ||||
|                             if (dotToken.value.startsWith(".") && astUtils.isDecimalIntegerNumericToken(tokenBeforeDot)) { | ||||
|                                 yield fixer.insertTextAfter(tokenBeforeDot, ` ${dotToken.value}`); | ||||
|                             } else { | ||||
|                                 yield fixer.insertTextAfter(tokenBeforeDot, dotToken.value); | ||||
|                             } | ||||
|                             yield fixer.remove(dotToken); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } else if (!astUtils.isTokenOnSameLine(dotToken, property)) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: dotToken.loc, | ||||
|                     messageId: "expectedDotBeforeProperty", | ||||
|                     *fix(fixer) { | ||||
|                         yield fixer.remove(dotToken); | ||||
|                         yield fixer.insertTextBefore(property, dotToken.value); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks the spacing of the dot within a member expression. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkNode(node) { | ||||
|             if (!node.computed) { | ||||
|                 checkDotLocation(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             MemberExpression: checkNode | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										176
									
								
								node_modules/eslint/lib/rules/dot-notation.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								node_modules/eslint/lib/rules/dot-notation.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible. | ||||
|  * @author Josh Perez | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const keywords = require("./utils/keywords"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u; | ||||
|  | ||||
| // `null` literal must be handled separately. | ||||
| const literalTypesToCheck = new Set(["string", "boolean"]); | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce dot notation whenever possible", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/dot-notation" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allowKeywords: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     }, | ||||
|                     allowPattern: { | ||||
|                         type: "string", | ||||
|                         default: "" | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         messages: { | ||||
|             useDot: "[{{key}}] is better written in dot notation.", | ||||
|             useBrackets: ".{{key}} is a syntax error." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const allowKeywords = options.allowKeywords === void 0 || options.allowKeywords; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let allowPattern; | ||||
|  | ||||
|         if (options.allowPattern) { | ||||
|             allowPattern = new RegExp(options.allowPattern, "u"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if the property is valid dot notation | ||||
|          * @param {ASTNode} node The dot notation node | ||||
|          * @param {string} value Value which is to be checked | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkComputedProperty(node, value) { | ||||
|             if ( | ||||
|                 validIdentifier.test(value) && | ||||
|                 (allowKeywords || !keywords.includes(String(value))) && | ||||
|                 !(allowPattern && allowPattern.test(value)) | ||||
|             ) { | ||||
|                 const formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : `\`${value}\``; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: node.property, | ||||
|                     messageId: "useDot", | ||||
|                     data: { | ||||
|                         key: formattedValue | ||||
|                     }, | ||||
|                     *fix(fixer) { | ||||
|                         const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken); | ||||
|                         const rightBracket = sourceCode.getLastToken(node); | ||||
|                         const nextToken = sourceCode.getTokenAfter(node); | ||||
|  | ||||
|                         // Don't perform any fixes if there are comments inside the brackets. | ||||
|                         if (sourceCode.commentsExistBetween(leftBracket, rightBracket)) { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         // Replace the brackets by an identifier. | ||||
|                         if (!node.optional) { | ||||
|                             yield fixer.insertTextBefore( | ||||
|                                 leftBracket, | ||||
|                                 astUtils.isDecimalInteger(node.object) ? " ." : "." | ||||
|                             ); | ||||
|                         } | ||||
|                         yield fixer.replaceTextRange( | ||||
|                             [leftBracket.range[0], rightBracket.range[1]], | ||||
|                             value | ||||
|                         ); | ||||
|  | ||||
|                         // Insert a space after the property if it will be connected to the next token. | ||||
|                         if ( | ||||
|                             nextToken && | ||||
|                             rightBracket.range[1] === nextToken.range[0] && | ||||
|                             !astUtils.canTokensBeAdjacent(String(value), nextToken) | ||||
|                         ) { | ||||
|                             yield fixer.insertTextAfter(node, " "); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             MemberExpression(node) { | ||||
|                 if ( | ||||
|                     node.computed && | ||||
|                     node.property.type === "Literal" && | ||||
|                     (literalTypesToCheck.has(typeof node.property.value) || astUtils.isNullLiteral(node.property)) | ||||
|                 ) { | ||||
|                     checkComputedProperty(node, node.property.value); | ||||
|                 } | ||||
|                 if ( | ||||
|                     node.computed && | ||||
|                     astUtils.isStaticTemplateLiteral(node.property) | ||||
|                 ) { | ||||
|                     checkComputedProperty(node, node.property.quasis[0].value.cooked); | ||||
|                 } | ||||
|                 if ( | ||||
|                     !allowKeywords && | ||||
|                     !node.computed && | ||||
|                     node.property.type === "Identifier" && | ||||
|                     keywords.includes(String(node.property.name)) | ||||
|                 ) { | ||||
|                     context.report({ | ||||
|                         node: node.property, | ||||
|                         messageId: "useBrackets", | ||||
|                         data: { | ||||
|                             key: node.property.name | ||||
|                         }, | ||||
|                         *fix(fixer) { | ||||
|                             const dotToken = sourceCode.getTokenBefore(node.property); | ||||
|  | ||||
|                             // A statement that starts with `let[` is parsed as a destructuring variable declaration, not a MemberExpression. | ||||
|                             if (node.object.type === "Identifier" && node.object.name === "let" && !node.optional) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             // Don't perform any fixes if there are comments between the dot and the property name. | ||||
|                             if (sourceCode.commentsExistBetween(dotToken, node.property)) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             // Replace the identifier to brackets. | ||||
|                             if (!node.optional) { | ||||
|                                 yield fixer.remove(dotToken); | ||||
|                             } | ||||
|                             yield fixer.replaceText(node.property, `["${node.property.name}"]`); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										115
									
								
								node_modules/eslint/lib/rules/eol-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								node_modules/eslint/lib/rules/eol-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /** | ||||
|  * @fileoverview Require or disallow newline at the end of files | ||||
|  * @author Nodeca Team <https://github.com/nodeca> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow newline at the end of files", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/eol-last" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "never", "unix", "windows"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             missing: "Newline required at end of file but not found.", | ||||
|             unexpected: "Newline not allowed at end of file." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program: function checkBadEOF(node) { | ||||
|                 const sourceCode = context.sourceCode, | ||||
|                     src = sourceCode.getText(), | ||||
|                     lastLine = sourceCode.lines[sourceCode.lines.length - 1], | ||||
|                     location = { | ||||
|                         column: lastLine.length, | ||||
|                         line: sourceCode.lines.length | ||||
|                     }, | ||||
|                     LF = "\n", | ||||
|                     CRLF = `\r${LF}`, | ||||
|                     endsWithNewline = src.endsWith(LF); | ||||
|  | ||||
|                 /* | ||||
|                  * Empty source is always valid: No content in file so we don't | ||||
|                  * need to lint for a newline on the last line of content. | ||||
|                  */ | ||||
|                 if (!src.length) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 let mode = context.options[0] || "always", | ||||
|                     appendCRLF = false; | ||||
|  | ||||
|                 if (mode === "unix") { | ||||
|  | ||||
|                     // `"unix"` should behave exactly as `"always"` | ||||
|                     mode = "always"; | ||||
|                 } | ||||
|                 if (mode === "windows") { | ||||
|  | ||||
|                     // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility | ||||
|                     mode = "always"; | ||||
|                     appendCRLF = true; | ||||
|                 } | ||||
|                 if (mode === "always" && !endsWithNewline) { | ||||
|  | ||||
|                     // File is not newline-terminated, but should be | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: location, | ||||
|                         messageId: "missing", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF); | ||||
|                         } | ||||
|                     }); | ||||
|                 } else if (mode === "never" && endsWithNewline) { | ||||
|  | ||||
|                     const secondLastLine = sourceCode.lines[sourceCode.lines.length - 2]; | ||||
|  | ||||
|                     // File is newline-terminated, but shouldn't be | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: { | ||||
|                             start: { line: sourceCode.lines.length - 1, column: secondLastLine.length }, | ||||
|                             end: { line: sourceCode.lines.length, column: 0 } | ||||
|                         }, | ||||
|                         messageId: "unexpected", | ||||
|                         fix(fixer) { | ||||
|                             const finalEOLs = /(?:\r?\n)+$/u, | ||||
|                                 match = finalEOLs.exec(sourceCode.text), | ||||
|                                 start = match.index, | ||||
|                                 end = sourceCode.text.length; | ||||
|  | ||||
|                             return fixer.replaceTextRange([start, end], ""); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										174
									
								
								node_modules/eslint/lib/rules/eqeqeq.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								node_modules/eslint/lib/rules/eqeqeq.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag statements that use != and == instead of !== and === | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require the use of `===` and `!==`", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/eqeqeq" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["always"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 null: { | ||||
|                                     enum: ["always", "never", "ignore"] | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ], | ||||
|                     additionalItems: false | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["smart", "allow-null"] | ||||
|                         } | ||||
|                     ], | ||||
|                     additionalItems: false | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const config = context.options[0] || "always"; | ||||
|         const options = context.options[1] || {}; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         const nullOption = (config === "always") | ||||
|             ? options.null || "always" | ||||
|             : "ignore"; | ||||
|         const enforceRuleForNull = (nullOption === "always"); | ||||
|         const enforceInverseRuleForNull = (nullOption === "never"); | ||||
|  | ||||
|         /** | ||||
|          * Checks if an expression is a typeof expression | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} if the node is a typeof expression | ||||
|          */ | ||||
|         function isTypeOf(node) { | ||||
|             return node.type === "UnaryExpression" && node.operator === "typeof"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if either operand of a binary expression is a typeof operation | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} if one of the operands is typeof | ||||
|          * @private | ||||
|          */ | ||||
|         function isTypeOfBinary(node) { | ||||
|             return isTypeOf(node.left) || isTypeOf(node.right); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if operands are literals of the same type (via typeof) | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} if operands are of same type | ||||
|          * @private | ||||
|          */ | ||||
|         function areLiteralsAndSameType(node) { | ||||
|             return node.left.type === "Literal" && node.right.type === "Literal" && | ||||
|                     typeof node.left.value === typeof node.right.value; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if one of the operands is a literal null | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} if operands are null | ||||
|          * @private | ||||
|          */ | ||||
|         function isNullCheck(node) { | ||||
|             return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a message for this rule. | ||||
|          * @param {ASTNode} node The binary expression node that was checked | ||||
|          * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node, expectedOperator) { | ||||
|             const operatorToken = sourceCode.getFirstTokenBetween( | ||||
|                 node.left, | ||||
|                 node.right, | ||||
|                 token => token.value === node.operator | ||||
|             ); | ||||
|  | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: operatorToken.loc, | ||||
|                 messageId: "unexpected", | ||||
|                 data: { expectedOperator, actualOperator: node.operator }, | ||||
|                 fix(fixer) { | ||||
|  | ||||
|                     // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. | ||||
|                     if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { | ||||
|                         return fixer.replaceText(operatorToken, expectedOperator); | ||||
|                     } | ||||
|                     return null; | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             BinaryExpression(node) { | ||||
|                 const isNull = isNullCheck(node); | ||||
|  | ||||
|                 if (node.operator !== "==" && node.operator !== "!=") { | ||||
|                     if (enforceInverseRuleForNull && isNull) { | ||||
|                         report(node, node.operator.slice(0, -1)); | ||||
|                     } | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (config === "smart" && (isTypeOfBinary(node) || | ||||
|                         areLiteralsAndSameType(node) || isNull)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (!enforceRuleForNull && isNull) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 report(node, `${node.operator}=`); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										140
									
								
								node_modules/eslint/lib/rules/for-direction.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								node_modules/eslint/lib/rules/for-direction.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| /** | ||||
|  * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction) | ||||
|  * @author Aladdin-ADD<hh_2013@foxmail.com> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const { getStaticValue } = require("@eslint-community/eslint-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce \"for\" loop update clause moving the counter in the right direction", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/for-direction" | ||||
|         }, | ||||
|  | ||||
|         fixable: null, | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             incorrectDirection: "The update clause in this loop moves the variable in the wrong direction." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const { sourceCode } = context; | ||||
|  | ||||
|         /** | ||||
|          * report an error. | ||||
|          * @param {ASTNode} node the node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(node) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId: "incorrectDirection" | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * check the right side of the assignment | ||||
|          * @param {ASTNode} update UpdateExpression to check | ||||
|          * @param {int} dir expected direction that could either be turned around or invalidated | ||||
|          * @returns {int} return dir, the negated dir, or zero if the counter does not change or the direction is not clear | ||||
|          */ | ||||
|         function getRightDirection(update, dir) { | ||||
|             const staticValue = getStaticValue(update.right, sourceCode.getScope(update)); | ||||
|  | ||||
|             if (staticValue && ["bigint", "boolean", "number"].includes(typeof staticValue.value)) { | ||||
|                 const sign = Math.sign(Number(staticValue.value)) || 0; // convert NaN to 0 | ||||
|  | ||||
|                 return dir * sign; | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * check UpdateExpression add/sub the counter | ||||
|          * @param {ASTNode} update UpdateExpression to check | ||||
|          * @param {string} counter variable name to check | ||||
|          * @returns {int} if add return 1, if sub return -1, if nochange, return 0 | ||||
|          */ | ||||
|         function getUpdateDirection(update, counter) { | ||||
|             if (update.argument.type === "Identifier" && update.argument.name === counter) { | ||||
|                 if (update.operator === "++") { | ||||
|                     return 1; | ||||
|                 } | ||||
|                 if (update.operator === "--") { | ||||
|                     return -1; | ||||
|                 } | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * check AssignmentExpression add/sub the counter | ||||
|          * @param {ASTNode} update AssignmentExpression to check | ||||
|          * @param {string} counter variable name to check | ||||
|          * @returns {int} if add return 1, if sub return -1, if nochange, return 0 | ||||
|          */ | ||||
|         function getAssignmentDirection(update, counter) { | ||||
|             if (update.left.name === counter) { | ||||
|                 if (update.operator === "+=") { | ||||
|                     return getRightDirection(update, 1); | ||||
|                 } | ||||
|                 if (update.operator === "-=") { | ||||
|                     return getRightDirection(update, -1); | ||||
|                 } | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ForStatement(node) { | ||||
|  | ||||
|                 if (node.test && node.test.type === "BinaryExpression" && node.update) { | ||||
|                     for (const counterPosition of ["left", "right"]) { | ||||
|                         if (node.test[counterPosition].type !== "Identifier") { | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         const counter = node.test[counterPosition].name; | ||||
|                         const operator = node.test.operator; | ||||
|                         const update = node.update; | ||||
|  | ||||
|                         let wrongDirection; | ||||
|  | ||||
|                         if (operator === "<" || operator === "<=") { | ||||
|                             wrongDirection = counterPosition === "left" ? -1 : 1; | ||||
|                         } else if (operator === ">" || operator === ">=") { | ||||
|                             wrongDirection = counterPosition === "left" ? 1 : -1; | ||||
|                         } else { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         if (update.type === "UpdateExpression") { | ||||
|                             if (getUpdateDirection(update, counter) === wrongDirection) { | ||||
|                                 report(node); | ||||
|                             } | ||||
|                         } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) { | ||||
|                             report(node); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										233
									
								
								node_modules/eslint/lib/rules/func-call-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								node_modules/eslint/lib/rules/func-call-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,233 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to control spacing within function calls | ||||
|  * @author Matt DuVall <http://www.mattduvall.com> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow spacing between function identifiers and their invocations", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/func-call-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["never"] | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 1 | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["always"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 allowNewlines: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 2 | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedWhitespace: "Unexpected whitespace between function name and paren.", | ||||
|             unexpectedNewline: "Unexpected newline between function name and paren.", | ||||
|             missing: "Missing space between function name and paren." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const never = context.options[0] !== "always"; | ||||
|         const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const text = sourceCode.getText(); | ||||
|  | ||||
|         /** | ||||
|          * Check if open space is present in a function name | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee. | ||||
|          * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkSpacing(node, leftToken, rightToken) { | ||||
|             const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, ""); | ||||
|             const hasWhitespace = /\s/u.test(textBetweenTokens); | ||||
|             const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens); | ||||
|  | ||||
|             /* | ||||
|              * never allowNewlines hasWhitespace hasNewline message | ||||
|              * F     F             F             F          Missing space between function name and paren. | ||||
|              * F     F             F             T          (Invalid `!hasWhitespace && hasNewline`) | ||||
|              * F     F             T             T          Unexpected newline between function name and paren. | ||||
|              * F     F             T             F          (OK) | ||||
|              * F     T             T             F          (OK) | ||||
|              * F     T             T             T          (OK) | ||||
|              * F     T             F             T          (Invalid `!hasWhitespace && hasNewline`) | ||||
|              * F     T             F             F          Missing space between function name and paren. | ||||
|              * T     T             F             F          (Invalid `never && allowNewlines`) | ||||
|              * T     T             F             T          (Invalid `!hasWhitespace && hasNewline`) | ||||
|              * T     T             T             T          (Invalid `never && allowNewlines`) | ||||
|              * T     T             T             F          (Invalid `never && allowNewlines`) | ||||
|              * T     F             T             F          Unexpected space between function name and paren. | ||||
|              * T     F             T             T          Unexpected space between function name and paren. | ||||
|              * T     F             F             T          (Invalid `!hasWhitespace && hasNewline`) | ||||
|              * T     F             F             F          (OK) | ||||
|              * | ||||
|              * T                   T                        Unexpected space between function name and paren. | ||||
|              * F                   F                        Missing space between function name and paren. | ||||
|              * F     F                           T          Unexpected newline between function name and paren. | ||||
|              */ | ||||
|  | ||||
|             if (never && hasWhitespace) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: { | ||||
|                         start: leftToken.loc.end, | ||||
|                         end: { | ||||
|                             line: rightToken.loc.start.line, | ||||
|                             column: rightToken.loc.start.column - 1 | ||||
|                         } | ||||
|                     }, | ||||
|                     messageId: "unexpectedWhitespace", | ||||
|                     fix(fixer) { | ||||
|  | ||||
|                         // Don't remove comments. | ||||
|                         if (sourceCode.commentsExistBetween(leftToken, rightToken)) { | ||||
|                             return null; | ||||
|                         } | ||||
|  | ||||
|                         // If `?.` exists, it doesn't hide no-unexpected-multiline errors | ||||
|                         if (node.optional) { | ||||
|                             return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?."); | ||||
|                         } | ||||
|  | ||||
|                         /* | ||||
|                          * Only autofix if there is no newline | ||||
|                          * https://github.com/eslint/eslint/issues/7787 | ||||
|                          */ | ||||
|                         if (hasNewline) { | ||||
|                             return null; | ||||
|                         } | ||||
|                         return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } else if (!never && !hasWhitespace) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: { | ||||
|                         start: { | ||||
|                             line: leftToken.loc.end.line, | ||||
|                             column: leftToken.loc.end.column - 1 | ||||
|                         }, | ||||
|                         end: rightToken.loc.start | ||||
|                     }, | ||||
|                     messageId: "missing", | ||||
|                     fix(fixer) { | ||||
|                         if (node.optional) { | ||||
|                             return null; // Not sure if inserting a space to either before/after `?.` token. | ||||
|                         } | ||||
|                         return fixer.insertTextBefore(rightToken, " "); | ||||
|                     } | ||||
|                 }); | ||||
|             } else if (!never && !allowNewlines && hasNewline) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: { | ||||
|                         start: leftToken.loc.end, | ||||
|                         end: rightToken.loc.start | ||||
|                     }, | ||||
|                     messageId: "unexpectedNewline", | ||||
|                     fix(fixer) { | ||||
|  | ||||
|                         /* | ||||
|                          * Only autofix if there is no newline | ||||
|                          * https://github.com/eslint/eslint/issues/7787 | ||||
|                          * But if `?.` exists, it doesn't hide no-unexpected-multiline errors | ||||
|                          */ | ||||
|                         if (!node.optional) { | ||||
|                             return null; | ||||
|                         } | ||||
|  | ||||
|                         // Don't remove comments. | ||||
|                         if (sourceCode.commentsExistBetween(leftToken, rightToken)) { | ||||
|                             return null; | ||||
|                         } | ||||
|  | ||||
|                         const range = [leftToken.range[1], rightToken.range[0]]; | ||||
|                         const qdToken = sourceCode.getTokenAfter(leftToken); | ||||
|  | ||||
|                         if (qdToken.range[0] === leftToken.range[1]) { | ||||
|                             return fixer.replaceTextRange(range, "?. "); | ||||
|                         } | ||||
|                         if (qdToken.range[1] === rightToken.range[0]) { | ||||
|                             return fixer.replaceTextRange(range, " ?."); | ||||
|                         } | ||||
|                         return fixer.replaceTextRange(range, " ?. "); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "CallExpression, NewExpression"(node) { | ||||
|                 const lastToken = sourceCode.getLastToken(node); | ||||
|                 const lastCalleeToken = sourceCode.getLastToken(node.callee); | ||||
|                 const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken); | ||||
|                 const prevToken = parenToken && sourceCode.getTokenBefore(parenToken, astUtils.isNotQuestionDotToken); | ||||
|  | ||||
|                 // Parens in NewExpression are optional | ||||
|                 if (!(parenToken && parenToken.range[1] < node.range[1])) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 checkSpacing(node, prevToken, parenToken); | ||||
|             }, | ||||
|  | ||||
|             ImportExpression(node) { | ||||
|                 const leftToken = sourceCode.getFirstToken(node); | ||||
|                 const rightToken = sourceCode.getTokenAfter(leftToken); | ||||
|  | ||||
|                 checkSpacing(node, leftToken, rightToken); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										253
									
								
								node_modules/eslint/lib/rules/func-name-matching.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								node_modules/eslint/lib/rules/func-name-matching.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,253 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned. | ||||
|  * @author Annie Zhang, Pavel Strashkin | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //-------------------------------------------------------------------------- | ||||
| // Requirements | ||||
| //-------------------------------------------------------------------------- | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const esutils = require("esutils"); | ||||
|  | ||||
| //-------------------------------------------------------------------------- | ||||
| // Helpers | ||||
| //-------------------------------------------------------------------------- | ||||
|  | ||||
| /** | ||||
|  * Determines if a pattern is `module.exports` or `module["exports"]` | ||||
|  * @param {ASTNode} pattern The left side of the AssignmentExpression | ||||
|  * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]` | ||||
|  */ | ||||
| function isModuleExports(pattern) { | ||||
|     if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") { | ||||
|  | ||||
|         // module.exports | ||||
|         if (pattern.property.type === "Identifier" && pattern.property.name === "exports") { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         // module["exports"] | ||||
|         if (pattern.property.type === "Literal" && pattern.property.value === "exports") { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Determines if a string name is a valid identifier | ||||
|  * @param {string} name The string to be checked | ||||
|  * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config | ||||
|  * @returns {boolean} True if the string is a valid identifier | ||||
|  */ | ||||
| function isIdentifier(name, ecmaVersion) { | ||||
|     if (ecmaVersion >= 2015) { | ||||
|         return esutils.keyword.isIdentifierES6(name); | ||||
|     } | ||||
|     return esutils.keyword.isIdentifierES5(name); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const alwaysOrNever = { enum: ["always", "never"] }; | ||||
| const optionsObject = { | ||||
|     type: "object", | ||||
|     properties: { | ||||
|         considerPropertyDescriptor: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         includeCommonJSModuleExports: { | ||||
|             type: "boolean" | ||||
|         } | ||||
|     }, | ||||
|     additionalProperties: false | ||||
| }; | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require function names to match the name of the variable or property to which they are assigned", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/func-name-matching" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [{ | ||||
|                 type: "array", | ||||
|                 additionalItems: false, | ||||
|                 items: [alwaysOrNever, optionsObject] | ||||
|             }, { | ||||
|                 type: "array", | ||||
|                 additionalItems: false, | ||||
|                 items: [optionsObject] | ||||
|             }] | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`.", | ||||
|             matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`.", | ||||
|             notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`.", | ||||
|             notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {}; | ||||
|         const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; | ||||
|         const considerPropertyDescriptor = options.considerPropertyDescriptor; | ||||
|         const includeModuleExports = options.includeCommonJSModuleExports; | ||||
|         const ecmaVersion = context.languageOptions.ecmaVersion; | ||||
|  | ||||
|         /** | ||||
|          * Check whether node is a certain CallExpression. | ||||
|          * @param {string} objName object name | ||||
|          * @param {string} funcName function name | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} `true` if node matches CallExpression | ||||
|          */ | ||||
|         function isPropertyCall(objName, funcName, node) { | ||||
|             if (!node) { | ||||
|                 return false; | ||||
|             } | ||||
|             return node.type === "CallExpression" && astUtils.isSpecificMemberAccess(node.callee, objName, funcName); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Compares identifiers based on the nameMatches option | ||||
|          * @param {string} x the first identifier | ||||
|          * @param {string} y the second identifier | ||||
|          * @returns {boolean} whether the two identifiers should warn. | ||||
|          */ | ||||
|         function shouldWarn(x, y) { | ||||
|             return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports | ||||
|          * @param {ASTNode} node The node to report | ||||
|          * @param {string} name The variable or property name | ||||
|          * @param {string} funcName The function name | ||||
|          * @param {boolean} isProp True if the reported node is a property assignment | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(node, name, funcName, isProp) { | ||||
|             let messageId; | ||||
|  | ||||
|             if (nameMatches === "always" && isProp) { | ||||
|                 messageId = "matchProperty"; | ||||
|             } else if (nameMatches === "always") { | ||||
|                 messageId = "matchVariable"; | ||||
|             } else if (isProp) { | ||||
|                 messageId = "notMatchProperty"; | ||||
|             } else { | ||||
|                 messageId = "notMatchVariable"; | ||||
|             } | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId, | ||||
|                 data: { | ||||
|                     name, | ||||
|                     funcName | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether a given node is a string literal | ||||
|          * @param {ASTNode} node The node to check | ||||
|          * @returns {boolean} `true` if the node is a string literal | ||||
|          */ | ||||
|         function isStringLiteral(node) { | ||||
|             return node.type === "Literal" && typeof node.value === "string"; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             VariableDeclarator(node) { | ||||
|                 if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") { | ||||
|                     return; | ||||
|                 } | ||||
|                 if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { | ||||
|                     report(node, node.id.name, node.init.id.name, false); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             AssignmentExpression(node) { | ||||
|                 if ( | ||||
|                     node.right.type !== "FunctionExpression" || | ||||
|                     (node.left.computed && node.left.property.type !== "Literal") || | ||||
|                     (!includeModuleExports && isModuleExports(node.left)) || | ||||
|                     (node.left.type !== "Identifier" && node.left.type !== "MemberExpression") | ||||
|                 ) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const isProp = node.left.type === "MemberExpression"; | ||||
|                 const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; | ||||
|  | ||||
|                 if (node.right.id && name && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { | ||||
|                     report(node, name, node.right.id.name, isProp); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             "Property, PropertyDefinition[value]"(node) { | ||||
|                 if (!(node.value.type === "FunctionExpression" && node.value.id)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (node.key.type === "Identifier" && !node.computed) { | ||||
|                     const functionName = node.value.id.name; | ||||
|                     let propertyName = node.key.name; | ||||
|  | ||||
|                     if ( | ||||
|                         considerPropertyDescriptor && | ||||
|                         propertyName === "value" && | ||||
|                         node.parent.type === "ObjectExpression" | ||||
|                     ) { | ||||
|                         if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) { | ||||
|                             const property = node.parent.parent.arguments[1]; | ||||
|  | ||||
|                             if (isStringLiteral(property) && shouldWarn(property.value, functionName)) { | ||||
|                                 report(node, property.value, functionName, true); | ||||
|                             } | ||||
|                         } else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) { | ||||
|                             propertyName = node.parent.parent.key.name; | ||||
|                             if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { | ||||
|                                 report(node, propertyName, functionName, true); | ||||
|                             } | ||||
|                         } else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) { | ||||
|                             propertyName = node.parent.parent.key.name; | ||||
|                             if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { | ||||
|                                 report(node, propertyName, functionName, true); | ||||
|                             } | ||||
|                         } else if (shouldWarn(propertyName, functionName)) { | ||||
|                             report(node, propertyName, functionName, true); | ||||
|                         } | ||||
|                     } else if (shouldWarn(propertyName, functionName)) { | ||||
|                         report(node, propertyName, functionName, true); | ||||
|                     } | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if ( | ||||
|                     isStringLiteral(node.key) && | ||||
|                     isIdentifier(node.key.value, ecmaVersion) && | ||||
|                     shouldWarn(node.key.value, node.value.id.name) | ||||
|                 ) { | ||||
|                     report(node, node.key.value, node.value.id.name, true); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										191
									
								
								node_modules/eslint/lib/rules/func-names.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								node_modules/eslint/lib/rules/func-names.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to warn when a function expression does not have a name. | ||||
|  * @author Kyle T. Nunery | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given variable is a function name. | ||||
|  * @param {eslint-scope.Variable} variable A variable to check. | ||||
|  * @returns {boolean} `true` if the variable is a function name. | ||||
|  */ | ||||
| function isFunctionName(variable) { | ||||
|     return variable && variable.defs[0].type === "FunctionName"; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow named `function` expressions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/func-names" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             definitions: { | ||||
|                 value: { | ||||
|                     enum: [ | ||||
|                         "always", | ||||
|                         "as-needed", | ||||
|                         "never" | ||||
|                     ] | ||||
|                 } | ||||
|             }, | ||||
|             items: [ | ||||
|                 { | ||||
|                     $ref: "#/definitions/value" | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "object", | ||||
|                     properties: { | ||||
|                         generators: { | ||||
|                             $ref: "#/definitions/value" | ||||
|                         } | ||||
|                     }, | ||||
|                     additionalProperties: false | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|  | ||||
|         messages: { | ||||
|             unnamed: "Unexpected unnamed {{name}}.", | ||||
|             named: "Unexpected named {{name}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Returns the config option for the given node. | ||||
|          * @param {ASTNode} node A node to get the config for. | ||||
|          * @returns {string} The config option. | ||||
|          */ | ||||
|         function getConfigForNode(node) { | ||||
|             if ( | ||||
|                 node.generator && | ||||
|                 context.options.length > 1 && | ||||
|                 context.options[1].generators | ||||
|             ) { | ||||
|                 return context.options[1].generators; | ||||
|             } | ||||
|  | ||||
|             return context.options[0] || "always"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the current FunctionExpression node is a get, set, or | ||||
|          * shorthand method in an object literal or a class. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {boolean} True if the node is a get, set, or shorthand method. | ||||
|          */ | ||||
|         function isObjectOrClassMethod(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             return (parent.type === "MethodDefinition" || ( | ||||
|                 parent.type === "Property" && ( | ||||
|                     parent.method || | ||||
|                     parent.kind === "get" || | ||||
|                     parent.kind === "set" | ||||
|                 ) | ||||
|             )); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the current FunctionExpression node has a name that would be | ||||
|          * inferred from context in a conforming ES6 environment. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {boolean} True if the node would have a name assigned automatically. | ||||
|          */ | ||||
|         function hasInferredName(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             return isObjectOrClassMethod(node) || | ||||
|                 (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) || | ||||
|                 (parent.type === "Property" && parent.value === node) || | ||||
|                 (parent.type === "PropertyDefinition" && parent.value === node) || | ||||
|                 (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) || | ||||
|                 (parent.type === "AssignmentPattern" && parent.left.type === "Identifier" && parent.right === node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that an unnamed function should be named | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportUnexpectedUnnamedFunction(node) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId: "unnamed", | ||||
|                 loc: astUtils.getFunctionHeadLoc(node, sourceCode), | ||||
|                 data: { name: astUtils.getFunctionNameWithKind(node) } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports that a named function should be unnamed | ||||
|          * @param {ASTNode} node The node to report in the event of an error. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportUnexpectedNamedFunction(node) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId: "named", | ||||
|                 loc: astUtils.getFunctionHeadLoc(node, sourceCode), | ||||
|                 data: { name: astUtils.getFunctionNameWithKind(node) } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * The listener for function nodes. | ||||
|          * @param {ASTNode} node function node | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function handleFunction(node) { | ||||
|  | ||||
|             // Skip recursive functions. | ||||
|             const nameVar = sourceCode.getDeclaredVariables(node)[0]; | ||||
|  | ||||
|             if (isFunctionName(nameVar) && nameVar.references.length > 0) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const hasName = Boolean(node.id && node.id.name); | ||||
|             const config = getConfigForNode(node); | ||||
|  | ||||
|             if (config === "never") { | ||||
|                 if (hasName && node.type !== "FunctionDeclaration") { | ||||
|                     reportUnexpectedNamedFunction(node); | ||||
|                 } | ||||
|             } else if (config === "as-needed") { | ||||
|                 if (!hasName && !hasInferredName(node)) { | ||||
|                     reportUnexpectedUnnamedFunction(node); | ||||
|                 } | ||||
|             } else { | ||||
|                 if (!hasName && !isObjectOrClassMethod(node)) { | ||||
|                     reportUnexpectedUnnamedFunction(node); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "FunctionExpression:exit": handleFunction, | ||||
|             "ExportDefaultDeclaration > FunctionDeclaration": handleFunction | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										98
									
								
								node_modules/eslint/lib/rules/func-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								node_modules/eslint/lib/rules/func-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce a particular function style | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce the consistent use of either `function` declarations or expressions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/func-style" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["declaration", "expression"] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allowArrowFunctions: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expression: "Expected a function expression.", | ||||
|             declaration: "Expected a function declaration." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const style = context.options[0], | ||||
|             allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions, | ||||
|             enforceDeclarations = (style === "declaration"), | ||||
|             stack = []; | ||||
|  | ||||
|         const nodesToCheck = { | ||||
|             FunctionDeclaration(node) { | ||||
|                 stack.push(false); | ||||
|  | ||||
|                 if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { | ||||
|                     context.report({ node, messageId: "expression" }); | ||||
|                 } | ||||
|             }, | ||||
|             "FunctionDeclaration:exit"() { | ||||
|                 stack.pop(); | ||||
|             }, | ||||
|  | ||||
|             FunctionExpression(node) { | ||||
|                 stack.push(false); | ||||
|  | ||||
|                 if (enforceDeclarations && node.parent.type === "VariableDeclarator") { | ||||
|                     context.report({ node: node.parent, messageId: "declaration" }); | ||||
|                 } | ||||
|             }, | ||||
|             "FunctionExpression:exit"() { | ||||
|                 stack.pop(); | ||||
|             }, | ||||
|  | ||||
|             ThisExpression() { | ||||
|                 if (stack.length > 0) { | ||||
|                     stack[stack.length - 1] = true; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         if (!allowArrowFunctions) { | ||||
|             nodesToCheck.ArrowFunctionExpression = function() { | ||||
|                 stack.push(false); | ||||
|             }; | ||||
|  | ||||
|             nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { | ||||
|                 const hasThisExpr = stack.pop(); | ||||
|  | ||||
|                 if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { | ||||
|                     context.report({ node: node.parent, messageId: "declaration" }); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return nodesToCheck; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										125
									
								
								node_modules/eslint/lib/rules/function-call-argument-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								node_modules/eslint/lib/rules/function-call-argument-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce line breaks between arguments of a function call | ||||
|  * @author Alexey Gonchar <https://github.com/finico> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce line breaks between arguments of a function call", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/function-call-argument-newline" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "never", "consistent"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedLineBreak: "There should be no line break here.", | ||||
|             missingLineBreak: "There should be a line break after this argument." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         const checkers = { | ||||
|             unexpected: { | ||||
|                 messageId: "unexpectedLineBreak", | ||||
|                 check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line, | ||||
|                 createFix: (token, tokenBefore) => fixer => | ||||
|                     fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ") | ||||
|             }, | ||||
|             missing: { | ||||
|                 messageId: "missingLineBreak", | ||||
|                 check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line, | ||||
|                 createFix: (token, tokenBefore) => fixer => | ||||
|                     fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n") | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Check all arguments for line breaks in the CallExpression | ||||
|          * @param {CallExpression} node node to evaluate | ||||
|          * @param {{ messageId: string, check: Function }} checker selected checker | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkArguments(node, checker) { | ||||
|             for (let i = 1; i < node.arguments.length; i++) { | ||||
|                 const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]); | ||||
|                 const currentArgToken = sourceCode.getFirstToken(node.arguments[i]); | ||||
|  | ||||
|                 if (checker.check(prevArgToken, currentArgToken)) { | ||||
|                     const tokenBefore = sourceCode.getTokenBefore( | ||||
|                         currentArgToken, | ||||
|                         { includeComments: true } | ||||
|                     ); | ||||
|  | ||||
|                     const hasLineCommentBefore = tokenBefore.type === "Line"; | ||||
|  | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: { | ||||
|                             start: tokenBefore.loc.end, | ||||
|                             end: currentArgToken.loc.start | ||||
|                         }, | ||||
|                         messageId: checker.messageId, | ||||
|                         fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore) | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if open space is present in a function name | ||||
|          * @param {CallExpression} node node to evaluate | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function check(node) { | ||||
|             if (node.arguments.length < 2) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const option = context.options[0] || "always"; | ||||
|  | ||||
|             if (option === "never") { | ||||
|                 checkArguments(node, checkers.unexpected); | ||||
|             } else if (option === "always") { | ||||
|                 checkArguments(node, checkers.missing); | ||||
|             } else if (option === "consistent") { | ||||
|                 const firstArgToken = sourceCode.getLastToken(node.arguments[0]); | ||||
|                 const secondArgToken = sourceCode.getFirstToken(node.arguments[1]); | ||||
|  | ||||
|                 if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) { | ||||
|                     checkArguments(node, checkers.unexpected); | ||||
|                 } else { | ||||
|                     checkArguments(node, checkers.missing); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             CallExpression: check, | ||||
|             NewExpression: check | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										292
									
								
								node_modules/eslint/lib/rules/function-paren-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								node_modules/eslint/lib/rules/function-paren-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,292 @@ | ||||
| /** | ||||
|  * @fileoverview enforce consistent line breaks inside function parentheses | ||||
|  * @author Teddy Katz | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent line breaks inside function parentheses", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/function-paren-newline" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         enum: ["always", "never", "consistent", "multiline", "multiline-arguments"] | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             minItems: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expectedBefore: "Expected newline before ')'.", | ||||
|             expectedAfter: "Expected newline after '('.", | ||||
|             expectedBetween: "Expected newline between arguments/params.", | ||||
|             unexpectedBefore: "Unexpected newline before ')'.", | ||||
|             unexpectedAfter: "Unexpected newline after '('." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const rawOption = context.options[0] || "multiline"; | ||||
|         const multilineOption = rawOption === "multiline"; | ||||
|         const multilineArgumentsOption = rawOption === "multiline-arguments"; | ||||
|         const consistentOption = rawOption === "consistent"; | ||||
|         let minItems; | ||||
|  | ||||
|         if (typeof rawOption === "object") { | ||||
|             minItems = rawOption.minItems; | ||||
|         } else if (rawOption === "always") { | ||||
|             minItems = 0; | ||||
|         } else if (rawOption === "never") { | ||||
|             minItems = Infinity; | ||||
|         } else { | ||||
|             minItems = null; | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Determines whether there should be newlines inside function parens | ||||
|          * @param {ASTNode[]} elements The arguments or parameters in the list | ||||
|          * @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code. | ||||
|          * @returns {boolean} `true` if there should be newlines inside the function parens | ||||
|          */ | ||||
|         function shouldHaveNewlines(elements, hasLeftNewline) { | ||||
|             if (multilineArgumentsOption && elements.length === 1) { | ||||
|                 return hasLeftNewline; | ||||
|             } | ||||
|             if (multilineOption || multilineArgumentsOption) { | ||||
|                 return elements.some((element, index) => index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line); | ||||
|             } | ||||
|             if (consistentOption) { | ||||
|                 return hasLeftNewline; | ||||
|             } | ||||
|             return elements.length >= minItems; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates parens | ||||
|          * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token | ||||
|          * @param {ASTNode[]} elements The arguments or parameters in the list | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateParens(parens, elements) { | ||||
|             const leftParen = parens.leftParen; | ||||
|             const rightParen = parens.rightParen; | ||||
|             const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); | ||||
|             const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen); | ||||
|             const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); | ||||
|             const hasRightNewline = !astUtils.isTokenOnSameLine(tokenBeforeRightParen, rightParen); | ||||
|             const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); | ||||
|  | ||||
|             if (hasLeftNewline && !needsNewlines) { | ||||
|                 context.report({ | ||||
|                     node: leftParen, | ||||
|                     messageId: "unexpectedAfter", | ||||
|                     fix(fixer) { | ||||
|                         return sourceCode.getText().slice(leftParen.range[1], tokenAfterLeftParen.range[0]).trim() | ||||
|  | ||||
|                             // If there is a comment between the ( and the first element, don't do a fix. | ||||
|                             ? null | ||||
|                             : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } else if (!hasLeftNewline && needsNewlines) { | ||||
|                 context.report({ | ||||
|                     node: leftParen, | ||||
|                     messageId: "expectedAfter", | ||||
|                     fix: fixer => fixer.insertTextAfter(leftParen, "\n") | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             if (hasRightNewline && !needsNewlines) { | ||||
|                 context.report({ | ||||
|                     node: rightParen, | ||||
|                     messageId: "unexpectedBefore", | ||||
|                     fix(fixer) { | ||||
|                         return sourceCode.getText().slice(tokenBeforeRightParen.range[1], rightParen.range[0]).trim() | ||||
|  | ||||
|                             // If there is a comment between the last element and the ), don't do a fix. | ||||
|                             ? null | ||||
|                             : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } else if (!hasRightNewline && needsNewlines) { | ||||
|                 context.report({ | ||||
|                     node: rightParen, | ||||
|                     messageId: "expectedBefore", | ||||
|                     fix: fixer => fixer.insertTextBefore(rightParen, "\n") | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Validates a list of arguments or parameters | ||||
|          * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token | ||||
|          * @param {ASTNode[]} elements The arguments or parameters in the list | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateArguments(parens, elements) { | ||||
|             const leftParen = parens.leftParen; | ||||
|             const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); | ||||
|             const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); | ||||
|             const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); | ||||
|  | ||||
|             for (let i = 0; i <= elements.length - 2; i++) { | ||||
|                 const currentElement = elements[i]; | ||||
|                 const nextElement = elements[i + 1]; | ||||
|                 const hasNewLine = currentElement.loc.end.line !== nextElement.loc.start.line; | ||||
|  | ||||
|                 if (!hasNewLine && needsNewlines) { | ||||
|                     context.report({ | ||||
|                         node: currentElement, | ||||
|                         messageId: "expectedBetween", | ||||
|                         fix: fixer => fixer.insertTextBefore(nextElement, "\n") | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the left paren and right paren tokens of a node. | ||||
|          * @param {ASTNode} node The node with parens | ||||
|          * @throws {TypeError} Unexpected node type. | ||||
|          * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token. | ||||
|          * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression | ||||
|          * with a single parameter) | ||||
|          */ | ||||
|         function getParenTokens(node) { | ||||
|             switch (node.type) { | ||||
|                 case "NewExpression": | ||||
|                     if (!node.arguments.length && | ||||
|                         !( | ||||
|                             astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) && | ||||
|                             astUtils.isClosingParenToken(sourceCode.getLastToken(node)) && | ||||
|                             node.callee.range[1] < node.range[1] | ||||
|                         ) | ||||
|                     ) { | ||||
|  | ||||
|                         // If the NewExpression does not have parens (e.g. `new Foo`), return null. | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     // falls through | ||||
|  | ||||
|                 case "CallExpression": | ||||
|                     return { | ||||
|                         leftParen: sourceCode.getTokenAfter(node.callee, astUtils.isOpeningParenToken), | ||||
|                         rightParen: sourceCode.getLastToken(node) | ||||
|                     }; | ||||
|  | ||||
|                 case "FunctionDeclaration": | ||||
|                 case "FunctionExpression": { | ||||
|                     const leftParen = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); | ||||
|                     const rightParen = node.params.length | ||||
|                         ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken) | ||||
|                         : sourceCode.getTokenAfter(leftParen); | ||||
|  | ||||
|                     return { leftParen, rightParen }; | ||||
|                 } | ||||
|  | ||||
|                 case "ArrowFunctionExpression": { | ||||
|                     const firstToken = sourceCode.getFirstToken(node, { skip: (node.async ? 1 : 0) }); | ||||
|  | ||||
|                     if (!astUtils.isOpeningParenToken(firstToken)) { | ||||
|  | ||||
|                         // If the ArrowFunctionExpression has a single param without parens, return null. | ||||
|                         return null; | ||||
|                     } | ||||
|  | ||||
|                     const rightParen = node.params.length | ||||
|                         ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken) | ||||
|                         : sourceCode.getTokenAfter(firstToken); | ||||
|  | ||||
|                     return { | ||||
|                         leftParen: firstToken, | ||||
|                         rightParen | ||||
|                     }; | ||||
|                 } | ||||
|  | ||||
|                 case "ImportExpression": { | ||||
|                     const leftParen = sourceCode.getFirstToken(node, 1); | ||||
|                     const rightParen = sourceCode.getLastToken(node); | ||||
|  | ||||
|                     return { leftParen, rightParen }; | ||||
|                 } | ||||
|  | ||||
|                 default: | ||||
|                     throw new TypeError(`unexpected node with type ${node.type}`); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             [[ | ||||
|                 "ArrowFunctionExpression", | ||||
|                 "CallExpression", | ||||
|                 "FunctionDeclaration", | ||||
|                 "FunctionExpression", | ||||
|                 "ImportExpression", | ||||
|                 "NewExpression" | ||||
|             ]](node) { | ||||
|                 const parens = getParenTokens(node); | ||||
|                 let params; | ||||
|  | ||||
|                 if (node.type === "ImportExpression") { | ||||
|                     params = [node.source]; | ||||
|                 } else if (astUtils.isFunction(node)) { | ||||
|                     params = node.params; | ||||
|                 } else { | ||||
|                     params = node.arguments; | ||||
|                 } | ||||
|  | ||||
|                 if (parens) { | ||||
|                     validateParens(parens, params); | ||||
|  | ||||
|                     if (multilineArgumentsOption) { | ||||
|                         validateArguments(parens, params); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										209
									
								
								node_modules/eslint/lib/rules/generator-star-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								node_modules/eslint/lib/rules/generator-star-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to check the spacing around the * in generator functions. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const OVERRIDE_SCHEMA = { | ||||
|     oneOf: [ | ||||
|         { | ||||
|             enum: ["before", "after", "both", "neither"] | ||||
|         }, | ||||
|         { | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 before: { type: "boolean" }, | ||||
|                 after: { type: "boolean" } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing around `*` operators in generator functions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/generator-star-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         enum: ["before", "after", "both", "neither"] | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             before: { type: "boolean" }, | ||||
|                             after: { type: "boolean" }, | ||||
|                             named: OVERRIDE_SCHEMA, | ||||
|                             anonymous: OVERRIDE_SCHEMA, | ||||
|                             method: OVERRIDE_SCHEMA | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             missingBefore: "Missing space before *.", | ||||
|             missingAfter: "Missing space after *.", | ||||
|             unexpectedBefore: "Unexpected space before *.", | ||||
|             unexpectedAfter: "Unexpected space after *." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const optionDefinitions = { | ||||
|             before: { before: true, after: false }, | ||||
|             after: { before: false, after: true }, | ||||
|             both: { before: true, after: true }, | ||||
|             neither: { before: false, after: false } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Returns resolved option definitions based on an option and defaults | ||||
|          * @param {any} option The option object or string value | ||||
|          * @param {Object} defaults The defaults to use if options are not present | ||||
|          * @returns {Object} the resolved object definition | ||||
|          */ | ||||
|         function optionToDefinition(option, defaults) { | ||||
|             if (!option) { | ||||
|                 return defaults; | ||||
|             } | ||||
|  | ||||
|             return typeof option === "string" | ||||
|                 ? optionDefinitions[option] | ||||
|                 : Object.assign({}, defaults, option); | ||||
|         } | ||||
|  | ||||
|         const modes = (function(option) { | ||||
|             const defaults = optionToDefinition(option, optionDefinitions.before); | ||||
|  | ||||
|             return { | ||||
|                 named: optionToDefinition(option.named, defaults), | ||||
|                 anonymous: optionToDefinition(option.anonymous, defaults), | ||||
|                 method: optionToDefinition(option.method, defaults) | ||||
|             }; | ||||
|         }(context.options[0] || {})); | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given token is a star token or not. | ||||
|          * @param {Token} token The token to check. | ||||
|          * @returns {boolean} `true` if the token is a star token. | ||||
|          */ | ||||
|         function isStarToken(token) { | ||||
|             return token.value === "*" && token.type === "Punctuator"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the generator star token of the given function node. | ||||
|          * @param {ASTNode} node The function node to get. | ||||
|          * @returns {Token} Found star token. | ||||
|          */ | ||||
|         function getStarToken(node) { | ||||
|             return sourceCode.getFirstToken( | ||||
|                 (node.parent.method || node.parent.type === "MethodDefinition") ? node.parent : node, | ||||
|                 isStarToken | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * capitalize a given string. | ||||
|          * @param {string} str the given string. | ||||
|          * @returns {string} the capitalized string. | ||||
|          */ | ||||
|         function capitalize(str) { | ||||
|             return str[0].toUpperCase() + str.slice(1); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks the spacing between two tokens before or after the star token. | ||||
|          * @param {string} kind Either "named", "anonymous", or "method" | ||||
|          * @param {string} side Either "before" or "after". | ||||
|          * @param {Token} leftToken `function` keyword token if side is "before", or | ||||
|          *     star token if side is "after". | ||||
|          * @param {Token} rightToken Star token if side is "before", or identifier | ||||
|          *     token if side is "after". | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacing(kind, side, leftToken, rightToken) { | ||||
|             if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) { | ||||
|                 const after = leftToken.value === "*"; | ||||
|                 const spaceRequired = modes[kind][side]; | ||||
|                 const node = after ? leftToken : rightToken; | ||||
|                 const messageId = `${spaceRequired ? "missing" : "unexpected"}${capitalize(side)}`; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId, | ||||
|                     fix(fixer) { | ||||
|                         if (spaceRequired) { | ||||
|                             if (after) { | ||||
|                                 return fixer.insertTextAfter(node, " "); | ||||
|                             } | ||||
|                             return fixer.insertTextBefore(node, " "); | ||||
|                         } | ||||
|                         return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Enforces the spacing around the star if node is a generator function. | ||||
|          * @param {ASTNode} node A function expression or declaration node. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkFunction(node) { | ||||
|             if (!node.generator) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const starToken = getStarToken(node); | ||||
|             const prevToken = sourceCode.getTokenBefore(starToken); | ||||
|             const nextToken = sourceCode.getTokenAfter(starToken); | ||||
|  | ||||
|             let kind = "named"; | ||||
|  | ||||
|             if (node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method)) { | ||||
|                 kind = "method"; | ||||
|             } else if (!node.id) { | ||||
|                 kind = "anonymous"; | ||||
|             } | ||||
|  | ||||
|             // Only check before when preceded by `function`|`static` keyword | ||||
|             if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) { | ||||
|                 checkSpacing(kind, "before", prevToken, starToken); | ||||
|             } | ||||
|  | ||||
|             checkSpacing(kind, "after", starToken, nextToken); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: checkFunction, | ||||
|             FunctionExpression: checkFunction | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										204
									
								
								node_modules/eslint/lib/rules/getter-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								node_modules/eslint/lib/rules/getter-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| /** | ||||
|  * @fileoverview Enforces that a return statement is present in property getters. | ||||
|  * @author Aladdin-ADD(hh_2013@foxmail.com) | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u; | ||||
|  | ||||
| /** | ||||
|  * Checks all segments in a set and returns true if any are reachable. | ||||
|  * @param {Set<CodePathSegment>} segments The segments to check. | ||||
|  * @returns {boolean} True if any segment is reachable; false otherwise. | ||||
|  */ | ||||
| function isAnySegmentReachable(segments) { | ||||
|  | ||||
|     for (const segment of segments) { | ||||
|         if (segment.reachable) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce `return` statements in getters", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/getter-return" | ||||
|         }, | ||||
|  | ||||
|         fixable: null, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allowImplicit: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expected: "Expected to return a value in {{name}}.", | ||||
|             expectedAlways: "Expected {{name}} to always return a value." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const options = context.options[0] || { allowImplicit: false }; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let funcInfo = { | ||||
|             upper: null, | ||||
|             codePath: null, | ||||
|             hasReturn: false, | ||||
|             shouldCheck: false, | ||||
|             node: null, | ||||
|             currentSegments: [] | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether or not the last code path segment is reachable. | ||||
|          * Then reports this function if the segment is reachable. | ||||
|          * | ||||
|          * If the last code path segment is reachable, there are paths which are not | ||||
|          * returned or thrown. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkLastSegment(node) { | ||||
|             if (funcInfo.shouldCheck && | ||||
|                 isAnySegmentReachable(funcInfo.currentSegments) | ||||
|             ) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     loc: astUtils.getFunctionHeadLoc(node, sourceCode), | ||||
|                     messageId: funcInfo.hasReturn ? "expectedAlways" : "expected", | ||||
|                     data: { | ||||
|                         name: astUtils.getFunctionNameWithKind(funcInfo.node) | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether a node means a getter function. | ||||
|          * @param {ASTNode} node a node to check. | ||||
|          * @returns {boolean} if node means a getter, return true; else return false. | ||||
|          */ | ||||
|         function isGetter(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") { | ||||
|                 if (parent.kind === "get") { | ||||
|                     return true; | ||||
|                 } | ||||
|                 if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") { | ||||
|  | ||||
|                     // Object.defineProperty() or Reflect.defineProperty() | ||||
|                     if (parent.parent.parent.type === "CallExpression") { | ||||
|                         const callNode = parent.parent.parent.callee; | ||||
|  | ||||
|                         if (astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperty") || | ||||
|                             astUtils.isSpecificMemberAccess(callNode, "Reflect", "defineProperty")) { | ||||
|                             return true; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     // Object.defineProperties() or Object.create() | ||||
|                     if (parent.parent.parent.type === "Property" && | ||||
|                         parent.parent.parent.parent.type === "ObjectExpression" && | ||||
|                         parent.parent.parent.parent.parent.type === "CallExpression") { | ||||
|                         const callNode = parent.parent.parent.parent.parent.callee; | ||||
|  | ||||
|                         return astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperties") || | ||||
|                                astUtils.isSpecificMemberAccess(callNode, "Object", "create"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         return { | ||||
|  | ||||
|             // Stacks this function's information. | ||||
|             onCodePathStart(codePath, node) { | ||||
|                 funcInfo = { | ||||
|                     upper: funcInfo, | ||||
|                     codePath, | ||||
|                     hasReturn: false, | ||||
|                     shouldCheck: isGetter(node), | ||||
|                     node, | ||||
|                     currentSegments: new Set() | ||||
|                 }; | ||||
|             }, | ||||
|  | ||||
|             // Pops this function's information. | ||||
|             onCodePathEnd() { | ||||
|                 funcInfo = funcInfo.upper; | ||||
|             }, | ||||
|             onUnreachableCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onUnreachableCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentStart(segment) { | ||||
|                 funcInfo.currentSegments.add(segment); | ||||
|             }, | ||||
|  | ||||
|             onCodePathSegmentEnd(segment) { | ||||
|                 funcInfo.currentSegments.delete(segment); | ||||
|             }, | ||||
|  | ||||
|             // Checks the return statement is valid. | ||||
|             ReturnStatement(node) { | ||||
|                 if (funcInfo.shouldCheck) { | ||||
|                     funcInfo.hasReturn = true; | ||||
|  | ||||
|                     // if allowImplicit: false, should also check node.argument | ||||
|                     if (!options.allowImplicit && !node.argument) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "expected", | ||||
|                             data: { | ||||
|                                 name: astUtils.getFunctionNameWithKind(funcInfo.node) | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // Reports a given function if the last path is reachable. | ||||
|             "FunctionExpression:exit": checkLastSegment, | ||||
|             "ArrowFunctionExpression:exit": checkLastSegment | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										90
									
								
								node_modules/eslint/lib/rules/global-require.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								node_modules/eslint/lib/rules/global-require.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| /** | ||||
|  * @fileoverview Rule for disallowing require() outside of the top-level module context | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v7.0.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const ACCEPTABLE_PARENTS = new Set([ | ||||
|     "AssignmentExpression", | ||||
|     "VariableDeclarator", | ||||
|     "MemberExpression", | ||||
|     "ExpressionStatement", | ||||
|     "CallExpression", | ||||
|     "ConditionalExpression", | ||||
|     "Program", | ||||
|     "VariableDeclaration", | ||||
|     "ChainExpression" | ||||
| ]); | ||||
|  | ||||
| /** | ||||
|  * Finds the eslint-scope reference in the given scope. | ||||
|  * @param {Object} scope The scope to search. | ||||
|  * @param {ASTNode} node The identifier node. | ||||
|  * @returns {Reference|null} Returns the found reference or null if none were found. | ||||
|  */ | ||||
| function findReference(scope, node) { | ||||
|     const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && | ||||
|             reference.identifier.range[1] === node.range[1]); | ||||
|  | ||||
|     if (references.length === 1) { | ||||
|         return references[0]; | ||||
|     } | ||||
|  | ||||
|     /* c8 ignore next */ | ||||
|     return null; | ||||
|  | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if the given identifier node is shadowed in the given scope. | ||||
|  * @param {Object} scope The current scope. | ||||
|  * @param {ASTNode} node The identifier node to check. | ||||
|  * @returns {boolean} Whether or not the name is shadowed. | ||||
|  */ | ||||
| function isShadowed(scope, node) { | ||||
|     const reference = findReference(scope, node); | ||||
|  | ||||
|     return reference && reference.resolved && reference.resolved.defs.length > 0; | ||||
| } | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|  | ||||
|         replacedBy: [], | ||||
|  | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `require()` calls to be placed at top-level module scope", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/global-require" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|         messages: { | ||||
|             unexpected: "Unexpected require()." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         return { | ||||
|             CallExpression(node) { | ||||
|                 const currentScope = sourceCode.getScope(node); | ||||
|  | ||||
|                 if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { | ||||
|                     const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type)); | ||||
|  | ||||
|                     if (!isGoodRequire) { | ||||
|                         context.report({ node, messageId: "unexpected" }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										215
									
								
								node_modules/eslint/lib/rules/grouped-accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								node_modules/eslint/lib/rules/grouped-accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to require grouped accessor pairs in object literals and classes | ||||
|  * @author Milos Djermanovic | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Typedefs | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Property name if it can be computed statically, otherwise the list of the tokens of the key node. | ||||
|  * @typedef {string|Token[]} Key | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Accessor nodes with the same key. | ||||
|  * @typedef {Object} AccessorData | ||||
|  * @property {Key} key Accessor's key | ||||
|  * @property {ASTNode[]} getters List of getter nodes. | ||||
|  * @property {ASTNode[]} setters List of setter nodes. | ||||
|  */ | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not the given lists represent the equal tokens in the same order. | ||||
|  * Tokens are compared by their properties, not by instance. | ||||
|  * @param {Token[]} left First list of tokens. | ||||
|  * @param {Token[]} right Second list of tokens. | ||||
|  * @returns {boolean} `true` if the lists have same tokens. | ||||
|  */ | ||||
| function areEqualTokenLists(left, right) { | ||||
|     if (left.length !== right.length) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     for (let i = 0; i < left.length; i++) { | ||||
|         const leftToken = left[i], | ||||
|             rightToken = right[i]; | ||||
|  | ||||
|         if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not the given keys are equal. | ||||
|  * @param {Key} left First key. | ||||
|  * @param {Key} right Second key. | ||||
|  * @returns {boolean} `true` if the keys are equal. | ||||
|  */ | ||||
| function areEqualKeys(left, right) { | ||||
|     if (typeof left === "string" && typeof right === "string") { | ||||
|  | ||||
|         // Statically computed names. | ||||
|         return left === right; | ||||
|     } | ||||
|     if (Array.isArray(left) && Array.isArray(right)) { | ||||
|  | ||||
|         // Token lists. | ||||
|         return areEqualTokenLists(left, right); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is of an accessor kind ('get' or 'set'). | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if the node is of an accessor kind. | ||||
|  */ | ||||
| function isAccessorKind(node) { | ||||
|     return node.kind === "get" || node.kind === "set"; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require grouped accessor pairs in object literals and classes", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/grouped-accessor-pairs" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["anyOrder", "getBeforeSet", "setBeforeGet"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             notGrouped: "Accessor pair {{ formerName }} and {{ latterName }} should be grouped.", | ||||
|             invalidOrder: "Expected {{ latterName }} to be before {{ formerName }}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const order = context.options[0] || "anyOrder"; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Reports the given accessor pair. | ||||
|          * @param {string} messageId messageId to report. | ||||
|          * @param {ASTNode} formerNode getter/setter node that is defined before `latterNode`. | ||||
|          * @param {ASTNode} latterNode getter/setter node that is defined after `formerNode`. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(messageId, formerNode, latterNode) { | ||||
|             context.report({ | ||||
|                 node: latterNode, | ||||
|                 messageId, | ||||
|                 loc: astUtils.getFunctionHeadLoc(latterNode.value, sourceCode), | ||||
|                 data: { | ||||
|                     formerName: astUtils.getFunctionNameWithKind(formerNode.value), | ||||
|                     latterName: astUtils.getFunctionNameWithKind(latterNode.value) | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks accessor pairs in the given list of nodes. | ||||
|          * @param {ASTNode[]} nodes The list to check. | ||||
|          * @param {Function} shouldCheck – Predicate that returns `true` if the node should be checked. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkList(nodes, shouldCheck) { | ||||
|             const accessors = []; | ||||
|             let found = false; | ||||
|  | ||||
|             for (let i = 0; i < nodes.length; i++) { | ||||
|                 const node = nodes[i]; | ||||
|  | ||||
|                 if (shouldCheck(node) && isAccessorKind(node)) { | ||||
|  | ||||
|                     // Creates a new `AccessorData` object for the given getter or setter node. | ||||
|                     const name = astUtils.getStaticPropertyName(node); | ||||
|                     const key = (name !== null) ? name : sourceCode.getTokens(node.key); | ||||
|  | ||||
|                     // Merges the given `AccessorData` object into the given accessors list. | ||||
|                     for (let j = 0; j < accessors.length; j++) { | ||||
|                         const accessor = accessors[j]; | ||||
|  | ||||
|                         if (areEqualKeys(accessor.key, key)) { | ||||
|                             accessor.getters.push(...node.kind === "get" ? [node] : []); | ||||
|                             accessor.setters.push(...node.kind === "set" ? [node] : []); | ||||
|                             found = true; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     if (!found) { | ||||
|                         accessors.push({ | ||||
|                             key, | ||||
|                             getters: node.kind === "get" ? [node] : [], | ||||
|                             setters: node.kind === "set" ? [node] : [] | ||||
|                         }); | ||||
|                     } | ||||
|                     found = false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for (const { getters, setters } of accessors) { | ||||
|  | ||||
|                 // Don't report accessor properties that have duplicate getters or setters. | ||||
|                 if (getters.length === 1 && setters.length === 1) { | ||||
|                     const [getter] = getters, | ||||
|                         [setter] = setters, | ||||
|                         getterIndex = nodes.indexOf(getter), | ||||
|                         setterIndex = nodes.indexOf(setter), | ||||
|                         formerNode = getterIndex < setterIndex ? getter : setter, | ||||
|                         latterNode = getterIndex < setterIndex ? setter : getter; | ||||
|  | ||||
|                     if (Math.abs(getterIndex - setterIndex) > 1) { | ||||
|                         report("notGrouped", formerNode, latterNode); | ||||
|                     } else if ( | ||||
|                         (order === "getBeforeSet" && getterIndex > setterIndex) || | ||||
|                         (order === "setBeforeGet" && getterIndex < setterIndex) | ||||
|                     ) { | ||||
|                         report("invalidOrder", formerNode, latterNode); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ObjectExpression(node) { | ||||
|                 checkList(node.properties, n => n.type === "Property"); | ||||
|             }, | ||||
|             ClassBody(node) { | ||||
|                 checkList(node.body, n => n.type === "MethodDefinition" && !n.static); | ||||
|                 checkList(node.body, n => n.type === "MethodDefinition" && n.static); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										76
									
								
								node_modules/eslint/lib/rules/guard-for-in.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								node_modules/eslint/lib/rules/guard-for-in.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag for-in loops without if statements inside | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require `for-in` loops to include an `if` statement", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/guard-for-in" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|         messages: { | ||||
|             wrap: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             ForInStatement(node) { | ||||
|                 const body = node.body; | ||||
|  | ||||
|                 // empty statement | ||||
|                 if (body.type === "EmptyStatement") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // if statement | ||||
|                 if (body.type === "IfStatement") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // empty block | ||||
|                 if (body.type === "BlockStatement" && body.body.length === 0) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // block with just if statement | ||||
|                 if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // block that starts with if statement | ||||
|                 if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") { | ||||
|                     const i = body.body[0]; | ||||
|  | ||||
|                     // ... whose consequent is a continue | ||||
|                     if (i.consequent.type === "ContinueStatement") { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     // ... whose consequent is a block that contains only a continue | ||||
|                     if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") { | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 context.report({ node, messageId: "wrap" }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										101
									
								
								node_modules/eslint/lib/rules/handle-callback-err.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								node_modules/eslint/lib/rules/handle-callback-err.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| /** | ||||
|  * @fileoverview Ensure handling of errors when we know they exist. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v7.0.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|  | ||||
|         replacedBy: [], | ||||
|  | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require error handling in callbacks", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/handle-callback-err" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "string" | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             expected: "Expected error to be handled." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const errorArgument = context.options[0] || "err"; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given argument should be interpreted as a regexp pattern. | ||||
|          * @param {string} stringToCheck The string which should be checked. | ||||
|          * @returns {boolean} Whether or not the string should be interpreted as a pattern. | ||||
|          */ | ||||
|         function isPattern(stringToCheck) { | ||||
|             const firstChar = stringToCheck[0]; | ||||
|  | ||||
|             return firstChar === "^"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given name matches the configured error argument. | ||||
|          * @param {string} name The name which should be compared. | ||||
|          * @returns {boolean} Whether or not the given name matches the configured error variable name. | ||||
|          */ | ||||
|         function matchesConfiguredErrorName(name) { | ||||
|             if (isPattern(errorArgument)) { | ||||
|                 const regexp = new RegExp(errorArgument, "u"); | ||||
|  | ||||
|                 return regexp.test(name); | ||||
|             } | ||||
|             return name === errorArgument; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Get the parameters of a given function scope. | ||||
|          * @param {Object} scope The function scope. | ||||
|          * @returns {Array} All parameters of the given scope. | ||||
|          */ | ||||
|         function getParameters(scope) { | ||||
|             return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check to see if we're handling the error object properly. | ||||
|          * @param {ASTNode} node The AST node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkForError(node) { | ||||
|             const scope = sourceCode.getScope(node), | ||||
|                 parameters = getParameters(scope), | ||||
|                 firstParameter = parameters[0]; | ||||
|  | ||||
|             if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { | ||||
|                 if (firstParameter.references.length === 0) { | ||||
|                     context.report({ node, messageId: "expected" }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: checkForError, | ||||
|             FunctionExpression: checkForError, | ||||
|             ArrowFunctionExpression: checkForError | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										246
									
								
								node_modules/eslint/lib/rules/id-blacklist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								node_modules/eslint/lib/rules/id-blacklist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,246 @@ | ||||
| /** | ||||
|  * @fileoverview Rule that warns when identifier names that are | ||||
|  * specified in the configuration are used. | ||||
|  * @author Keith Cirkel (http://keithcirkel.co.uk) | ||||
|  * @deprecated in ESLint v7.5.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node represents assignment target in a normal assignment or destructuring. | ||||
|  * @param {ASTNode} node The node to check. | ||||
|  * @returns {boolean} `true` if the node is assignment target. | ||||
|  */ | ||||
| function isAssignmentTarget(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|  | ||||
|         // normal assignment | ||||
|         ( | ||||
|             parent.type === "AssignmentExpression" && | ||||
|             parent.left === node | ||||
|         ) || | ||||
|  | ||||
|         // destructuring | ||||
|         parent.type === "ArrayPattern" || | ||||
|         parent.type === "RestElement" || | ||||
|         ( | ||||
|             parent.type === "Property" && | ||||
|             parent.value === node && | ||||
|             parent.parent.type === "ObjectPattern" | ||||
|         ) || | ||||
|         ( | ||||
|             parent.type === "AssignmentPattern" && | ||||
|             parent.left === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. | ||||
|  * | ||||
|  * Examples: | ||||
|  * import { a as b } from 'mod'; // node `a` is renamed import | ||||
|  * export { a as b } from 'mod'; // node `a` is renamed import | ||||
|  * @param {ASTNode} node `Identifier` node to check. | ||||
|  * @returns {boolean} `true` if the node is a renamed import. | ||||
|  */ | ||||
| function isRenamedImport(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         ( | ||||
|             parent.type === "ImportSpecifier" && | ||||
|             parent.imported !== parent.local && | ||||
|             parent.imported === node | ||||
|         ) || | ||||
|         ( | ||||
|             parent.type === "ExportSpecifier" && | ||||
|             parent.parent.source && // re-export | ||||
|             parent.local !== parent.exported && | ||||
|             parent.local === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring. | ||||
|  * | ||||
|  * Examples: | ||||
|  * const { a : b } = foo; // node `a` is renamed node. | ||||
|  * @param {ASTNode} node `Identifier` node to check. | ||||
|  * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring. | ||||
|  */ | ||||
| function isRenamedInDestructuring(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         ( | ||||
|             !parent.computed && | ||||
|             parent.type === "Property" && | ||||
|             parent.parent.type === "ObjectPattern" && | ||||
|             parent.value !== node && | ||||
|             parent.key === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node represents shorthand definition of a property in an object literal. | ||||
|  * @param {ASTNode} node `Identifier` node to check. | ||||
|  * @returns {boolean} `true` if the node is a shorthand property definition. | ||||
|  */ | ||||
| function isShorthandPropertyDefinition(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         parent.type === "Property" && | ||||
|         parent.parent.type === "ObjectExpression" && | ||||
|         parent.shorthand | ||||
|     ); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: ["id-denylist"], | ||||
|  | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow specified identifiers", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/id-blacklist" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             type: "array", | ||||
|             items: { | ||||
|                 type: "string" | ||||
|             }, | ||||
|             uniqueItems: true | ||||
|         }, | ||||
|         messages: { | ||||
|             restricted: "Identifier '{{name}}' is restricted." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const denyList = new Set(context.options); | ||||
|         const reportedNodes = new Set(); | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let globalScope; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given name is restricted. | ||||
|          * @param {string} name The name to check. | ||||
|          * @returns {boolean} `true` if the name is restricted. | ||||
|          * @private | ||||
|          */ | ||||
|         function isRestricted(name) { | ||||
|             return denyList.has(name); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given node represents a reference to a global variable that is not declared in the source code. | ||||
|          * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. | ||||
|          * @param {ASTNode} node `Identifier` node to check. | ||||
|          * @returns {boolean} `true` if the node is a reference to a global variable. | ||||
|          */ | ||||
|         function isReferenceToGlobalVariable(node) { | ||||
|             const variable = globalScope.set.get(node.name); | ||||
|  | ||||
|             return variable && variable.defs.length === 0 && | ||||
|                 variable.references.some(ref => ref.identifier === node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the given node should be checked. | ||||
|          * @param {ASTNode} node `Identifier` node. | ||||
|          * @returns {boolean} `true` if the node should be checked. | ||||
|          */ | ||||
|         function shouldCheck(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             /* | ||||
|              * Member access has special rules for checking property names. | ||||
|              * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. | ||||
|              * Write access isn't allowed, because it potentially creates a new property with a restricted name. | ||||
|              */ | ||||
|             if ( | ||||
|                 parent.type === "MemberExpression" && | ||||
|                 parent.property === node && | ||||
|                 !parent.computed | ||||
|             ) { | ||||
|                 return isAssignmentTarget(parent); | ||||
|             } | ||||
|  | ||||
|             return ( | ||||
|                 parent.type !== "CallExpression" && | ||||
|                 parent.type !== "NewExpression" && | ||||
|                 !isRenamedImport(node) && | ||||
|                 !isRenamedInDestructuring(node) && | ||||
|                 !( | ||||
|                     isReferenceToGlobalVariable(node) && | ||||
|                     !isShorthandPropertyDefinition(node) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an AST node as a rule violation. | ||||
|          * @param {ASTNode} node The node to report. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node) { | ||||
|  | ||||
|             /* | ||||
|              * We used the range instead of the node because it's possible | ||||
|              * for the same identifier to be represented by two different | ||||
|              * nodes, with the most clear example being shorthand properties: | ||||
|              * { foo } | ||||
|              * In this case, "foo" is represented by one node for the name | ||||
|              * and one for the value. The only way to know they are the same | ||||
|              * is to look at the range. | ||||
|              */ | ||||
|             if (!reportedNodes.has(node.range.toString())) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "restricted", | ||||
|                     data: { | ||||
|                         name: node.name | ||||
|                     } | ||||
|                 }); | ||||
|                 reportedNodes.add(node.range.toString()); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             Program(node) { | ||||
|                 globalScope = sourceCode.getScope(node); | ||||
|             }, | ||||
|  | ||||
|             Identifier(node) { | ||||
|                 if (isRestricted(node.name) && shouldCheck(node)) { | ||||
|                     report(node); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										228
									
								
								node_modules/eslint/lib/rules/id-denylist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								node_modules/eslint/lib/rules/id-denylist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,228 @@ | ||||
| /** | ||||
|  * @fileoverview Rule that warns when identifier names that are | ||||
|  * specified in the configuration are used. | ||||
|  * @author Keith Cirkel (http://keithcirkel.co.uk) | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node represents assignment target in a normal assignment or destructuring. | ||||
|  * @param {ASTNode} node The node to check. | ||||
|  * @returns {boolean} `true` if the node is assignment target. | ||||
|  */ | ||||
| function isAssignmentTarget(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|  | ||||
|         // normal assignment | ||||
|         ( | ||||
|             parent.type === "AssignmentExpression" && | ||||
|             parent.left === node | ||||
|         ) || | ||||
|  | ||||
|         // destructuring | ||||
|         parent.type === "ArrayPattern" || | ||||
|         parent.type === "RestElement" || | ||||
|         ( | ||||
|             parent.type === "Property" && | ||||
|             parent.value === node && | ||||
|             parent.parent.type === "ObjectPattern" | ||||
|         ) || | ||||
|         ( | ||||
|             parent.type === "AssignmentPattern" && | ||||
|             parent.left === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. | ||||
|  * | ||||
|  * Examples: | ||||
|  * import { a as b } from 'mod'; // node `a` is renamed import | ||||
|  * export { a as b } from 'mod'; // node `a` is renamed import | ||||
|  * @param {ASTNode} node `Identifier` node to check. | ||||
|  * @returns {boolean} `true` if the node is a renamed import. | ||||
|  */ | ||||
| function isRenamedImport(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         ( | ||||
|             parent.type === "ImportSpecifier" && | ||||
|             parent.imported !== parent.local && | ||||
|             parent.imported === node | ||||
|         ) || | ||||
|         ( | ||||
|             parent.type === "ExportSpecifier" && | ||||
|             parent.parent.source && // re-export | ||||
|             parent.local !== parent.exported && | ||||
|             parent.local === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the given node is an ObjectPattern destructuring. | ||||
|  * | ||||
|  * Examples: | ||||
|  * const { a : b } = foo; | ||||
|  * @param {ASTNode} node `Identifier` node to check. | ||||
|  * @returns {boolean} `true` if the node is in an ObjectPattern destructuring. | ||||
|  */ | ||||
| function isPropertyNameInDestructuring(node) { | ||||
|     const parent = node.parent; | ||||
|  | ||||
|     return ( | ||||
|         ( | ||||
|             !parent.computed && | ||||
|             parent.type === "Property" && | ||||
|             parent.parent.type === "ObjectPattern" && | ||||
|             parent.key === node | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow specified identifiers", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/id-denylist" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             type: "array", | ||||
|             items: { | ||||
|                 type: "string" | ||||
|             }, | ||||
|             uniqueItems: true | ||||
|         }, | ||||
|         messages: { | ||||
|             restricted: "Identifier '{{name}}' is restricted.", | ||||
|             restrictedPrivate: "Identifier '#{{name}}' is restricted." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const denyList = new Set(context.options); | ||||
|         const reportedNodes = new Set(); | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let globalScope; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given name is restricted. | ||||
|          * @param {string} name The name to check. | ||||
|          * @returns {boolean} `true` if the name is restricted. | ||||
|          * @private | ||||
|          */ | ||||
|         function isRestricted(name) { | ||||
|             return denyList.has(name); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given node represents a reference to a global variable that is not declared in the source code. | ||||
|          * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. | ||||
|          * @param {ASTNode} node `Identifier` node to check. | ||||
|          * @returns {boolean} `true` if the node is a reference to a global variable. | ||||
|          */ | ||||
|         function isReferenceToGlobalVariable(node) { | ||||
|             const variable = globalScope.set.get(node.name); | ||||
|  | ||||
|             return variable && variable.defs.length === 0 && | ||||
|                 variable.references.some(ref => ref.identifier === node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determines whether the given node should be checked. | ||||
|          * @param {ASTNode} node `Identifier` node. | ||||
|          * @returns {boolean} `true` if the node should be checked. | ||||
|          */ | ||||
|         function shouldCheck(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             /* | ||||
|              * Member access has special rules for checking property names. | ||||
|              * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. | ||||
|              * Write access isn't allowed, because it potentially creates a new property with a restricted name. | ||||
|              */ | ||||
|             if ( | ||||
|                 parent.type === "MemberExpression" && | ||||
|                 parent.property === node && | ||||
|                 !parent.computed | ||||
|             ) { | ||||
|                 return isAssignmentTarget(parent); | ||||
|             } | ||||
|  | ||||
|             return ( | ||||
|                 parent.type !== "CallExpression" && | ||||
|                 parent.type !== "NewExpression" && | ||||
|                 !isRenamedImport(node) && | ||||
|                 !isPropertyNameInDestructuring(node) && | ||||
|                 !isReferenceToGlobalVariable(node) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an AST node as a rule violation. | ||||
|          * @param {ASTNode} node The node to report. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node) { | ||||
|  | ||||
|             /* | ||||
|              * We used the range instead of the node because it's possible | ||||
|              * for the same identifier to be represented by two different | ||||
|              * nodes, with the most clear example being shorthand properties: | ||||
|              * { foo } | ||||
|              * In this case, "foo" is represented by one node for the name | ||||
|              * and one for the value. The only way to know they are the same | ||||
|              * is to look at the range. | ||||
|              */ | ||||
|             if (!reportedNodes.has(node.range.toString())) { | ||||
|                 const isPrivate = node.type === "PrivateIdentifier"; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: isPrivate ? "restrictedPrivate" : "restricted", | ||||
|                     data: { | ||||
|                         name: node.name | ||||
|                     } | ||||
|                 }); | ||||
|                 reportedNodes.add(node.range.toString()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             Program(node) { | ||||
|                 globalScope = sourceCode.getScope(node); | ||||
|             }, | ||||
|  | ||||
|             [[ | ||||
|                 "Identifier", | ||||
|                 "PrivateIdentifier" | ||||
|             ]](node) { | ||||
|                 if (isRestricted(node.name) && shouldCheck(node)) { | ||||
|                     report(node); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										177
									
								
								node_modules/eslint/lib/rules/id-length.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								node_modules/eslint/lib/rules/id-length.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| /** | ||||
|  * @fileoverview Rule that warns when identifier names are shorter or longer | ||||
|  * than the values provided in configuration. | ||||
|  * @author Burak Yigit Kaya aka BYK | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const { getGraphemeCount } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce minimum and maximum identifier lengths", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/id-length" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     min: { | ||||
|                         type: "integer", | ||||
|                         default: 2 | ||||
|                     }, | ||||
|                     max: { | ||||
|                         type: "integer" | ||||
|                     }, | ||||
|                     exceptions: { | ||||
|                         type: "array", | ||||
|                         uniqueItems: true, | ||||
|                         items: { | ||||
|                             type: "string" | ||||
|                         } | ||||
|                     }, | ||||
|                     exceptionPatterns: { | ||||
|                         type: "array", | ||||
|                         uniqueItems: true, | ||||
|                         items: { | ||||
|                             type: "string" | ||||
|                         } | ||||
|                     }, | ||||
|                     properties: { | ||||
|                         enum: ["always", "never"] | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             tooShort: "Identifier name '{{name}}' is too short (< {{min}}).", | ||||
|             tooShortPrivate: "Identifier name '#{{name}}' is too short (< {{min}}).", | ||||
|             tooLong: "Identifier name '{{name}}' is too long (> {{max}}).", | ||||
|             tooLongPrivate: "Identifier name #'{{name}}' is too long (> {{max}})." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const minLength = typeof options.min !== "undefined" ? options.min : 2; | ||||
|         const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; | ||||
|         const properties = options.properties !== "never"; | ||||
|         const exceptions = new Set(options.exceptions); | ||||
|         const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u")); | ||||
|         const reportedNodes = new Set(); | ||||
|  | ||||
|         /** | ||||
|          * Checks if a string matches the provided exception patterns | ||||
|          * @param {string} name The string to check. | ||||
|          * @returns {boolean} if the string is a match | ||||
|          * @private | ||||
|          */ | ||||
|         function matchesExceptionPattern(name) { | ||||
|             return exceptionPatterns.some(pattern => pattern.test(name)); | ||||
|         } | ||||
|  | ||||
|         const SUPPORTED_EXPRESSIONS = { | ||||
|             MemberExpression: properties && function(parent) { | ||||
|                 return !parent.computed && ( | ||||
|  | ||||
|                     // regular property assignment | ||||
|                     (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" || | ||||
|  | ||||
|                     // or the last identifier in an ObjectPattern destructuring | ||||
|                     parent.parent.type === "Property" && parent.parent.value === parent && | ||||
|                     parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent) | ||||
|                 ); | ||||
|             }, | ||||
|             AssignmentPattern(parent, node) { | ||||
|                 return parent.left === node; | ||||
|             }, | ||||
|             VariableDeclarator(parent, node) { | ||||
|                 return parent.id === node; | ||||
|             }, | ||||
|             Property(parent, node) { | ||||
|  | ||||
|                 if (parent.parent.type === "ObjectPattern") { | ||||
|                     const isKeyAndValueSame = parent.value.name === parent.key.name; | ||||
|  | ||||
|                     return ( | ||||
|                         !isKeyAndValueSame && parent.value === node || | ||||
|                         isKeyAndValueSame && parent.key === node && properties | ||||
|                     ); | ||||
|                 } | ||||
|                 return properties && !parent.computed && parent.key.name === node.name; | ||||
|             }, | ||||
|             ImportDefaultSpecifier: true, | ||||
|             RestElement: true, | ||||
|             FunctionExpression: true, | ||||
|             ArrowFunctionExpression: true, | ||||
|             ClassDeclaration: true, | ||||
|             FunctionDeclaration: true, | ||||
|             MethodDefinition: true, | ||||
|             PropertyDefinition: true, | ||||
|             CatchClause: true, | ||||
|             ArrayPattern: true | ||||
|         }; | ||||
|  | ||||
|         return { | ||||
|             [[ | ||||
|                 "Identifier", | ||||
|                 "PrivateIdentifier" | ||||
|             ]](node) { | ||||
|                 const name = node.name; | ||||
|                 const parent = node.parent; | ||||
|  | ||||
|                 const nameLength = getGraphemeCount(name); | ||||
|  | ||||
|                 const isShort = nameLength < minLength; | ||||
|                 const isLong = nameLength > maxLength; | ||||
|  | ||||
|                 if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) { | ||||
|                     return; // Nothing to report | ||||
|                 } | ||||
|  | ||||
|                 const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; | ||||
|  | ||||
|                 /* | ||||
|                  * We used the range instead of the node because it's possible | ||||
|                  * for the same identifier to be represented by two different | ||||
|                  * nodes, with the most clear example being shorthand properties: | ||||
|                  * { foo } | ||||
|                  * In this case, "foo" is represented by one node for the name | ||||
|                  * and one for the value. The only way to know they are the same | ||||
|                  * is to look at the range. | ||||
|                  */ | ||||
|                 if (isValidExpression && !reportedNodes.has(node.range.toString()) && (isValidExpression === true || isValidExpression(parent, node))) { | ||||
|                     reportedNodes.add(node.range.toString()); | ||||
|  | ||||
|                     let messageId = isShort ? "tooShort" : "tooLong"; | ||||
|  | ||||
|                     if (node.type === "PrivateIdentifier") { | ||||
|                         messageId += "Private"; | ||||
|                     } | ||||
|  | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId, | ||||
|                         data: { name, min: minLength, max: maxLength } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										299
									
								
								node_modules/eslint/lib/rules/id-match.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								node_modules/eslint/lib/rules/id-match.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag non-matching identifiers | ||||
|  * @author Matthieu Larcher | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require identifiers to match a specified regular expression", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/id-match" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "string" | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     properties: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     classFields: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     onlyDeclarations: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     ignoreDestructuring: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             notMatch: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", | ||||
|             notMatchPrivate: "Identifier '#{{name}}' does not match the pattern '{{pattern}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Options | ||||
|         //-------------------------------------------------------------------------- | ||||
|         const pattern = context.options[0] || "^.+$", | ||||
|             regexp = new RegExp(pattern, "u"); | ||||
|  | ||||
|         const options = context.options[1] || {}, | ||||
|             checkProperties = !!options.properties, | ||||
|             checkClassFields = !!options.classFields, | ||||
|             onlyDeclarations = !!options.onlyDeclarations, | ||||
|             ignoreDestructuring = !!options.ignoreDestructuring; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|         let globalScope; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         // contains reported nodes to avoid reporting twice on destructuring with shorthand notation | ||||
|         const reportedNodes = new Set(); | ||||
|         const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); | ||||
|         const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]); | ||||
|         const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]); | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given node represents a reference to a global variable that is not declared in the source code. | ||||
|          * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. | ||||
|          * @param {ASTNode} node `Identifier` node to check. | ||||
|          * @returns {boolean} `true` if the node is a reference to a global variable. | ||||
|          */ | ||||
|         function isReferenceToGlobalVariable(node) { | ||||
|             const variable = globalScope.set.get(node.name); | ||||
|  | ||||
|             return variable && variable.defs.length === 0 && | ||||
|                 variable.references.some(ref => ref.identifier === node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a string matches the provided pattern | ||||
|          * @param {string} name The string to check. | ||||
|          * @returns {boolean} if the string is a match | ||||
|          * @private | ||||
|          */ | ||||
|         function isInvalid(name) { | ||||
|             return !regexp.test(name); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a parent of a node is an ObjectPattern. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} if the node is inside an ObjectPattern | ||||
|          * @private | ||||
|          */ | ||||
|         function isInsideObjectPattern(node) { | ||||
|             let { parent } = node; | ||||
|  | ||||
|             while (parent) { | ||||
|                 if (parent.type === "ObjectPattern") { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 parent = parent.parent; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Verifies if we should report an error or not based on the effective | ||||
|          * parent node and the identifier name. | ||||
|          * @param {ASTNode} effectiveParent The effective parent node of the node to be reported | ||||
|          * @param {string} name The identifier name of the identifier node | ||||
|          * @returns {boolean} whether an error should be reported or not | ||||
|          */ | ||||
|         function shouldReport(effectiveParent, name) { | ||||
|             return (!onlyDeclarations || DECLARATION_TYPES.has(effectiveParent.type)) && | ||||
|                 !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && isInvalid(name); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an AST node as a rule violation. | ||||
|          * @param {ASTNode} node The node to report. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function report(node) { | ||||
|  | ||||
|             /* | ||||
|              * We used the range instead of the node because it's possible | ||||
|              * for the same identifier to be represented by two different | ||||
|              * nodes, with the most clear example being shorthand properties: | ||||
|              * { foo } | ||||
|              * In this case, "foo" is represented by one node for the name | ||||
|              * and one for the value. The only way to know they are the same | ||||
|              * is to look at the range. | ||||
|              */ | ||||
|             if (!reportedNodes.has(node.range.toString())) { | ||||
|  | ||||
|                 const messageId = (node.type === "PrivateIdentifier") | ||||
|                     ? "notMatchPrivate" : "notMatch"; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId, | ||||
|                     data: { | ||||
|                         name: node.name, | ||||
|                         pattern | ||||
|                     } | ||||
|                 }); | ||||
|                 reportedNodes.add(node.range.toString()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             Program(node) { | ||||
|                 globalScope = sourceCode.getScope(node); | ||||
|             }, | ||||
|  | ||||
|             Identifier(node) { | ||||
|                 const name = node.name, | ||||
|                     parent = node.parent, | ||||
|                     effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; | ||||
|  | ||||
|                 if (isReferenceToGlobalVariable(node)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (parent.type === "MemberExpression") { | ||||
|  | ||||
|                     if (!checkProperties) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     // Always check object names | ||||
|                     if (parent.object.type === "Identifier" && | ||||
|                         parent.object.name === name) { | ||||
|                         if (isInvalid(name)) { | ||||
|                             report(node); | ||||
|                         } | ||||
|  | ||||
|                     // Report AssignmentExpressions left side's assigned variable id | ||||
|                     } else if (effectiveParent.type === "AssignmentExpression" && | ||||
|                         effectiveParent.left.type === "MemberExpression" && | ||||
|                         effectiveParent.left.property.name === node.name) { | ||||
|                         if (isInvalid(name)) { | ||||
|                             report(node); | ||||
|                         } | ||||
|  | ||||
|                     // Report AssignmentExpressions only if they are the left side of the assignment | ||||
|                     } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.right.type !== "MemberExpression") { | ||||
|                         if (isInvalid(name)) { | ||||
|                             report(node); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                 // For https://github.com/eslint/eslint/issues/15123 | ||||
|                 } else if ( | ||||
|                     parent.type === "Property" && | ||||
|                     parent.parent.type === "ObjectExpression" && | ||||
|                     parent.key === node && | ||||
|                     !parent.computed | ||||
|                 ) { | ||||
|                     if (checkProperties && isInvalid(name)) { | ||||
|                         report(node); | ||||
|                     } | ||||
|  | ||||
|                 /* | ||||
|                  * Properties have their own rules, and | ||||
|                  * AssignmentPattern nodes can be treated like Properties: | ||||
|                  * e.g.: const { no_camelcased = false } = bar; | ||||
|                  */ | ||||
|                 } else if (parent.type === "Property" || parent.type === "AssignmentPattern") { | ||||
|  | ||||
|                     if (parent.parent && parent.parent.type === "ObjectPattern") { | ||||
|                         if (!ignoreDestructuring && parent.shorthand && parent.value.left && isInvalid(name)) { | ||||
|                             report(node); | ||||
|                         } | ||||
|  | ||||
|                         const assignmentKeyEqualsValue = parent.key.name === parent.value.name; | ||||
|  | ||||
|                         // prevent checking righthand side of destructured object | ||||
|                         if (!assignmentKeyEqualsValue && parent.key === node) { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         const valueIsInvalid = parent.value.name && isInvalid(name); | ||||
|  | ||||
|                         // ignore destructuring if the option is set, unless a new identifier is created | ||||
|                         if (valueIsInvalid && !(assignmentKeyEqualsValue && ignoreDestructuring)) { | ||||
|                             report(node); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     // never check properties or always ignore destructuring | ||||
|                     if ((!checkProperties && !parent.computed) || (ignoreDestructuring && isInsideObjectPattern(node))) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     // don't check right hand side of AssignmentExpression to prevent duplicate warnings | ||||
|                     if (parent.right !== node && shouldReport(effectiveParent, name)) { | ||||
|                         report(node); | ||||
|                     } | ||||
|  | ||||
|                 // Check if it's an import specifier | ||||
|                 } else if (IMPORT_TYPES.has(parent.type)) { | ||||
|  | ||||
|                     // Report only if the local imported identifier is invalid | ||||
|                     if (parent.local && parent.local.name === node.name && isInvalid(name)) { | ||||
|                         report(node); | ||||
|                     } | ||||
|  | ||||
|                 } else if (parent.type === "PropertyDefinition") { | ||||
|  | ||||
|                     if (checkClassFields && isInvalid(name)) { | ||||
|                         report(node); | ||||
|                     } | ||||
|  | ||||
|                 // Report anything that is invalid that isn't a CallExpression | ||||
|                 } else if (shouldReport(effectiveParent, name)) { | ||||
|                     report(node); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             "PrivateIdentifier"(node) { | ||||
|  | ||||
|                 const isClassField = node.parent.type === "PropertyDefinition"; | ||||
|  | ||||
|                 if (isClassField && !checkClassFields) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (isInvalid(node.name)) { | ||||
|                     report(node); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										84
									
								
								node_modules/eslint/lib/rules/implicit-arrow-linebreak.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								node_modules/eslint/lib/rules/implicit-arrow-linebreak.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /** | ||||
|  * @fileoverview enforce the location of arrow function bodies | ||||
|  * @author Sharmila Jesupaul | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const { isCommentToken, isNotOpeningParenToken } = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce the location of arrow function bodies", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/implicit-arrow-linebreak" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["beside", "below"] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             expected: "Expected a linebreak before this expression.", | ||||
|             unexpected: "Expected no linebreak before this expression." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const option = context.options[0] || "beside"; | ||||
|  | ||||
|         /** | ||||
|          * Validates the location of an arrow function body | ||||
|          * @param {ASTNode} node The arrow function body | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validateExpression(node) { | ||||
|             if (node.body.type === "BlockStatement") { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken); | ||||
|             const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken); | ||||
|  | ||||
|             if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") { | ||||
|                 context.report({ | ||||
|                     node: firstTokenOfBody, | ||||
|                     messageId: "expected", | ||||
|                     fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n") | ||||
|                 }); | ||||
|             } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") { | ||||
|                 context.report({ | ||||
|                     node: firstTokenOfBody, | ||||
|                     messageId: "unexpected", | ||||
|                     fix(fixer) { | ||||
|                         if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) { | ||||
|                             return null; | ||||
|                         } | ||||
|  | ||||
|                         return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " "); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|         return { | ||||
|             ArrowFunctionExpression: node => validateExpression(node) | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										1126
									
								
								node_modules/eslint/lib/rules/indent-legacy.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1126
									
								
								node_modules/eslint/lib/rules/indent-legacy.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1803
									
								
								node_modules/eslint/lib/rules/indent.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1803
									
								
								node_modules/eslint/lib/rules/indent.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										306
									
								
								node_modules/eslint/lib/rules/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								node_modules/eslint/lib/rules/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,306 @@ | ||||
| /** | ||||
|  * @fileoverview Collects the built-in rules into a map structure so that they can be imported all at once and without | ||||
|  * using the file-system directly. | ||||
|  * @author Peter (Somogyvari) Metz | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| /* eslint sort-keys: ["error", "asc"] -- More readable for long list */ | ||||
|  | ||||
| const { LazyLoadingRuleMap } = require("./utils/lazy-loading-rule-map"); | ||||
|  | ||||
| /** @type {Map<string, import("../shared/types").Rule>} */ | ||||
| module.exports = new LazyLoadingRuleMap(Object.entries({ | ||||
|     "accessor-pairs": () => require("./accessor-pairs"), | ||||
|     "array-bracket-newline": () => require("./array-bracket-newline"), | ||||
|     "array-bracket-spacing": () => require("./array-bracket-spacing"), | ||||
|     "array-callback-return": () => require("./array-callback-return"), | ||||
|     "array-element-newline": () => require("./array-element-newline"), | ||||
|     "arrow-body-style": () => require("./arrow-body-style"), | ||||
|     "arrow-parens": () => require("./arrow-parens"), | ||||
|     "arrow-spacing": () => require("./arrow-spacing"), | ||||
|     "block-scoped-var": () => require("./block-scoped-var"), | ||||
|     "block-spacing": () => require("./block-spacing"), | ||||
|     "brace-style": () => require("./brace-style"), | ||||
|     "callback-return": () => require("./callback-return"), | ||||
|     camelcase: () => require("./camelcase"), | ||||
|     "capitalized-comments": () => require("./capitalized-comments"), | ||||
|     "class-methods-use-this": () => require("./class-methods-use-this"), | ||||
|     "comma-dangle": () => require("./comma-dangle"), | ||||
|     "comma-spacing": () => require("./comma-spacing"), | ||||
|     "comma-style": () => require("./comma-style"), | ||||
|     complexity: () => require("./complexity"), | ||||
|     "computed-property-spacing": () => require("./computed-property-spacing"), | ||||
|     "consistent-return": () => require("./consistent-return"), | ||||
|     "consistent-this": () => require("./consistent-this"), | ||||
|     "constructor-super": () => require("./constructor-super"), | ||||
|     curly: () => require("./curly"), | ||||
|     "default-case": () => require("./default-case"), | ||||
|     "default-case-last": () => require("./default-case-last"), | ||||
|     "default-param-last": () => require("./default-param-last"), | ||||
|     "dot-location": () => require("./dot-location"), | ||||
|     "dot-notation": () => require("./dot-notation"), | ||||
|     "eol-last": () => require("./eol-last"), | ||||
|     eqeqeq: () => require("./eqeqeq"), | ||||
|     "for-direction": () => require("./for-direction"), | ||||
|     "func-call-spacing": () => require("./func-call-spacing"), | ||||
|     "func-name-matching": () => require("./func-name-matching"), | ||||
|     "func-names": () => require("./func-names"), | ||||
|     "func-style": () => require("./func-style"), | ||||
|     "function-call-argument-newline": () => require("./function-call-argument-newline"), | ||||
|     "function-paren-newline": () => require("./function-paren-newline"), | ||||
|     "generator-star-spacing": () => require("./generator-star-spacing"), | ||||
|     "getter-return": () => require("./getter-return"), | ||||
|     "global-require": () => require("./global-require"), | ||||
|     "grouped-accessor-pairs": () => require("./grouped-accessor-pairs"), | ||||
|     "guard-for-in": () => require("./guard-for-in"), | ||||
|     "handle-callback-err": () => require("./handle-callback-err"), | ||||
|     "id-blacklist": () => require("./id-blacklist"), | ||||
|     "id-denylist": () => require("./id-denylist"), | ||||
|     "id-length": () => require("./id-length"), | ||||
|     "id-match": () => require("./id-match"), | ||||
|     "implicit-arrow-linebreak": () => require("./implicit-arrow-linebreak"), | ||||
|     indent: () => require("./indent"), | ||||
|     "indent-legacy": () => require("./indent-legacy"), | ||||
|     "init-declarations": () => require("./init-declarations"), | ||||
|     "jsx-quotes": () => require("./jsx-quotes"), | ||||
|     "key-spacing": () => require("./key-spacing"), | ||||
|     "keyword-spacing": () => require("./keyword-spacing"), | ||||
|     "line-comment-position": () => require("./line-comment-position"), | ||||
|     "linebreak-style": () => require("./linebreak-style"), | ||||
|     "lines-around-comment": () => require("./lines-around-comment"), | ||||
|     "lines-around-directive": () => require("./lines-around-directive"), | ||||
|     "lines-between-class-members": () => require("./lines-between-class-members"), | ||||
|     "logical-assignment-operators": () => require("./logical-assignment-operators"), | ||||
|     "max-classes-per-file": () => require("./max-classes-per-file"), | ||||
|     "max-depth": () => require("./max-depth"), | ||||
|     "max-len": () => require("./max-len"), | ||||
|     "max-lines": () => require("./max-lines"), | ||||
|     "max-lines-per-function": () => require("./max-lines-per-function"), | ||||
|     "max-nested-callbacks": () => require("./max-nested-callbacks"), | ||||
|     "max-params": () => require("./max-params"), | ||||
|     "max-statements": () => require("./max-statements"), | ||||
|     "max-statements-per-line": () => require("./max-statements-per-line"), | ||||
|     "multiline-comment-style": () => require("./multiline-comment-style"), | ||||
|     "multiline-ternary": () => require("./multiline-ternary"), | ||||
|     "new-cap": () => require("./new-cap"), | ||||
|     "new-parens": () => require("./new-parens"), | ||||
|     "newline-after-var": () => require("./newline-after-var"), | ||||
|     "newline-before-return": () => require("./newline-before-return"), | ||||
|     "newline-per-chained-call": () => require("./newline-per-chained-call"), | ||||
|     "no-alert": () => require("./no-alert"), | ||||
|     "no-array-constructor": () => require("./no-array-constructor"), | ||||
|     "no-async-promise-executor": () => require("./no-async-promise-executor"), | ||||
|     "no-await-in-loop": () => require("./no-await-in-loop"), | ||||
|     "no-bitwise": () => require("./no-bitwise"), | ||||
|     "no-buffer-constructor": () => require("./no-buffer-constructor"), | ||||
|     "no-caller": () => require("./no-caller"), | ||||
|     "no-case-declarations": () => require("./no-case-declarations"), | ||||
|     "no-catch-shadow": () => require("./no-catch-shadow"), | ||||
|     "no-class-assign": () => require("./no-class-assign"), | ||||
|     "no-compare-neg-zero": () => require("./no-compare-neg-zero"), | ||||
|     "no-cond-assign": () => require("./no-cond-assign"), | ||||
|     "no-confusing-arrow": () => require("./no-confusing-arrow"), | ||||
|     "no-console": () => require("./no-console"), | ||||
|     "no-const-assign": () => require("./no-const-assign"), | ||||
|     "no-constant-binary-expression": () => require("./no-constant-binary-expression"), | ||||
|     "no-constant-condition": () => require("./no-constant-condition"), | ||||
|     "no-constructor-return": () => require("./no-constructor-return"), | ||||
|     "no-continue": () => require("./no-continue"), | ||||
|     "no-control-regex": () => require("./no-control-regex"), | ||||
|     "no-debugger": () => require("./no-debugger"), | ||||
|     "no-delete-var": () => require("./no-delete-var"), | ||||
|     "no-div-regex": () => require("./no-div-regex"), | ||||
|     "no-dupe-args": () => require("./no-dupe-args"), | ||||
|     "no-dupe-class-members": () => require("./no-dupe-class-members"), | ||||
|     "no-dupe-else-if": () => require("./no-dupe-else-if"), | ||||
|     "no-dupe-keys": () => require("./no-dupe-keys"), | ||||
|     "no-duplicate-case": () => require("./no-duplicate-case"), | ||||
|     "no-duplicate-imports": () => require("./no-duplicate-imports"), | ||||
|     "no-else-return": () => require("./no-else-return"), | ||||
|     "no-empty": () => require("./no-empty"), | ||||
|     "no-empty-character-class": () => require("./no-empty-character-class"), | ||||
|     "no-empty-function": () => require("./no-empty-function"), | ||||
|     "no-empty-pattern": () => require("./no-empty-pattern"), | ||||
|     "no-empty-static-block": () => require("./no-empty-static-block"), | ||||
|     "no-eq-null": () => require("./no-eq-null"), | ||||
|     "no-eval": () => require("./no-eval"), | ||||
|     "no-ex-assign": () => require("./no-ex-assign"), | ||||
|     "no-extend-native": () => require("./no-extend-native"), | ||||
|     "no-extra-bind": () => require("./no-extra-bind"), | ||||
|     "no-extra-boolean-cast": () => require("./no-extra-boolean-cast"), | ||||
|     "no-extra-label": () => require("./no-extra-label"), | ||||
|     "no-extra-parens": () => require("./no-extra-parens"), | ||||
|     "no-extra-semi": () => require("./no-extra-semi"), | ||||
|     "no-fallthrough": () => require("./no-fallthrough"), | ||||
|     "no-floating-decimal": () => require("./no-floating-decimal"), | ||||
|     "no-func-assign": () => require("./no-func-assign"), | ||||
|     "no-global-assign": () => require("./no-global-assign"), | ||||
|     "no-implicit-coercion": () => require("./no-implicit-coercion"), | ||||
|     "no-implicit-globals": () => require("./no-implicit-globals"), | ||||
|     "no-implied-eval": () => require("./no-implied-eval"), | ||||
|     "no-import-assign": () => require("./no-import-assign"), | ||||
|     "no-inline-comments": () => require("./no-inline-comments"), | ||||
|     "no-inner-declarations": () => require("./no-inner-declarations"), | ||||
|     "no-invalid-regexp": () => require("./no-invalid-regexp"), | ||||
|     "no-invalid-this": () => require("./no-invalid-this"), | ||||
|     "no-irregular-whitespace": () => require("./no-irregular-whitespace"), | ||||
|     "no-iterator": () => require("./no-iterator"), | ||||
|     "no-label-var": () => require("./no-label-var"), | ||||
|     "no-labels": () => require("./no-labels"), | ||||
|     "no-lone-blocks": () => require("./no-lone-blocks"), | ||||
|     "no-lonely-if": () => require("./no-lonely-if"), | ||||
|     "no-loop-func": () => require("./no-loop-func"), | ||||
|     "no-loss-of-precision": () => require("./no-loss-of-precision"), | ||||
|     "no-magic-numbers": () => require("./no-magic-numbers"), | ||||
|     "no-misleading-character-class": () => require("./no-misleading-character-class"), | ||||
|     "no-mixed-operators": () => require("./no-mixed-operators"), | ||||
|     "no-mixed-requires": () => require("./no-mixed-requires"), | ||||
|     "no-mixed-spaces-and-tabs": () => require("./no-mixed-spaces-and-tabs"), | ||||
|     "no-multi-assign": () => require("./no-multi-assign"), | ||||
|     "no-multi-spaces": () => require("./no-multi-spaces"), | ||||
|     "no-multi-str": () => require("./no-multi-str"), | ||||
|     "no-multiple-empty-lines": () => require("./no-multiple-empty-lines"), | ||||
|     "no-native-reassign": () => require("./no-native-reassign"), | ||||
|     "no-negated-condition": () => require("./no-negated-condition"), | ||||
|     "no-negated-in-lhs": () => require("./no-negated-in-lhs"), | ||||
|     "no-nested-ternary": () => require("./no-nested-ternary"), | ||||
|     "no-new": () => require("./no-new"), | ||||
|     "no-new-func": () => require("./no-new-func"), | ||||
|     "no-new-native-nonconstructor": () => require("./no-new-native-nonconstructor"), | ||||
|     "no-new-object": () => require("./no-new-object"), | ||||
|     "no-new-require": () => require("./no-new-require"), | ||||
|     "no-new-symbol": () => require("./no-new-symbol"), | ||||
|     "no-new-wrappers": () => require("./no-new-wrappers"), | ||||
|     "no-nonoctal-decimal-escape": () => require("./no-nonoctal-decimal-escape"), | ||||
|     "no-obj-calls": () => require("./no-obj-calls"), | ||||
|     "no-object-constructor": () => require("./no-object-constructor"), | ||||
|     "no-octal": () => require("./no-octal"), | ||||
|     "no-octal-escape": () => require("./no-octal-escape"), | ||||
|     "no-param-reassign": () => require("./no-param-reassign"), | ||||
|     "no-path-concat": () => require("./no-path-concat"), | ||||
|     "no-plusplus": () => require("./no-plusplus"), | ||||
|     "no-process-env": () => require("./no-process-env"), | ||||
|     "no-process-exit": () => require("./no-process-exit"), | ||||
|     "no-promise-executor-return": () => require("./no-promise-executor-return"), | ||||
|     "no-proto": () => require("./no-proto"), | ||||
|     "no-prototype-builtins": () => require("./no-prototype-builtins"), | ||||
|     "no-redeclare": () => require("./no-redeclare"), | ||||
|     "no-regex-spaces": () => require("./no-regex-spaces"), | ||||
|     "no-restricted-exports": () => require("./no-restricted-exports"), | ||||
|     "no-restricted-globals": () => require("./no-restricted-globals"), | ||||
|     "no-restricted-imports": () => require("./no-restricted-imports"), | ||||
|     "no-restricted-modules": () => require("./no-restricted-modules"), | ||||
|     "no-restricted-properties": () => require("./no-restricted-properties"), | ||||
|     "no-restricted-syntax": () => require("./no-restricted-syntax"), | ||||
|     "no-return-assign": () => require("./no-return-assign"), | ||||
|     "no-return-await": () => require("./no-return-await"), | ||||
|     "no-script-url": () => require("./no-script-url"), | ||||
|     "no-self-assign": () => require("./no-self-assign"), | ||||
|     "no-self-compare": () => require("./no-self-compare"), | ||||
|     "no-sequences": () => require("./no-sequences"), | ||||
|     "no-setter-return": () => require("./no-setter-return"), | ||||
|     "no-shadow": () => require("./no-shadow"), | ||||
|     "no-shadow-restricted-names": () => require("./no-shadow-restricted-names"), | ||||
|     "no-spaced-func": () => require("./no-spaced-func"), | ||||
|     "no-sparse-arrays": () => require("./no-sparse-arrays"), | ||||
|     "no-sync": () => require("./no-sync"), | ||||
|     "no-tabs": () => require("./no-tabs"), | ||||
|     "no-template-curly-in-string": () => require("./no-template-curly-in-string"), | ||||
|     "no-ternary": () => require("./no-ternary"), | ||||
|     "no-this-before-super": () => require("./no-this-before-super"), | ||||
|     "no-throw-literal": () => require("./no-throw-literal"), | ||||
|     "no-trailing-spaces": () => require("./no-trailing-spaces"), | ||||
|     "no-undef": () => require("./no-undef"), | ||||
|     "no-undef-init": () => require("./no-undef-init"), | ||||
|     "no-undefined": () => require("./no-undefined"), | ||||
|     "no-underscore-dangle": () => require("./no-underscore-dangle"), | ||||
|     "no-unexpected-multiline": () => require("./no-unexpected-multiline"), | ||||
|     "no-unmodified-loop-condition": () => require("./no-unmodified-loop-condition"), | ||||
|     "no-unneeded-ternary": () => require("./no-unneeded-ternary"), | ||||
|     "no-unreachable": () => require("./no-unreachable"), | ||||
|     "no-unreachable-loop": () => require("./no-unreachable-loop"), | ||||
|     "no-unsafe-finally": () => require("./no-unsafe-finally"), | ||||
|     "no-unsafe-negation": () => require("./no-unsafe-negation"), | ||||
|     "no-unsafe-optional-chaining": () => require("./no-unsafe-optional-chaining"), | ||||
|     "no-unused-expressions": () => require("./no-unused-expressions"), | ||||
|     "no-unused-labels": () => require("./no-unused-labels"), | ||||
|     "no-unused-private-class-members": () => require("./no-unused-private-class-members"), | ||||
|     "no-unused-vars": () => require("./no-unused-vars"), | ||||
|     "no-use-before-define": () => require("./no-use-before-define"), | ||||
|     "no-useless-backreference": () => require("./no-useless-backreference"), | ||||
|     "no-useless-call": () => require("./no-useless-call"), | ||||
|     "no-useless-catch": () => require("./no-useless-catch"), | ||||
|     "no-useless-computed-key": () => require("./no-useless-computed-key"), | ||||
|     "no-useless-concat": () => require("./no-useless-concat"), | ||||
|     "no-useless-constructor": () => require("./no-useless-constructor"), | ||||
|     "no-useless-escape": () => require("./no-useless-escape"), | ||||
|     "no-useless-rename": () => require("./no-useless-rename"), | ||||
|     "no-useless-return": () => require("./no-useless-return"), | ||||
|     "no-var": () => require("./no-var"), | ||||
|     "no-void": () => require("./no-void"), | ||||
|     "no-warning-comments": () => require("./no-warning-comments"), | ||||
|     "no-whitespace-before-property": () => require("./no-whitespace-before-property"), | ||||
|     "no-with": () => require("./no-with"), | ||||
|     "nonblock-statement-body-position": () => require("./nonblock-statement-body-position"), | ||||
|     "object-curly-newline": () => require("./object-curly-newline"), | ||||
|     "object-curly-spacing": () => require("./object-curly-spacing"), | ||||
|     "object-property-newline": () => require("./object-property-newline"), | ||||
|     "object-shorthand": () => require("./object-shorthand"), | ||||
|     "one-var": () => require("./one-var"), | ||||
|     "one-var-declaration-per-line": () => require("./one-var-declaration-per-line"), | ||||
|     "operator-assignment": () => require("./operator-assignment"), | ||||
|     "operator-linebreak": () => require("./operator-linebreak"), | ||||
|     "padded-blocks": () => require("./padded-blocks"), | ||||
|     "padding-line-between-statements": () => require("./padding-line-between-statements"), | ||||
|     "prefer-arrow-callback": () => require("./prefer-arrow-callback"), | ||||
|     "prefer-const": () => require("./prefer-const"), | ||||
|     "prefer-destructuring": () => require("./prefer-destructuring"), | ||||
|     "prefer-exponentiation-operator": () => require("./prefer-exponentiation-operator"), | ||||
|     "prefer-named-capture-group": () => require("./prefer-named-capture-group"), | ||||
|     "prefer-numeric-literals": () => require("./prefer-numeric-literals"), | ||||
|     "prefer-object-has-own": () => require("./prefer-object-has-own"), | ||||
|     "prefer-object-spread": () => require("./prefer-object-spread"), | ||||
|     "prefer-promise-reject-errors": () => require("./prefer-promise-reject-errors"), | ||||
|     "prefer-reflect": () => require("./prefer-reflect"), | ||||
|     "prefer-regex-literals": () => require("./prefer-regex-literals"), | ||||
|     "prefer-rest-params": () => require("./prefer-rest-params"), | ||||
|     "prefer-spread": () => require("./prefer-spread"), | ||||
|     "prefer-template": () => require("./prefer-template"), | ||||
|     "quote-props": () => require("./quote-props"), | ||||
|     quotes: () => require("./quotes"), | ||||
|     radix: () => require("./radix"), | ||||
|     "require-atomic-updates": () => require("./require-atomic-updates"), | ||||
|     "require-await": () => require("./require-await"), | ||||
|     "require-jsdoc": () => require("./require-jsdoc"), | ||||
|     "require-unicode-regexp": () => require("./require-unicode-regexp"), | ||||
|     "require-yield": () => require("./require-yield"), | ||||
|     "rest-spread-spacing": () => require("./rest-spread-spacing"), | ||||
|     semi: () => require("./semi"), | ||||
|     "semi-spacing": () => require("./semi-spacing"), | ||||
|     "semi-style": () => require("./semi-style"), | ||||
|     "sort-imports": () => require("./sort-imports"), | ||||
|     "sort-keys": () => require("./sort-keys"), | ||||
|     "sort-vars": () => require("./sort-vars"), | ||||
|     "space-before-blocks": () => require("./space-before-blocks"), | ||||
|     "space-before-function-paren": () => require("./space-before-function-paren"), | ||||
|     "space-in-parens": () => require("./space-in-parens"), | ||||
|     "space-infix-ops": () => require("./space-infix-ops"), | ||||
|     "space-unary-ops": () => require("./space-unary-ops"), | ||||
|     "spaced-comment": () => require("./spaced-comment"), | ||||
|     strict: () => require("./strict"), | ||||
|     "switch-colon-spacing": () => require("./switch-colon-spacing"), | ||||
|     "symbol-description": () => require("./symbol-description"), | ||||
|     "template-curly-spacing": () => require("./template-curly-spacing"), | ||||
|     "template-tag-spacing": () => require("./template-tag-spacing"), | ||||
|     "unicode-bom": () => require("./unicode-bom"), | ||||
|     "use-isnan": () => require("./use-isnan"), | ||||
|     "valid-jsdoc": () => require("./valid-jsdoc"), | ||||
|     "valid-typeof": () => require("./valid-typeof"), | ||||
|     "vars-on-top": () => require("./vars-on-top"), | ||||
|     "wrap-iife": () => require("./wrap-iife"), | ||||
|     "wrap-regex": () => require("./wrap-regex"), | ||||
|     "yield-star-spacing": () => require("./yield-star-spacing"), | ||||
|     yoda: () => require("./yoda") | ||||
| })); | ||||
							
								
								
									
										139
									
								
								node_modules/eslint/lib/rules/init-declarations.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								node_modules/eslint/lib/rules/init-declarations.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to control the style of variable initializations. | ||||
|  * @author Colin Ihrig | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given node is a for loop. | ||||
|  * @param {ASTNode} block A node to check. | ||||
|  * @returns {boolean} `true` when the node is a for loop. | ||||
|  */ | ||||
| function isForLoop(block) { | ||||
|     return block.type === "ForInStatement" || | ||||
|     block.type === "ForOfStatement" || | ||||
|     block.type === "ForStatement"; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given declarator node has its initializer. | ||||
|  * @param {ASTNode} node A declarator node to check. | ||||
|  * @returns {boolean} `true` when the node has its initializer. | ||||
|  */ | ||||
| function isInitialized(node) { | ||||
|     const declaration = node.parent; | ||||
|     const block = declaration.parent; | ||||
|  | ||||
|     if (isForLoop(block)) { | ||||
|         if (block.type === "ForStatement") { | ||||
|             return block.init === declaration; | ||||
|         } | ||||
|         return block.left === declaration; | ||||
|     } | ||||
|     return Boolean(node.init); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow initialization in variable declarations", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/init-declarations" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["always"] | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 1 | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["never"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 ignoreForLoopInit: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ], | ||||
|                     minItems: 0, | ||||
|                     maxItems: 2 | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|         messages: { | ||||
|             initialized: "Variable '{{idName}}' should be initialized on declaration.", | ||||
|             notInitialized: "Variable '{{idName}}' should not be initialized on declaration." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const MODE_ALWAYS = "always", | ||||
|             MODE_NEVER = "never"; | ||||
|  | ||||
|         const mode = context.options[0] || MODE_ALWAYS; | ||||
|         const params = context.options[1] || {}; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             "VariableDeclaration:exit"(node) { | ||||
|  | ||||
|                 const kind = node.kind, | ||||
|                     declarations = node.declarations; | ||||
|  | ||||
|                 for (let i = 0; i < declarations.length; ++i) { | ||||
|                     const declaration = declarations[i], | ||||
|                         id = declaration.id, | ||||
|                         initialized = isInitialized(declaration), | ||||
|                         isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); | ||||
|                     let messageId = ""; | ||||
|  | ||||
|                     if (mode === MODE_ALWAYS && !initialized) { | ||||
|                         messageId = "initialized"; | ||||
|                     } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { | ||||
|                         messageId = "notInitialized"; | ||||
|                     } | ||||
|  | ||||
|                     if (id.type === "Identifier" && messageId) { | ||||
|                         context.report({ | ||||
|                             node: declaration, | ||||
|                             messageId, | ||||
|                             data: { | ||||
|                                 idName: id.name | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										98
									
								
								node_modules/eslint/lib/rules/jsx-quotes.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								node_modules/eslint/lib/rules/jsx-quotes.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to ensure consistent quotes used in jsx syntax. | ||||
|  * @author Mathias Schreck <https://github.com/lo1tuma> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Constants | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const QUOTE_SETTINGS = { | ||||
|     "prefer-double": { | ||||
|         quote: "\"", | ||||
|         description: "singlequote", | ||||
|         convert(str) { | ||||
|             return str.replace(/'/gu, "\""); | ||||
|         } | ||||
|     }, | ||||
|     "prefer-single": { | ||||
|         quote: "'", | ||||
|         description: "doublequote", | ||||
|         convert(str) { | ||||
|             return str.replace(/"/gu, "'"); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce the consistent use of either double or single quotes in JSX attributes", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/jsx-quotes" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["prefer-single", "prefer-double"] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             unexpected: "Unexpected usage of {{description}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const quoteOption = context.options[0] || "prefer-double", | ||||
|             setting = QUOTE_SETTINGS[quoteOption]; | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given string literal node uses the expected quotes | ||||
|          * @param {ASTNode} node A string literal node. | ||||
|          * @returns {boolean} Whether or not the string literal used the expected quotes. | ||||
|          * @public | ||||
|          */ | ||||
|         function usesExpectedQuotes(node) { | ||||
|             return node.value.includes(setting.quote) || astUtils.isSurroundedBy(node.raw, setting.quote); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             JSXAttribute(node) { | ||||
|                 const attributeValue = node.value; | ||||
|  | ||||
|                 if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { | ||||
|                     context.report({ | ||||
|                         node: attributeValue, | ||||
|                         messageId: "unexpected", | ||||
|                         data: { | ||||
|                             description: setting.description | ||||
|                         }, | ||||
|                         fix(fixer) { | ||||
|                             return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										687
									
								
								node_modules/eslint/lib/rules/key-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										687
									
								
								node_modules/eslint/lib/rules/key-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,687 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to specify spacing of object literal keys and values | ||||
|  * @author Brandon Mills | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { getGraphemeCount } = require("../shared/string-utils"); | ||||
|  | ||||
| /** | ||||
|  * Checks whether a string contains a line terminator as defined in | ||||
|  * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 | ||||
|  * @param {string} str String to test. | ||||
|  * @returns {boolean} True if str contains a line terminator. | ||||
|  */ | ||||
| function containsLineTerminator(str) { | ||||
|     return astUtils.LINEBREAK_MATCHER.test(str); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Gets the last element of an array. | ||||
|  * @param {Array} arr An array. | ||||
|  * @returns {any} Last element of arr. | ||||
|  */ | ||||
| function last(arr) { | ||||
|     return arr[arr.length - 1]; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether a node is contained on a single line. | ||||
|  * @param {ASTNode} node AST Node being evaluated. | ||||
|  * @returns {boolean} True if the node is a single line. | ||||
|  */ | ||||
| function isSingleLine(node) { | ||||
|     return (node.loc.end.line === node.loc.start.line); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether the properties on a single line. | ||||
|  * @param {ASTNode[]} properties List of Property AST nodes. | ||||
|  * @returns {boolean} True if all properties is on a single line. | ||||
|  */ | ||||
| function isSingleLineProperties(properties) { | ||||
|     const [firstProp] = properties, | ||||
|         lastProp = last(properties); | ||||
|  | ||||
|     return firstProp.loc.start.line === lastProp.loc.end.line; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Initializes a single option property from the configuration with defaults for undefined values | ||||
|  * @param {Object} toOptions Object to be initialized | ||||
|  * @param {Object} fromOptions Object to be initialized from | ||||
|  * @returns {Object} The object with correctly initialized options and values | ||||
|  */ | ||||
| function initOptionProperty(toOptions, fromOptions) { | ||||
|     toOptions.mode = fromOptions.mode || "strict"; | ||||
|  | ||||
|     // Set value of beforeColon | ||||
|     if (typeof fromOptions.beforeColon !== "undefined") { | ||||
|         toOptions.beforeColon = +fromOptions.beforeColon; | ||||
|     } else { | ||||
|         toOptions.beforeColon = 0; | ||||
|     } | ||||
|  | ||||
|     // Set value of afterColon | ||||
|     if (typeof fromOptions.afterColon !== "undefined") { | ||||
|         toOptions.afterColon = +fromOptions.afterColon; | ||||
|     } else { | ||||
|         toOptions.afterColon = 1; | ||||
|     } | ||||
|  | ||||
|     // Set align if exists | ||||
|     if (typeof fromOptions.align !== "undefined") { | ||||
|         if (typeof fromOptions.align === "object") { | ||||
|             toOptions.align = fromOptions.align; | ||||
|         } else { // "string" | ||||
|             toOptions.align = { | ||||
|                 on: fromOptions.align, | ||||
|                 mode: toOptions.mode, | ||||
|                 beforeColon: toOptions.beforeColon, | ||||
|                 afterColon: toOptions.afterColon | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return toOptions; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values | ||||
|  * @param {Object} toOptions Object to be initialized | ||||
|  * @param {Object} fromOptions Object to be initialized from | ||||
|  * @returns {Object} The object with correctly initialized options and values | ||||
|  */ | ||||
| function initOptions(toOptions, fromOptions) { | ||||
|     if (typeof fromOptions.align === "object") { | ||||
|  | ||||
|         // Initialize the alignment configuration | ||||
|         toOptions.align = initOptionProperty({}, fromOptions.align); | ||||
|         toOptions.align.on = fromOptions.align.on || "colon"; | ||||
|         toOptions.align.mode = fromOptions.align.mode || "strict"; | ||||
|  | ||||
|         toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); | ||||
|         toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); | ||||
|  | ||||
|     } else { // string or undefined | ||||
|         toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); | ||||
|         toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); | ||||
|  | ||||
|         // If alignment options are defined in multiLine, pull them out into the general align configuration | ||||
|         if (toOptions.multiLine.align) { | ||||
|             toOptions.align = { | ||||
|                 on: toOptions.multiLine.align.on, | ||||
|                 mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode, | ||||
|                 beforeColon: toOptions.multiLine.align.beforeColon, | ||||
|                 afterColon: toOptions.multiLine.align.afterColon | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return toOptions; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing between keys and values in object literal properties", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/key-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [{ | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "object", | ||||
|                     properties: { | ||||
|                         align: { | ||||
|                             anyOf: [ | ||||
|                                 { | ||||
|                                     enum: ["colon", "value"] | ||||
|                                 }, | ||||
|                                 { | ||||
|                                     type: "object", | ||||
|                                     properties: { | ||||
|                                         mode: { | ||||
|                                             enum: ["strict", "minimum"] | ||||
|                                         }, | ||||
|                                         on: { | ||||
|                                             enum: ["colon", "value"] | ||||
|                                         }, | ||||
|                                         beforeColon: { | ||||
|                                             type: "boolean" | ||||
|                                         }, | ||||
|                                         afterColon: { | ||||
|                                             type: "boolean" | ||||
|                                         } | ||||
|                                     }, | ||||
|                                     additionalProperties: false | ||||
|                                 } | ||||
|                             ] | ||||
|                         }, | ||||
|                         mode: { | ||||
|                             enum: ["strict", "minimum"] | ||||
|                         }, | ||||
|                         beforeColon: { | ||||
|                             type: "boolean" | ||||
|                         }, | ||||
|                         afterColon: { | ||||
|                             type: "boolean" | ||||
|                         } | ||||
|                     }, | ||||
|                     additionalProperties: false | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "object", | ||||
|                     properties: { | ||||
|                         singleLine: { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 mode: { | ||||
|                                     enum: ["strict", "minimum"] | ||||
|                                 }, | ||||
|                                 beforeColon: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 afterColon: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         }, | ||||
|                         multiLine: { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 align: { | ||||
|                                     anyOf: [ | ||||
|                                         { | ||||
|                                             enum: ["colon", "value"] | ||||
|                                         }, | ||||
|                                         { | ||||
|                                             type: "object", | ||||
|                                             properties: { | ||||
|                                                 mode: { | ||||
|                                                     enum: ["strict", "minimum"] | ||||
|                                                 }, | ||||
|                                                 on: { | ||||
|                                                     enum: ["colon", "value"] | ||||
|                                                 }, | ||||
|                                                 beforeColon: { | ||||
|                                                     type: "boolean" | ||||
|                                                 }, | ||||
|                                                 afterColon: { | ||||
|                                                     type: "boolean" | ||||
|                                                 } | ||||
|                                             }, | ||||
|                                             additionalProperties: false | ||||
|                                         } | ||||
|                                     ] | ||||
|                                 }, | ||||
|                                 mode: { | ||||
|                                     enum: ["strict", "minimum"] | ||||
|                                 }, | ||||
|                                 beforeColon: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 afterColon: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     }, | ||||
|                     additionalProperties: false | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "object", | ||||
|                     properties: { | ||||
|                         singleLine: { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 mode: { | ||||
|                                     enum: ["strict", "minimum"] | ||||
|                                 }, | ||||
|                                 beforeColon: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 afterColon: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         }, | ||||
|                         multiLine: { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 mode: { | ||||
|                                     enum: ["strict", "minimum"] | ||||
|                                 }, | ||||
|                                 beforeColon: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 afterColon: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         }, | ||||
|                         align: { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 mode: { | ||||
|                                     enum: ["strict", "minimum"] | ||||
|                                 }, | ||||
|                                 on: { | ||||
|                                     enum: ["colon", "value"] | ||||
|                                 }, | ||||
|                                 beforeColon: { | ||||
|                                     type: "boolean" | ||||
|                                 }, | ||||
|                                 afterColon: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     }, | ||||
|                     additionalProperties: false | ||||
|                 } | ||||
|             ] | ||||
|         }], | ||||
|         messages: { | ||||
|             extraKey: "Extra space after {{computed}}key '{{key}}'.", | ||||
|             extraValue: "Extra space before value for {{computed}}key '{{key}}'.", | ||||
|             missingKey: "Missing space after {{computed}}key '{{key}}'.", | ||||
|             missingValue: "Missing space before value for {{computed}}key '{{key}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /** | ||||
|          * OPTIONS | ||||
|          * "key-spacing": [2, { | ||||
|          *     beforeColon: false, | ||||
|          *     afterColon: true, | ||||
|          *     align: "colon" // Optional, or "value" | ||||
|          * } | ||||
|          */ | ||||
|         const options = context.options[0] || {}, | ||||
|             ruleOptions = initOptions({}, options), | ||||
|             multiLineOptions = ruleOptions.multiLine, | ||||
|             singleLineOptions = ruleOptions.singleLine, | ||||
|             alignmentOptions = ruleOptions.align || null; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Determines if the given property is key-value property. | ||||
|          * @param {ASTNode} property Property node to check. | ||||
|          * @returns {boolean} Whether the property is a key-value property. | ||||
|          */ | ||||
|         function isKeyValueProperty(property) { | ||||
|             return !( | ||||
|                 (property.method || | ||||
|                 property.shorthand || | ||||
|                 property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Starting from the given node (a property.key node here) looks forward | ||||
|          * until it finds the colon punctuator and returns it. | ||||
|          * @param {ASTNode} node The node to start looking from. | ||||
|          * @returns {ASTNode} The colon punctuator. | ||||
|          */ | ||||
|         function getNextColon(node) { | ||||
|             return sourceCode.getTokenAfter(node, astUtils.isColonToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Starting from the given node (a property.key node here) looks forward | ||||
|          * until it finds the last token before a colon punctuator and returns it. | ||||
|          * @param {ASTNode} node The node to start looking from. | ||||
|          * @returns {ASTNode} The last token before a colon punctuator. | ||||
|          */ | ||||
|         function getLastTokenBeforeColon(node) { | ||||
|             const colonToken = getNextColon(node); | ||||
|  | ||||
|             return sourceCode.getTokenBefore(colonToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Starting from the given node (a property.key node here) looks forward | ||||
|          * until it finds the first token after a colon punctuator and returns it. | ||||
|          * @param {ASTNode} node The node to start looking from. | ||||
|          * @returns {ASTNode} The first token after a colon punctuator. | ||||
|          */ | ||||
|         function getFirstTokenAfterColon(node) { | ||||
|             const colonToken = getNextColon(node); | ||||
|  | ||||
|             return sourceCode.getTokenAfter(colonToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether a property is a member of the property group it follows. | ||||
|          * @param {ASTNode} lastMember The last Property known to be in the group. | ||||
|          * @param {ASTNode} candidate The next Property that might be in the group. | ||||
|          * @returns {boolean} True if the candidate property is part of the group. | ||||
|          */ | ||||
|         function continuesPropertyGroup(lastMember, candidate) { | ||||
|             const groupEndLine = lastMember.loc.start.line, | ||||
|                 candidateValueStartLine = (isKeyValueProperty(candidate) ? getFirstTokenAfterColon(candidate.key) : candidate).loc.start.line; | ||||
|  | ||||
|             if (candidateValueStartLine - groupEndLine <= 1) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Check that the first comment is adjacent to the end of the group, the | ||||
|              * last comment is adjacent to the candidate property, and that successive | ||||
|              * comments are adjacent to each other. | ||||
|              */ | ||||
|             const leadingComments = sourceCode.getCommentsBefore(candidate); | ||||
|  | ||||
|             if ( | ||||
|                 leadingComments.length && | ||||
|                 leadingComments[0].loc.start.line - groupEndLine <= 1 && | ||||
|                 candidateValueStartLine - last(leadingComments).loc.end.line <= 1 | ||||
|             ) { | ||||
|                 for (let i = 1; i < leadingComments.length; i++) { | ||||
|                     if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets an object literal property's key as the identifier name or string value. | ||||
|          * @param {ASTNode} property Property node whose key to retrieve. | ||||
|          * @returns {string} The property's key. | ||||
|          */ | ||||
|         function getKey(property) { | ||||
|             const key = property.key; | ||||
|  | ||||
|             if (property.computed) { | ||||
|                 return sourceCode.getText().slice(key.range[0], key.range[1]); | ||||
|             } | ||||
|             return astUtils.getStaticPropertyName(property); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports an appropriately-formatted error if spacing is incorrect on one | ||||
|          * side of the colon. | ||||
|          * @param {ASTNode} property Key-value pair in an object literal. | ||||
|          * @param {string} side Side being verified - either "key" or "value". | ||||
|          * @param {string} whitespace Actual whitespace string. | ||||
|          * @param {int} expected Expected whitespace length. | ||||
|          * @param {string} mode Value of the mode as "strict" or "minimum" | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(property, side, whitespace, expected, mode) { | ||||
|             const diff = whitespace.length - expected; | ||||
|  | ||||
|             if (( | ||||
|                 diff && mode === "strict" || | ||||
|                 diff < 0 && mode === "minimum" || | ||||
|                 diff > 0 && !expected && mode === "minimum") && | ||||
|                 !(expected && containsLineTerminator(whitespace)) | ||||
|             ) { | ||||
|                 const nextColon = getNextColon(property.key), | ||||
|                     tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }), | ||||
|                     tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }), | ||||
|                     isKeySide = side === "key", | ||||
|                     isExtra = diff > 0, | ||||
|                     diffAbs = Math.abs(diff), | ||||
|                     spaces = Array(diffAbs + 1).join(" "); | ||||
|  | ||||
|                 const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start; | ||||
|                 const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start; | ||||
|                 const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc; | ||||
|                 const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc; | ||||
|  | ||||
|                 let fix; | ||||
|  | ||||
|                 if (isExtra) { | ||||
|                     let range; | ||||
|  | ||||
|                     // Remove whitespace | ||||
|                     if (isKeySide) { | ||||
|                         range = [tokenBeforeColon.range[1], tokenBeforeColon.range[1] + diffAbs]; | ||||
|                     } else { | ||||
|                         range = [tokenAfterColon.range[0] - diffAbs, tokenAfterColon.range[0]]; | ||||
|                     } | ||||
|                     fix = function(fixer) { | ||||
|                         return fixer.removeRange(range); | ||||
|                     }; | ||||
|                 } else { | ||||
|  | ||||
|                     // Add whitespace | ||||
|                     if (isKeySide) { | ||||
|                         fix = function(fixer) { | ||||
|                             return fixer.insertTextAfter(tokenBeforeColon, spaces); | ||||
|                         }; | ||||
|                     } else { | ||||
|                         fix = function(fixer) { | ||||
|                             return fixer.insertTextBefore(tokenAfterColon, spaces); | ||||
|                         }; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 let messageId = ""; | ||||
|  | ||||
|                 if (isExtra) { | ||||
|                     messageId = side === "key" ? "extraKey" : "extraValue"; | ||||
|                 } else { | ||||
|                     messageId = side === "key" ? "missingKey" : "missingValue"; | ||||
|                 } | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: property[side], | ||||
|                     loc, | ||||
|                     messageId, | ||||
|                     data: { | ||||
|                         computed: property.computed ? "computed " : "", | ||||
|                         key: getKey(property) | ||||
|                     }, | ||||
|                     fix | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the number of characters in a key, including quotes around string | ||||
|          * keys and braces around computed property keys. | ||||
|          * @param {ASTNode} property Property of on object literal. | ||||
|          * @returns {int} Width of the key. | ||||
|          */ | ||||
|         function getKeyWidth(property) { | ||||
|             const startToken = sourceCode.getFirstToken(property); | ||||
|             const endToken = getLastTokenBeforeColon(property.key); | ||||
|  | ||||
|             return getGraphemeCount(sourceCode.getText().slice(startToken.range[0], endToken.range[1])); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the whitespace around the colon in an object literal property. | ||||
|          * @param {ASTNode} property Property node from an object literal. | ||||
|          * @returns {Object} Whitespace before and after the property's colon. | ||||
|          */ | ||||
|         function getPropertyWhitespace(property) { | ||||
|             const whitespace = /(\s*):(\s*)/u.exec(sourceCode.getText().slice( | ||||
|                 property.key.range[1], property.value.range[0] | ||||
|             )); | ||||
|  | ||||
|             if (whitespace) { | ||||
|                 return { | ||||
|                     beforeColon: whitespace[1], | ||||
|                     afterColon: whitespace[2] | ||||
|                 }; | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Creates groups of properties. | ||||
|          * @param {ASTNode} node ObjectExpression node being evaluated. | ||||
|          * @returns {Array<ASTNode[]>} Groups of property AST node lists. | ||||
|          */ | ||||
|         function createGroups(node) { | ||||
|             if (node.properties.length === 1) { | ||||
|                 return [node.properties]; | ||||
|             } | ||||
|  | ||||
|             return node.properties.reduce((groups, property) => { | ||||
|                 const currentGroup = last(groups), | ||||
|                     prev = last(currentGroup); | ||||
|  | ||||
|                 if (!prev || continuesPropertyGroup(prev, property)) { | ||||
|                     currentGroup.push(property); | ||||
|                 } else { | ||||
|                     groups.push([property]); | ||||
|                 } | ||||
|  | ||||
|                 return groups; | ||||
|             }, [ | ||||
|                 [] | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Verifies correct vertical alignment of a group of properties. | ||||
|          * @param {ASTNode[]} properties List of Property AST nodes. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function verifyGroupAlignment(properties) { | ||||
|             const length = properties.length, | ||||
|                 widths = properties.map(getKeyWidth), // Width of keys, including quotes | ||||
|                 align = alignmentOptions.on; // "value" or "colon" | ||||
|             let targetWidth = Math.max(...widths), | ||||
|                 beforeColon, afterColon, mode; | ||||
|  | ||||
|             if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. | ||||
|                 beforeColon = alignmentOptions.beforeColon; | ||||
|                 afterColon = alignmentOptions.afterColon; | ||||
|                 mode = alignmentOptions.mode; | ||||
|             } else { | ||||
|                 beforeColon = multiLineOptions.beforeColon; | ||||
|                 afterColon = multiLineOptions.afterColon; | ||||
|                 mode = alignmentOptions.mode; | ||||
|             } | ||||
|  | ||||
|             // Conditionally include one space before or after colon | ||||
|             targetWidth += (align === "colon" ? beforeColon : afterColon); | ||||
|  | ||||
|             for (let i = 0; i < length; i++) { | ||||
|                 const property = properties[i]; | ||||
|                 const whitespace = getPropertyWhitespace(property); | ||||
|  | ||||
|                 if (whitespace) { // Object literal getters/setters lack a colon | ||||
|                     const width = widths[i]; | ||||
|  | ||||
|                     if (align === "value") { | ||||
|                         report(property, "key", whitespace.beforeColon, beforeColon, mode); | ||||
|                         report(property, "value", whitespace.afterColon, targetWidth - width, mode); | ||||
|                     } else { // align = "colon" | ||||
|                         report(property, "key", whitespace.beforeColon, targetWidth - width, mode); | ||||
|                         report(property, "value", whitespace.afterColon, afterColon, mode); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Verifies spacing of property conforms to specified options. | ||||
|          * @param {ASTNode} node Property node being evaluated. | ||||
|          * @param {Object} lineOptions Configured singleLine or multiLine options | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function verifySpacing(node, lineOptions) { | ||||
|             const actual = getPropertyWhitespace(node); | ||||
|  | ||||
|             if (actual) { // Object literal getters/setters lack colons | ||||
|                 report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); | ||||
|                 report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Verifies spacing of each property in a list. | ||||
|          * @param {ASTNode[]} properties List of Property AST nodes. | ||||
|          * @param {Object} lineOptions Configured singleLine or multiLine options | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function verifyListSpacing(properties, lineOptions) { | ||||
|             const length = properties.length; | ||||
|  | ||||
|             for (let i = 0; i < length; i++) { | ||||
|                 verifySpacing(properties[i], lineOptions); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Verifies vertical alignment, taking into account groups of properties. | ||||
|          * @param {ASTNode} node ObjectExpression node being evaluated. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function verifyAlignment(node) { | ||||
|             createGroups(node).forEach(group => { | ||||
|                 const properties = group.filter(isKeyValueProperty); | ||||
|  | ||||
|                 if (properties.length > 0 && isSingleLineProperties(properties)) { | ||||
|                     verifyListSpacing(properties, multiLineOptions); | ||||
|                 } else { | ||||
|                     verifyGroupAlignment(properties); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         if (alignmentOptions) { // Verify vertical alignment | ||||
|  | ||||
|             return { | ||||
|                 ObjectExpression(node) { | ||||
|                     if (isSingleLine(node)) { | ||||
|                         verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions); | ||||
|                     } else { | ||||
|                         verifyAlignment(node); | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Obey beforeColon and afterColon in each property as configured | ||||
|         return { | ||||
|             Property(node) { | ||||
|                 verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										640
									
								
								node_modules/eslint/lib/rules/keyword-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										640
									
								
								node_modules/eslint/lib/rules/keyword-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,640 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce spacing before and after keywords. | ||||
|  * @author Toru Nagashima | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"), | ||||
|     keywords = require("./utils/keywords"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Constants | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const PREV_TOKEN = /^[)\]}>]$/u; | ||||
| const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u; | ||||
| const PREV_TOKEN_M = /^[)\]}>*]$/u; | ||||
| const NEXT_TOKEN_M = /^[{*]$/u; | ||||
| const TEMPLATE_OPEN_PAREN = /\$\{$/u; | ||||
| const TEMPLATE_CLOSE_PAREN = /^\}/u; | ||||
| const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template|PrivateIdentifier)$/u; | ||||
| const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]); | ||||
|  | ||||
| // check duplications. | ||||
| (function() { | ||||
|     KEYS.sort(); | ||||
|     for (let i = 1; i < KEYS.length; ++i) { | ||||
|         if (KEYS[i] === KEYS[i - 1]) { | ||||
|             throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`); | ||||
|         } | ||||
|     } | ||||
| }()); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given token is a "Template" token ends with "${". | ||||
|  * @param {Token} token A token to check. | ||||
|  * @returns {boolean} `true` if the token is a "Template" token ends with "${". | ||||
|  */ | ||||
| function isOpenParenOfTemplate(token) { | ||||
|     return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a given token is a "Template" token starts with "}". | ||||
|  * @param {Token} token A token to check. | ||||
|  * @returns {boolean} `true` if the token is a "Template" token starts with "}". | ||||
|  */ | ||||
| function isCloseParenOfTemplate(token) { | ||||
|     return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent spacing before and after keywords", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/keyword-spacing" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     before: { type: "boolean", default: true }, | ||||
|                     after: { type: "boolean", default: true }, | ||||
|                     overrides: { | ||||
|                         type: "object", | ||||
|                         properties: KEYS.reduce((retv, key) => { | ||||
|                             retv[key] = { | ||||
|                                 type: "object", | ||||
|                                 properties: { | ||||
|                                     before: { type: "boolean" }, | ||||
|                                     after: { type: "boolean" } | ||||
|                                 }, | ||||
|                                 additionalProperties: false | ||||
|                             }; | ||||
|                             return retv; | ||||
|                         }, {}), | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             expectedBefore: "Expected space(s) before \"{{value}}\".", | ||||
|             expectedAfter: "Expected space(s) after \"{{value}}\".", | ||||
|             unexpectedBefore: "Unexpected space(s) before \"{{value}}\".", | ||||
|             unexpectedAfter: "Unexpected space(s) after \"{{value}}\"." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         const tokensToIgnore = new WeakSet(); | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if there are not space(s) before the token. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} pattern A pattern of the previous token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function expectSpaceBefore(token, pattern) { | ||||
|             const prevToken = sourceCode.getTokenBefore(token); | ||||
|  | ||||
|             if (prevToken && | ||||
|                 (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && | ||||
|                 !isOpenParenOfTemplate(prevToken) && | ||||
|                 !tokensToIgnore.has(prevToken) && | ||||
|                 astUtils.isTokenOnSameLine(prevToken, token) && | ||||
|                 !sourceCode.isSpaceBetweenTokens(prevToken, token) | ||||
|             ) { | ||||
|                 context.report({ | ||||
|                     loc: token.loc, | ||||
|                     messageId: "expectedBefore", | ||||
|                     data: token, | ||||
|                     fix(fixer) { | ||||
|                         return fixer.insertTextBefore(token, " "); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if there are space(s) before the token. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} pattern A pattern of the previous token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function unexpectSpaceBefore(token, pattern) { | ||||
|             const prevToken = sourceCode.getTokenBefore(token); | ||||
|  | ||||
|             if (prevToken && | ||||
|                 (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && | ||||
|                 !isOpenParenOfTemplate(prevToken) && | ||||
|                 !tokensToIgnore.has(prevToken) && | ||||
|                 astUtils.isTokenOnSameLine(prevToken, token) && | ||||
|                 sourceCode.isSpaceBetweenTokens(prevToken, token) | ||||
|             ) { | ||||
|                 context.report({ | ||||
|                     loc: { start: prevToken.loc.end, end: token.loc.start }, | ||||
|                     messageId: "unexpectedBefore", | ||||
|                     data: token, | ||||
|                     fix(fixer) { | ||||
|                         return fixer.removeRange([prevToken.range[1], token.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if there are not space(s) after the token. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} pattern A pattern of the next token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function expectSpaceAfter(token, pattern) { | ||||
|             const nextToken = sourceCode.getTokenAfter(token); | ||||
|  | ||||
|             if (nextToken && | ||||
|                 (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && | ||||
|                 !isCloseParenOfTemplate(nextToken) && | ||||
|                 !tokensToIgnore.has(nextToken) && | ||||
|                 astUtils.isTokenOnSameLine(token, nextToken) && | ||||
|                 !sourceCode.isSpaceBetweenTokens(token, nextToken) | ||||
|             ) { | ||||
|                 context.report({ | ||||
|                     loc: token.loc, | ||||
|                     messageId: "expectedAfter", | ||||
|                     data: token, | ||||
|                     fix(fixer) { | ||||
|                         return fixer.insertTextAfter(token, " "); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if there are space(s) after the token. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} pattern A pattern of the next token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function unexpectSpaceAfter(token, pattern) { | ||||
|             const nextToken = sourceCode.getTokenAfter(token); | ||||
|  | ||||
|             if (nextToken && | ||||
|                 (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && | ||||
|                 !isCloseParenOfTemplate(nextToken) && | ||||
|                 !tokensToIgnore.has(nextToken) && | ||||
|                 astUtils.isTokenOnSameLine(token, nextToken) && | ||||
|                 sourceCode.isSpaceBetweenTokens(token, nextToken) | ||||
|             ) { | ||||
|  | ||||
|                 context.report({ | ||||
|                     loc: { start: token.loc.end, end: nextToken.loc.start }, | ||||
|                     messageId: "unexpectedAfter", | ||||
|                     data: token, | ||||
|                     fix(fixer) { | ||||
|                         return fixer.removeRange([token.range[1], nextToken.range[0]]); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Parses the option object and determines check methods for each keyword. | ||||
|          * @param {Object|undefined} options The option object to parse. | ||||
|          * @returns {Object} - Normalized option object. | ||||
|          *      Keys are keywords (there are for every keyword). | ||||
|          *      Values are instances of `{"before": function, "after": function}`. | ||||
|          */ | ||||
|         function parseOptions(options = {}) { | ||||
|             const before = options.before !== false; | ||||
|             const after = options.after !== false; | ||||
|             const defaultValue = { | ||||
|                 before: before ? expectSpaceBefore : unexpectSpaceBefore, | ||||
|                 after: after ? expectSpaceAfter : unexpectSpaceAfter | ||||
|             }; | ||||
|             const overrides = (options && options.overrides) || {}; | ||||
|             const retv = Object.create(null); | ||||
|  | ||||
|             for (let i = 0; i < KEYS.length; ++i) { | ||||
|                 const key = KEYS[i]; | ||||
|                 const override = overrides[key]; | ||||
|  | ||||
|                 if (override) { | ||||
|                     const thisBefore = ("before" in override) ? override.before : before; | ||||
|                     const thisAfter = ("after" in override) ? override.after : after; | ||||
|  | ||||
|                     retv[key] = { | ||||
|                         before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, | ||||
|                         after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter | ||||
|                     }; | ||||
|                 } else { | ||||
|                     retv[key] = defaultValue; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return retv; | ||||
|         } | ||||
|  | ||||
|         const checkMethodMap = parseOptions(context.options[0]); | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if usage of spacing followed by the token is | ||||
|          * invalid. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} [pattern] Optional. A pattern of the previous | ||||
|          *      token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingBefore(token, pattern) { | ||||
|             checkMethodMap[token.value].before(token, pattern || PREV_TOKEN); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if usage of spacing preceded by the token is | ||||
|          * invalid. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @param {RegExp} [pattern] Optional. A pattern of the next | ||||
|          *      token to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingAfter(token, pattern) { | ||||
|             checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a given token if usage of spacing around the token is invalid. | ||||
|          * @param {Token} token A token to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingAround(token) { | ||||
|             checkSpacingBefore(token); | ||||
|             checkSpacingAfter(token); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the first token of a given node if the first token is a keyword | ||||
|          * and usage of spacing around the token is invalid. | ||||
|          * @param {ASTNode|null} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingAroundFirstToken(node) { | ||||
|             const firstToken = node && sourceCode.getFirstToken(node); | ||||
|  | ||||
|             if (firstToken && firstToken.type === "Keyword") { | ||||
|                 checkSpacingAround(firstToken); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the first token of a given node if the first token is a keyword | ||||
|          * and usage of spacing followed by the token is invalid. | ||||
|          * | ||||
|          * This is used for unary operators (e.g. `typeof`), `function`, and `super`. | ||||
|          * Other rules are handling usage of spacing preceded by those keywords. | ||||
|          * @param {ASTNode|null} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingBeforeFirstToken(node) { | ||||
|             const firstToken = node && sourceCode.getFirstToken(node); | ||||
|  | ||||
|             if (firstToken && firstToken.type === "Keyword") { | ||||
|                 checkSpacingBefore(firstToken); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the previous token of a given node if the token is a keyword and | ||||
|          * usage of spacing around the token is invalid. | ||||
|          * @param {ASTNode|null} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingAroundTokenBefore(node) { | ||||
|             if (node) { | ||||
|                 const token = sourceCode.getTokenBefore(node, astUtils.isKeywordToken); | ||||
|  | ||||
|                 checkSpacingAround(token); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `async` or `function` keywords of a given node if usage of | ||||
|          * spacing around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForFunction(node) { | ||||
|             const firstToken = node && sourceCode.getFirstToken(node); | ||||
|  | ||||
|             if (firstToken && | ||||
|                 ((firstToken.type === "Keyword" && firstToken.value === "function") || | ||||
|                 firstToken.value === "async") | ||||
|             ) { | ||||
|                 checkSpacingBefore(firstToken); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `class` and `extends` keywords of a given node if usage of | ||||
|          * spacing around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForClass(node) { | ||||
|             checkSpacingAroundFirstToken(node); | ||||
|             checkSpacingAroundTokenBefore(node.superClass); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `if` and `else` keywords of a given node if usage of spacing | ||||
|          * around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForIfStatement(node) { | ||||
|             checkSpacingAroundFirstToken(node); | ||||
|             checkSpacingAroundTokenBefore(node.alternate); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `try`, `catch`, and `finally` keywords of a given node if usage | ||||
|          * of spacing around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForTryStatement(node) { | ||||
|             checkSpacingAroundFirstToken(node); | ||||
|             checkSpacingAroundFirstToken(node.handler); | ||||
|             checkSpacingAroundTokenBefore(node.finalizer); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `do` and `while` keywords of a given node if usage of spacing | ||||
|          * around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForDoWhileStatement(node) { | ||||
|             checkSpacingAroundFirstToken(node); | ||||
|             checkSpacingAroundTokenBefore(node.test); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `for` and `in` keywords of a given node if usage of spacing | ||||
|          * around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForForInStatement(node) { | ||||
|             checkSpacingAroundFirstToken(node); | ||||
|  | ||||
|             const inToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken); | ||||
|             const previousToken = sourceCode.getTokenBefore(inToken); | ||||
|  | ||||
|             if (previousToken.type !== "PrivateIdentifier") { | ||||
|                 checkSpacingBefore(inToken); | ||||
|             } | ||||
|  | ||||
|             checkSpacingAfter(inToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `for` and `of` keywords of a given node if usage of spacing | ||||
|          * around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForForOfStatement(node) { | ||||
|             if (node.await) { | ||||
|                 checkSpacingBefore(sourceCode.getFirstToken(node, 0)); | ||||
|                 checkSpacingAfter(sourceCode.getFirstToken(node, 1)); | ||||
|             } else { | ||||
|                 checkSpacingAroundFirstToken(node); | ||||
|             } | ||||
|  | ||||
|             const ofToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken); | ||||
|             const previousToken = sourceCode.getTokenBefore(ofToken); | ||||
|  | ||||
|             if (previousToken.type !== "PrivateIdentifier") { | ||||
|                 checkSpacingBefore(ofToken); | ||||
|             } | ||||
|  | ||||
|             checkSpacingAfter(ofToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `import`, `export`, `as`, and `from` keywords of a given node if | ||||
|          * usage of spacing around those keywords is invalid. | ||||
|          * | ||||
|          * This rule handles the `*` token in module declarations. | ||||
|          * | ||||
|          *     import*as A from "./a"; /*error Expected space(s) after "import". | ||||
|          *                               error Expected space(s) before "as". | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForModuleDeclaration(node) { | ||||
|             const firstToken = sourceCode.getFirstToken(node); | ||||
|  | ||||
|             checkSpacingBefore(firstToken, PREV_TOKEN_M); | ||||
|             checkSpacingAfter(firstToken, NEXT_TOKEN_M); | ||||
|  | ||||
|             if (node.type === "ExportDefaultDeclaration") { | ||||
|                 checkSpacingAround(sourceCode.getTokenAfter(firstToken)); | ||||
|             } | ||||
|  | ||||
|             if (node.type === "ExportAllDeclaration" && node.exported) { | ||||
|                 const asToken = sourceCode.getTokenBefore(node.exported); | ||||
|  | ||||
|                 checkSpacingBefore(asToken, PREV_TOKEN_M); | ||||
|                 checkSpacingAfter(asToken, NEXT_TOKEN_M); | ||||
|             } | ||||
|  | ||||
|             if (node.source) { | ||||
|                 const fromToken = sourceCode.getTokenBefore(node.source); | ||||
|  | ||||
|                 checkSpacingBefore(fromToken, PREV_TOKEN_M); | ||||
|                 checkSpacingAfter(fromToken, NEXT_TOKEN_M); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `as` keyword of a given node if usage of spacing around this | ||||
|          * keyword is invalid. | ||||
|          * @param {ASTNode} node An `ImportSpecifier` node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForImportSpecifier(node) { | ||||
|             if (node.imported.range[0] !== node.local.range[0]) { | ||||
|                 const asToken = sourceCode.getTokenBefore(node.local); | ||||
|  | ||||
|                 checkSpacingBefore(asToken, PREV_TOKEN_M); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `as` keyword of a given node if usage of spacing around this | ||||
|          * keyword is invalid. | ||||
|          * @param {ASTNode} node An `ExportSpecifier` node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForExportSpecifier(node) { | ||||
|             if (node.local.range[0] !== node.exported.range[0]) { | ||||
|                 const asToken = sourceCode.getTokenBefore(node.exported); | ||||
|  | ||||
|                 checkSpacingBefore(asToken, PREV_TOKEN_M); | ||||
|                 checkSpacingAfter(asToken, NEXT_TOKEN_M); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `as` keyword of a given node if usage of spacing around this | ||||
|          * keyword is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForImportNamespaceSpecifier(node) { | ||||
|             const asToken = sourceCode.getFirstToken(node, 1); | ||||
|  | ||||
|             checkSpacingBefore(asToken, PREV_TOKEN_M); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `static`, `get`, and `set` keywords of a given node if usage of | ||||
|          * spacing around those keywords is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @throws {Error} If unable to find token get, set, or async beside method name. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForProperty(node) { | ||||
|             if (node.static) { | ||||
|                 checkSpacingAroundFirstToken(node); | ||||
|             } | ||||
|             if (node.kind === "get" || | ||||
|                 node.kind === "set" || | ||||
|                 ( | ||||
|                     (node.method || node.type === "MethodDefinition") && | ||||
|                     node.value.async | ||||
|                 ) | ||||
|             ) { | ||||
|                 const token = sourceCode.getTokenBefore( | ||||
|                     node.key, | ||||
|                     tok => { | ||||
|                         switch (tok.value) { | ||||
|                             case "get": | ||||
|                             case "set": | ||||
|                             case "async": | ||||
|                                 return true; | ||||
|                             default: | ||||
|                                 return false; | ||||
|                         } | ||||
|                     } | ||||
|                 ); | ||||
|  | ||||
|                 if (!token) { | ||||
|                     throw new Error("Failed to find token get, set, or async beside method name"); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 checkSpacingAround(token); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports `await` keyword of a given node if usage of spacing before | ||||
|          * this keyword is invalid. | ||||
|          * @param {ASTNode} node A node to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkSpacingForAwaitExpression(node) { | ||||
|             checkSpacingBefore(sourceCode.getFirstToken(node)); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             // Statements | ||||
|             DebuggerStatement: checkSpacingAroundFirstToken, | ||||
|             WithStatement: checkSpacingAroundFirstToken, | ||||
|  | ||||
|             // Statements - Control flow | ||||
|             BreakStatement: checkSpacingAroundFirstToken, | ||||
|             ContinueStatement: checkSpacingAroundFirstToken, | ||||
|             ReturnStatement: checkSpacingAroundFirstToken, | ||||
|             ThrowStatement: checkSpacingAroundFirstToken, | ||||
|             TryStatement: checkSpacingForTryStatement, | ||||
|  | ||||
|             // Statements - Choice | ||||
|             IfStatement: checkSpacingForIfStatement, | ||||
|             SwitchStatement: checkSpacingAroundFirstToken, | ||||
|             SwitchCase: checkSpacingAroundFirstToken, | ||||
|  | ||||
|             // Statements - Loops | ||||
|             DoWhileStatement: checkSpacingForDoWhileStatement, | ||||
|             ForInStatement: checkSpacingForForInStatement, | ||||
|             ForOfStatement: checkSpacingForForOfStatement, | ||||
|             ForStatement: checkSpacingAroundFirstToken, | ||||
|             WhileStatement: checkSpacingAroundFirstToken, | ||||
|  | ||||
|             // Statements - Declarations | ||||
|             ClassDeclaration: checkSpacingForClass, | ||||
|             ExportNamedDeclaration: checkSpacingForModuleDeclaration, | ||||
|             ExportDefaultDeclaration: checkSpacingForModuleDeclaration, | ||||
|             ExportAllDeclaration: checkSpacingForModuleDeclaration, | ||||
|             FunctionDeclaration: checkSpacingForFunction, | ||||
|             ImportDeclaration: checkSpacingForModuleDeclaration, | ||||
|             VariableDeclaration: checkSpacingAroundFirstToken, | ||||
|  | ||||
|             // Expressions | ||||
|             ArrowFunctionExpression: checkSpacingForFunction, | ||||
|             AwaitExpression: checkSpacingForAwaitExpression, | ||||
|             ClassExpression: checkSpacingForClass, | ||||
|             FunctionExpression: checkSpacingForFunction, | ||||
|             NewExpression: checkSpacingBeforeFirstToken, | ||||
|             Super: checkSpacingBeforeFirstToken, | ||||
|             ThisExpression: checkSpacingBeforeFirstToken, | ||||
|             UnaryExpression: checkSpacingBeforeFirstToken, | ||||
|             YieldExpression: checkSpacingBeforeFirstToken, | ||||
|  | ||||
|             // Others | ||||
|             ImportSpecifier: checkSpacingForImportSpecifier, | ||||
|             ExportSpecifier: checkSpacingForExportSpecifier, | ||||
|             ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, | ||||
|             MethodDefinition: checkSpacingForProperty, | ||||
|             PropertyDefinition: checkSpacingForProperty, | ||||
|             StaticBlock: checkSpacingAroundFirstToken, | ||||
|             Property: checkSpacingForProperty, | ||||
|  | ||||
|             // To avoid conflicts with `space-infix-ops`, e.g. `a > this.b` | ||||
|             "BinaryExpression[operator='>']"(node) { | ||||
|                 const operatorToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken); | ||||
|  | ||||
|                 tokensToIgnore.add(operatorToken); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										122
									
								
								node_modules/eslint/lib/rules/line-comment-position.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								node_modules/eslint/lib/rules/line-comment-position.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce the position of line comments | ||||
|  * @author Alberto Rodríguez | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce position of line comments", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/line-comment-position" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         enum: ["above", "beside"] | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             position: { | ||||
|                                 enum: ["above", "beside"] | ||||
|                             }, | ||||
|                             ignorePattern: { | ||||
|                                 type: "string" | ||||
|                             }, | ||||
|                             applyDefaultPatterns: { | ||||
|                                 type: "boolean" | ||||
|                             }, | ||||
|                             applyDefaultIgnorePatterns: { | ||||
|                                 type: "boolean" | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             above: "Expected comment to be above code.", | ||||
|             beside: "Expected comment to be beside code." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0]; | ||||
|  | ||||
|         let above, | ||||
|             ignorePattern, | ||||
|             applyDefaultIgnorePatterns = true; | ||||
|  | ||||
|         if (!options || typeof options === "string") { | ||||
|             above = !options || options === "above"; | ||||
|  | ||||
|         } else { | ||||
|             above = !options.position || options.position === "above"; | ||||
|             ignorePattern = options.ignorePattern; | ||||
|  | ||||
|             if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) { | ||||
|                 applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns; | ||||
|             } else { | ||||
|                 applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; | ||||
|         const fallThroughRegExp = /^\s*falls?\s?through/u; | ||||
|         const customIgnoreRegExp = new RegExp(ignorePattern, "u"); | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program() { | ||||
|                 const comments = sourceCode.getAllComments(); | ||||
|  | ||||
|                 comments.filter(token => token.type === "Line").forEach(node => { | ||||
|                     if (applyDefaultIgnorePatterns && (defaultIgnoreRegExp.test(node.value) || fallThroughRegExp.test(node.value))) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     if (ignorePattern && customIgnoreRegExp.test(node.value)) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     const previous = sourceCode.getTokenBefore(node, { includeComments: true }); | ||||
|                     const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; | ||||
|  | ||||
|                     if (above) { | ||||
|                         if (isOnSameLine) { | ||||
|                             context.report({ | ||||
|                                 node, | ||||
|                                 messageId: "above" | ||||
|                             }); | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (!isOnSameLine) { | ||||
|                             context.report({ | ||||
|                                 node, | ||||
|                                 messageId: "beside" | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										108
									
								
								node_modules/eslint/lib/rules/linebreak-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								node_modules/eslint/lib/rules/linebreak-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce a single linebreak style. | ||||
|  * @author Erik Mueller | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce consistent linebreak style", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/linebreak-style" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["unix", "windows"] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             expectedLF: "Expected linebreaks to be 'LF' but found 'CRLF'.", | ||||
|             expectedCRLF: "Expected linebreaks to be 'CRLF' but found 'LF'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Builds a fix function that replaces text at the specified range in the source text. | ||||
|          * @param {int[]} range The range to replace | ||||
|          * @param {string} text The text to insert. | ||||
|          * @returns {Function} Fixer function | ||||
|          * @private | ||||
|          */ | ||||
|         function createFix(range, text) { | ||||
|             return function(fixer) { | ||||
|                 return fixer.replaceTextRange(range, text); | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program: function checkForLinebreakStyle(node) { | ||||
|                 const linebreakStyle = context.options[0] || "unix", | ||||
|                     expectedLF = linebreakStyle === "unix", | ||||
|                     expectedLFChars = expectedLF ? "\n" : "\r\n", | ||||
|                     source = sourceCode.getText(), | ||||
|                     pattern = astUtils.createGlobalLinebreakMatcher(); | ||||
|                 let match; | ||||
|  | ||||
|                 let i = 0; | ||||
|  | ||||
|                 while ((match = pattern.exec(source)) !== null) { | ||||
|                     i++; | ||||
|                     if (match[0] === expectedLFChars) { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     const index = match.index; | ||||
|                     const range = [index, index + match[0].length]; | ||||
|  | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc: { | ||||
|                             start: { | ||||
|                                 line: i, | ||||
|                                 column: sourceCode.lines[i - 1].length | ||||
|                             }, | ||||
|                             end: { | ||||
|                                 line: i + 1, | ||||
|                                 column: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         messageId: expectedLF ? "expectedLF" : "expectedCRLF", | ||||
|                         fix: createFix(range, expectedLFChars) | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										471
									
								
								node_modules/eslint/lib/rules/lines-around-comment.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										471
									
								
								node_modules/eslint/lib/rules/lines-around-comment.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,471 @@ | ||||
| /** | ||||
|  * @fileoverview Enforces empty lines around comments. | ||||
|  * @author Jamund Ferguson | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Return an array with any line numbers that are empty. | ||||
|  * @param {Array} lines An array of each line of the file. | ||||
|  * @returns {Array} An array of line numbers. | ||||
|  */ | ||||
| function getEmptyLineNums(lines) { | ||||
|     const emptyLines = lines.map((line, i) => ({ | ||||
|         code: line.trim(), | ||||
|         num: i + 1 | ||||
|     })).filter(line => !line.code).map(line => line.num); | ||||
|  | ||||
|     return emptyLines; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Return an array with any line numbers that contain comments. | ||||
|  * @param {Array} comments An array of comment tokens. | ||||
|  * @returns {Array} An array of line numbers. | ||||
|  */ | ||||
| function getCommentLineNums(comments) { | ||||
|     const lines = []; | ||||
|  | ||||
|     comments.forEach(token => { | ||||
|         const start = token.loc.start.line; | ||||
|         const end = token.loc.end.line; | ||||
|  | ||||
|         lines.push(start, end); | ||||
|     }); | ||||
|     return lines; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require empty lines around comments", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/lines-around-comment" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     beforeBlockComment: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     }, | ||||
|                     afterBlockComment: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     beforeLineComment: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     afterLineComment: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     allowBlockStart: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     allowBlockEnd: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     }, | ||||
|                     allowClassStart: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     allowClassEnd: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     allowObjectStart: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     allowObjectEnd: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     allowArrayStart: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     allowArrayEnd: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     ignorePattern: { | ||||
|                         type: "string" | ||||
|                     }, | ||||
|                     applyDefaultIgnorePatterns: { | ||||
|                         type: "boolean" | ||||
|                     }, | ||||
|                     afterHashbangComment: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             after: "Expected line after comment.", | ||||
|             before: "Expected line before comment." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const options = Object.assign({}, context.options[0]); | ||||
|         const ignorePattern = options.ignorePattern; | ||||
|         const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; | ||||
|         const customIgnoreRegExp = new RegExp(ignorePattern, "u"); | ||||
|         const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false; | ||||
|  | ||||
|         options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         const lines = sourceCode.lines, | ||||
|             numLines = lines.length + 1, | ||||
|             comments = sourceCode.getAllComments(), | ||||
|             commentLines = getCommentLineNums(comments), | ||||
|             emptyLines = getEmptyLineNums(lines), | ||||
|             commentAndEmptyLines = new Set(commentLines.concat(emptyLines)); | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are on lines starting with or ending with code | ||||
|          * @param {token} token The comment token to check. | ||||
|          * @returns {boolean} True if the comment is not alone. | ||||
|          */ | ||||
|         function codeAroundComment(token) { | ||||
|             let currentToken = token; | ||||
|  | ||||
|             do { | ||||
|                 currentToken = sourceCode.getTokenBefore(currentToken, { includeComments: true }); | ||||
|             } while (currentToken && astUtils.isCommentToken(currentToken)); | ||||
|  | ||||
|             if (currentToken && astUtils.isTokenOnSameLine(currentToken, token)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             currentToken = token; | ||||
|             do { | ||||
|                 currentToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); | ||||
|             } while (currentToken && astUtils.isCommentToken(currentToken)); | ||||
|  | ||||
|             if (currentToken && astUtils.isTokenOnSameLine(token, currentToken)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are inside a node type or not. | ||||
|          * @param {ASTNode} parent The Comment parent node. | ||||
|          * @param {string} nodeType The parent type to check against. | ||||
|          * @returns {boolean} True if the comment is inside nodeType. | ||||
|          */ | ||||
|         function isParentNodeType(parent, nodeType) { | ||||
|             return parent.type === nodeType || | ||||
|                 (parent.body && parent.body.type === nodeType) || | ||||
|                 (parent.consequent && parent.consequent.type === nodeType); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the parent node that contains the given token. | ||||
|          * @param {token} token The token to check. | ||||
|          * @returns {ASTNode|null} The parent node that contains the given token. | ||||
|          */ | ||||
|         function getParentNodeOfToken(token) { | ||||
|             const node = sourceCode.getNodeByRangeIndex(token.range[0]); | ||||
|  | ||||
|             /* | ||||
|              * For the purpose of this rule, the comment token is in a `StaticBlock` node only | ||||
|              * if it's inside the braces of that `StaticBlock` node. | ||||
|              * | ||||
|              * Example where this function returns `null`: | ||||
|              * | ||||
|              *   static | ||||
|              *   // comment | ||||
|              *   { | ||||
|              *   } | ||||
|              * | ||||
|              * Example where this function returns `StaticBlock` node: | ||||
|              * | ||||
|              *   static | ||||
|              *   { | ||||
|              *   // comment | ||||
|              *   } | ||||
|              * | ||||
|              */ | ||||
|             if (node && node.type === "StaticBlock") { | ||||
|                 const openingBrace = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token | ||||
|  | ||||
|                 return token.range[0] >= openingBrace.range[0] | ||||
|                     ? node | ||||
|                     : null; | ||||
|             } | ||||
|  | ||||
|             return node; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the parent start or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @param {string} nodeType The parent type to check against. | ||||
|          * @returns {boolean} True if the comment is at parent start. | ||||
|          */ | ||||
|         function isCommentAtParentStart(token, nodeType) { | ||||
|             const parent = getParentNodeOfToken(token); | ||||
|  | ||||
|             if (parent && isParentNodeType(parent, nodeType)) { | ||||
|                 let parentStartNodeOrToken = parent; | ||||
|  | ||||
|                 if (parent.type === "StaticBlock") { | ||||
|                     parentStartNodeOrToken = sourceCode.getFirstToken(parent, { skip: 1 }); // opening brace of the static block | ||||
|                 } else if (parent.type === "SwitchStatement") { | ||||
|                     parentStartNodeOrToken = sourceCode.getTokenAfter(parent.discriminant, { | ||||
|                         filter: astUtils.isOpeningBraceToken | ||||
|                     }); // opening brace of the switch statement | ||||
|                 } | ||||
|  | ||||
|                 return token.loc.start.line - parentStartNodeOrToken.loc.start.line === 1; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the parent end or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @param {string} nodeType The parent type to check against. | ||||
|          * @returns {boolean} True if the comment is at parent end. | ||||
|          */ | ||||
|         function isCommentAtParentEnd(token, nodeType) { | ||||
|             const parent = getParentNodeOfToken(token); | ||||
|  | ||||
|             return !!parent && isParentNodeType(parent, nodeType) && | ||||
|                     parent.loc.end.line - token.loc.end.line === 1; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the block start or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at block start. | ||||
|          */ | ||||
|         function isCommentAtBlockStart(token) { | ||||
|             return ( | ||||
|                 isCommentAtParentStart(token, "ClassBody") || | ||||
|                 isCommentAtParentStart(token, "BlockStatement") || | ||||
|                 isCommentAtParentStart(token, "StaticBlock") || | ||||
|                 isCommentAtParentStart(token, "SwitchCase") || | ||||
|                 isCommentAtParentStart(token, "SwitchStatement") | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the block end or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at block end. | ||||
|          */ | ||||
|         function isCommentAtBlockEnd(token) { | ||||
|             return ( | ||||
|                 isCommentAtParentEnd(token, "ClassBody") || | ||||
|                 isCommentAtParentEnd(token, "BlockStatement") || | ||||
|                 isCommentAtParentEnd(token, "StaticBlock") || | ||||
|                 isCommentAtParentEnd(token, "SwitchCase") || | ||||
|                 isCommentAtParentEnd(token, "SwitchStatement") | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the class start or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at class start. | ||||
|          */ | ||||
|         function isCommentAtClassStart(token) { | ||||
|             return isCommentAtParentStart(token, "ClassBody"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the class end or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at class end. | ||||
|          */ | ||||
|         function isCommentAtClassEnd(token) { | ||||
|             return isCommentAtParentEnd(token, "ClassBody"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the object start or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at object start. | ||||
|          */ | ||||
|         function isCommentAtObjectStart(token) { | ||||
|             return isCommentAtParentStart(token, "ObjectExpression") || isCommentAtParentStart(token, "ObjectPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the object end or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at object end. | ||||
|          */ | ||||
|         function isCommentAtObjectEnd(token) { | ||||
|             return isCommentAtParentEnd(token, "ObjectExpression") || isCommentAtParentEnd(token, "ObjectPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the array start or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at array start. | ||||
|          */ | ||||
|         function isCommentAtArrayStart(token) { | ||||
|             return isCommentAtParentStart(token, "ArrayExpression") || isCommentAtParentStart(token, "ArrayPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not comments are at the array end or not. | ||||
|          * @param {token} token The Comment token. | ||||
|          * @returns {boolean} True if the comment is at array end. | ||||
|          */ | ||||
|         function isCommentAtArrayEnd(token) { | ||||
|             return isCommentAtParentEnd(token, "ArrayExpression") || isCommentAtParentEnd(token, "ArrayPattern"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a comment token has lines around it (ignores inline comments) | ||||
|          * @param {token} token The Comment token. | ||||
|          * @param {Object} opts Options to determine the newline. | ||||
|          * @param {boolean} opts.after Should have a newline after this line. | ||||
|          * @param {boolean} opts.before Should have a newline before this line. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkForEmptyLine(token, opts) { | ||||
|             if (applyDefaultIgnorePatterns && defaultIgnoreRegExp.test(token.value)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (ignorePattern && customIgnoreRegExp.test(token.value)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             let after = opts.after, | ||||
|                 before = opts.before; | ||||
|  | ||||
|             const prevLineNum = token.loc.start.line - 1, | ||||
|                 nextLineNum = token.loc.end.line + 1, | ||||
|                 commentIsNotAlone = codeAroundComment(token); | ||||
|  | ||||
|             const blockStartAllowed = options.allowBlockStart && | ||||
|                     isCommentAtBlockStart(token) && | ||||
|                     !(options.allowClassStart === false && | ||||
|                     isCommentAtClassStart(token)), | ||||
|                 blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)), | ||||
|                 classStartAllowed = options.allowClassStart && isCommentAtClassStart(token), | ||||
|                 classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token), | ||||
|                 objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(token), | ||||
|                 objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(token), | ||||
|                 arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(token), | ||||
|                 arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(token); | ||||
|  | ||||
|             const exceptionStartAllowed = blockStartAllowed || classStartAllowed || objectStartAllowed || arrayStartAllowed; | ||||
|             const exceptionEndAllowed = blockEndAllowed || classEndAllowed || objectEndAllowed || arrayEndAllowed; | ||||
|  | ||||
|             // ignore top of the file and bottom of the file | ||||
|             if (prevLineNum < 1) { | ||||
|                 before = false; | ||||
|             } | ||||
|             if (nextLineNum >= numLines) { | ||||
|                 after = false; | ||||
|             } | ||||
|  | ||||
|             // we ignore all inline comments | ||||
|             if (commentIsNotAlone) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const previousTokenOrComment = sourceCode.getTokenBefore(token, { includeComments: true }); | ||||
|             const nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true }); | ||||
|  | ||||
|             // check for newline before | ||||
|             if (!exceptionStartAllowed && before && !commentAndEmptyLines.has(prevLineNum) && | ||||
|                     !(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) { | ||||
|                 const lineStart = token.range[0] - token.loc.start.column; | ||||
|                 const range = [lineStart, lineStart]; | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: token, | ||||
|                     messageId: "before", | ||||
|                     fix(fixer) { | ||||
|                         return fixer.insertTextBeforeRange(range, "\n"); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // check for newline after | ||||
|             if (!exceptionEndAllowed && after && !commentAndEmptyLines.has(nextLineNum) && | ||||
|                     !(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) { | ||||
|                 context.report({ | ||||
|                     node: token, | ||||
|                     messageId: "after", | ||||
|                     fix(fixer) { | ||||
|                         return fixer.insertTextAfter(token, "\n"); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program() { | ||||
|                 comments.forEach(token => { | ||||
|                     if (token.type === "Line") { | ||||
|                         if (options.beforeLineComment || options.afterLineComment) { | ||||
|                             checkForEmptyLine(token, { | ||||
|                                 after: options.afterLineComment, | ||||
|                                 before: options.beforeLineComment | ||||
|                             }); | ||||
|                         } | ||||
|                     } else if (token.type === "Block") { | ||||
|                         if (options.beforeBlockComment || options.afterBlockComment) { | ||||
|                             checkForEmptyLine(token, { | ||||
|                                 after: options.afterBlockComment, | ||||
|                                 before: options.beforeBlockComment | ||||
|                             }); | ||||
|                         } | ||||
|                     } else if (token.type === "Shebang") { | ||||
|                         if (options.afterHashbangComment) { | ||||
|                             checkForEmptyLine(token, { | ||||
|                                 after: options.afterHashbangComment, | ||||
|                                 before: false | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										201
									
								
								node_modules/eslint/lib/rules/lines-around-directive.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								node_modules/eslint/lib/rules/lines-around-directive.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,201 @@ | ||||
| /** | ||||
|  * @fileoverview Require or disallow newlines around directives. | ||||
|  * @author Kai Cataldo | ||||
|  * @deprecated in ESLint v4.0.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow newlines around directives", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/lines-around-directive" | ||||
|         }, | ||||
|  | ||||
|         schema: [{ | ||||
|             oneOf: [ | ||||
|                 { | ||||
|                     enum: ["always", "never"] | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "object", | ||||
|                     properties: { | ||||
|                         before: { | ||||
|                             enum: ["always", "never"] | ||||
|                         }, | ||||
|                         after: { | ||||
|                             enum: ["always", "never"] | ||||
|                         } | ||||
|                     }, | ||||
|                     additionalProperties: false, | ||||
|                     minProperties: 2 | ||||
|                 } | ||||
|             ] | ||||
|         }], | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|         messages: { | ||||
|             expected: "Expected newline {{location}} \"{{value}}\" directive.", | ||||
|             unexpected: "Unexpected newline {{location}} \"{{value}}\" directive." | ||||
|         }, | ||||
|         deprecated: true, | ||||
|         replacedBy: ["padding-line-between-statements"] | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const config = context.options[0] || "always"; | ||||
|         const expectLineBefore = typeof config === "string" ? config : config.before; | ||||
|         const expectLineAfter = typeof config === "string" ? config : config.after; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Check if node is preceded by a blank newline. | ||||
|          * @param {ASTNode} node Node to check. | ||||
|          * @returns {boolean} Whether or not the passed in node is preceded by a blank newline. | ||||
|          */ | ||||
|         function hasNewlineBefore(node) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true }); | ||||
|             const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; | ||||
|  | ||||
|             return node.loc.start.line - tokenLineBefore >= 2; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the last token of a node that is on the same line as the rest of the node. | ||||
|          * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing | ||||
|          * semicolon on a different line. | ||||
|          * @param {ASTNode} node A directive node | ||||
|          * @returns {Token} The last token of the node on the line | ||||
|          */ | ||||
|         function getLastTokenOnLine(node) { | ||||
|             const lastToken = sourceCode.getLastToken(node); | ||||
|             const secondToLastToken = sourceCode.getTokenBefore(lastToken); | ||||
|  | ||||
|             return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line | ||||
|                 ? secondToLastToken | ||||
|                 : lastToken; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if node is followed by a blank newline. | ||||
|          * @param {ASTNode} node Node to check. | ||||
|          * @returns {boolean} Whether or not the passed in node is followed by a blank newline. | ||||
|          */ | ||||
|         function hasNewlineAfter(node) { | ||||
|             const lastToken = getLastTokenOnLine(node); | ||||
|             const tokenAfter = sourceCode.getTokenAfter(lastToken, { includeComments: true }); | ||||
|  | ||||
|             return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Report errors for newlines around directives. | ||||
|          * @param {ASTNode} node Node to check. | ||||
|          * @param {string} location Whether the error was found before or after the directive. | ||||
|          * @param {boolean} expected Whether or not a newline was expected or unexpected. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportError(node, location, expected) { | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 messageId: expected ? "expected" : "unexpected", | ||||
|                 data: { | ||||
|                     value: node.expression.value, | ||||
|                     location | ||||
|                 }, | ||||
|                 fix(fixer) { | ||||
|                     const lastToken = getLastTokenOnLine(node); | ||||
|  | ||||
|                     if (expected) { | ||||
|                         return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); | ||||
|                     } | ||||
|                     return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check lines around directives in node | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkDirectives(node) { | ||||
|             const directives = astUtils.getDirectivePrologue(node); | ||||
|  | ||||
|             if (!directives.length) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const firstDirective = directives[0]; | ||||
|             const leadingComments = sourceCode.getCommentsBefore(firstDirective); | ||||
|  | ||||
|             /* | ||||
|              * Only check before the first directive if it is preceded by a comment or if it is at the top of | ||||
|              * the file and expectLineBefore is set to "never". This is to not force a newline at the top of | ||||
|              * the file if there are no comments as well as for compatibility with padded-blocks. | ||||
|              */ | ||||
|             if (leadingComments.length) { | ||||
|                 if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { | ||||
|                     reportError(firstDirective, "before", true); | ||||
|                 } | ||||
|  | ||||
|                 if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { | ||||
|                     reportError(firstDirective, "before", false); | ||||
|                 } | ||||
|             } else if ( | ||||
|                 node.type === "Program" && | ||||
|                 expectLineBefore === "never" && | ||||
|                 !leadingComments.length && | ||||
|                 hasNewlineBefore(firstDirective) | ||||
|             ) { | ||||
|                 reportError(firstDirective, "before", false); | ||||
|             } | ||||
|  | ||||
|             const lastDirective = directives[directives.length - 1]; | ||||
|             const statements = node.type === "Program" ? node.body : node.body.body; | ||||
|  | ||||
|             /* | ||||
|              * Do not check after the last directive if the body only | ||||
|              * contains a directive prologue and isn't followed by a comment to ensure | ||||
|              * this rule behaves well with padded-blocks. | ||||
|              */ | ||||
|             if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { | ||||
|                 reportError(lastDirective, "after", true); | ||||
|             } | ||||
|  | ||||
|             if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { | ||||
|                 reportError(lastDirective, "after", false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program: checkDirectives, | ||||
|             FunctionDeclaration: checkDirectives, | ||||
|             FunctionExpression: checkDirectives, | ||||
|             ArrowFunctionExpression: checkDirectives | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										269
									
								
								node_modules/eslint/lib/rules/lines-between-class-members.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								node_modules/eslint/lib/rules/lines-between-class-members.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,269 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to check empty newline between class members | ||||
|  * @author 薛定谔的猫<hh_2013@foxmail.com> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Types of class members. | ||||
|  * Those have `test` method to check it matches to the given class member. | ||||
|  * @private | ||||
|  */ | ||||
| const ClassMemberTypes = { | ||||
|     "*": { test: () => true }, | ||||
|     field: { test: node => node.type === "PropertyDefinition" }, | ||||
|     method: { test: node => node.type === "MethodDefinition" } | ||||
| }; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow an empty line between class members", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/lines-between-class-members" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 anyOf: [ | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             enforce: { | ||||
|                                 type: "array", | ||||
|                                 items: { | ||||
|                                     type: "object", | ||||
|                                     properties: { | ||||
|                                         blankLine: { enum: ["always", "never"] }, | ||||
|                                         prev: { enum: ["method", "field", "*"] }, | ||||
|                                         next: { enum: ["method", "field", "*"] } | ||||
|                                     }, | ||||
|                                     additionalProperties: false, | ||||
|                                     required: ["blankLine", "prev", "next"] | ||||
|                                 }, | ||||
|                                 minItems: 1 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false, | ||||
|                         required: ["enforce"] | ||||
|                     }, | ||||
|                     { | ||||
|                         enum: ["always", "never"] | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     exceptAfterSingleLine: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             never: "Unexpected blank line between class members.", | ||||
|             always: "Expected blank line between class members." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const options = []; | ||||
|  | ||||
|         options[0] = context.options[0] || "always"; | ||||
|         options[1] = context.options[1] || { exceptAfterSingleLine: false }; | ||||
|  | ||||
|         const configureList = typeof options[0] === "object" ? options[0].enforce : [{ blankLine: options[0], prev: "*", next: "*" }]; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Gets a pair of tokens that should be used to check lines between two class member nodes. | ||||
|          * | ||||
|          * In most cases, this returns the very last token of the current node and | ||||
|          * the very first token of the next node. | ||||
|          * For example: | ||||
|          * | ||||
|          *     class C { | ||||
|          *         x = 1;   // curLast: `;` nextFirst: `in` | ||||
|          *         in = 2 | ||||
|          *     } | ||||
|          * | ||||
|          * There is only one exception. If the given node ends with a semicolon, and it looks like | ||||
|          * a semicolon-less style's semicolon - one that is not on the same line as the preceding | ||||
|          * token, but is on the line where the next class member starts - this returns the preceding | ||||
|          * token and the semicolon as boundary tokens. | ||||
|          * For example: | ||||
|          * | ||||
|          *     class C { | ||||
|          *         x = 1    // curLast: `1` nextFirst: `;` | ||||
|          *         ;in = 2 | ||||
|          *     } | ||||
|          * When determining the desired layout of the code, we should treat this semicolon as | ||||
|          * a part of the next class member node instead of the one it technically belongs to. | ||||
|          * @param {ASTNode} curNode Current class member node. | ||||
|          * @param {ASTNode} nextNode Next class member node. | ||||
|          * @returns {Token} The actual last token of `node`. | ||||
|          * @private | ||||
|          */ | ||||
|         function getBoundaryTokens(curNode, nextNode) { | ||||
|             const lastToken = sourceCode.getLastToken(curNode); | ||||
|             const prevToken = sourceCode.getTokenBefore(lastToken); | ||||
|             const nextToken = sourceCode.getFirstToken(nextNode); // skip possible lone `;` between nodes | ||||
|  | ||||
|             const isSemicolonLessStyle = ( | ||||
|                 astUtils.isSemicolonToken(lastToken) && | ||||
|                 !astUtils.isTokenOnSameLine(prevToken, lastToken) && | ||||
|                 astUtils.isTokenOnSameLine(lastToken, nextToken) | ||||
|             ); | ||||
|  | ||||
|             return isSemicolonLessStyle | ||||
|                 ? { curLast: prevToken, nextFirst: lastToken } | ||||
|                 : { curLast: lastToken, nextFirst: nextToken }; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member. | ||||
|          * @param {Token} prevLastToken The last token in the previous member node. | ||||
|          * @param {Token} nextFirstToken The first token in the next member node. | ||||
|          * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. | ||||
|          * @returns {Token} The last token among the consecutive tokens. | ||||
|          */ | ||||
|         function findLastConsecutiveTokenAfter(prevLastToken, nextFirstToken, maxLine) { | ||||
|             const after = sourceCode.getTokenAfter(prevLastToken, { includeComments: true }); | ||||
|  | ||||
|             if (after !== nextFirstToken && after.loc.start.line - prevLastToken.loc.end.line <= maxLine) { | ||||
|                 return findLastConsecutiveTokenAfter(after, nextFirstToken, maxLine); | ||||
|             } | ||||
|             return prevLastToken; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member. | ||||
|          * @param {Token} nextFirstToken The first token in the next member node. | ||||
|          * @param {Token} prevLastToken The last token in the previous member node. | ||||
|          * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. | ||||
|          * @returns {Token} The first token among the consecutive tokens. | ||||
|          */ | ||||
|         function findFirstConsecutiveTokenBefore(nextFirstToken, prevLastToken, maxLine) { | ||||
|             const before = sourceCode.getTokenBefore(nextFirstToken, { includeComments: true }); | ||||
|  | ||||
|             if (before !== prevLastToken && nextFirstToken.loc.start.line - before.loc.end.line <= maxLine) { | ||||
|                 return findFirstConsecutiveTokenBefore(before, prevLastToken, maxLine); | ||||
|             } | ||||
|             return nextFirstToken; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if there is a token or comment between two tokens. | ||||
|          * @param {Token} before The token before. | ||||
|          * @param {Token} after The token after. | ||||
|          * @returns {boolean} True if there is a token or comment between two tokens. | ||||
|          */ | ||||
|         function hasTokenOrCommentBetween(before, after) { | ||||
|             return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given node matches the given type. | ||||
|          * @param {ASTNode} node The class member node to check. | ||||
|          * @param {string} type The class member type to check. | ||||
|          * @returns {boolean} `true` if the class member node matched the type. | ||||
|          * @private | ||||
|          */ | ||||
|         function match(node, type) { | ||||
|             return ClassMemberTypes[type].test(node); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Finds the last matched configuration from the configureList. | ||||
|          * @param {ASTNode} prevNode The previous node to match. | ||||
|          * @param {ASTNode} nextNode The current node to match. | ||||
|          * @returns {string|null} Padding type or `null` if no matches were found. | ||||
|          * @private | ||||
|          */ | ||||
|         function getPaddingType(prevNode, nextNode) { | ||||
|             for (let i = configureList.length - 1; i >= 0; --i) { | ||||
|                 const configure = configureList[i]; | ||||
|                 const matched = | ||||
|                     match(prevNode, configure.prev) && | ||||
|                     match(nextNode, configure.next); | ||||
|  | ||||
|                 if (matched) { | ||||
|                     return configure.blankLine; | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ClassBody(node) { | ||||
|                 const body = node.body; | ||||
|  | ||||
|                 for (let i = 0; i < body.length - 1; i++) { | ||||
|                     const curFirst = sourceCode.getFirstToken(body[i]); | ||||
|                     const { curLast, nextFirst } = getBoundaryTokens(body[i], body[i + 1]); | ||||
|                     const isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast); | ||||
|                     const skip = !isMulti && options[1].exceptAfterSingleLine; | ||||
|                     const beforePadding = findLastConsecutiveTokenAfter(curLast, nextFirst, 1); | ||||
|                     const afterPadding = findFirstConsecutiveTokenBefore(nextFirst, curLast, 1); | ||||
|                     const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1; | ||||
|                     const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding); | ||||
|                     const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0); | ||||
|                     const paddingType = getPaddingType(body[i], body[i + 1]); | ||||
|  | ||||
|                     if (paddingType === "never" && isPadded) { | ||||
|                         context.report({ | ||||
|                             node: body[i + 1], | ||||
|                             messageId: "never", | ||||
|  | ||||
|                             fix(fixer) { | ||||
|                                 if (hasTokenInPadding) { | ||||
|                                     return null; | ||||
|                                 } | ||||
|                                 return fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n"); | ||||
|                             } | ||||
|                         }); | ||||
|                     } else if (paddingType === "always" && !skip && !isPadded) { | ||||
|                         context.report({ | ||||
|                             node: body[i + 1], | ||||
|                             messageId: "always", | ||||
|  | ||||
|                             fix(fixer) { | ||||
|                                 if (hasTokenInPadding) { | ||||
|                                     return null; | ||||
|                                 } | ||||
|                                 return fixer.insertTextAfter(curLineLastToken, "\n"); | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										504
									
								
								node_modules/eslint/lib/rules/logical-assignment-operators.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										504
									
								
								node_modules/eslint/lib/rules/logical-assignment-operators.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,504 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to replace assignment expressions with logical operator assignment | ||||
|  * @author Daniel Martens | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
| const astUtils = require("./utils/ast-utils.js"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const baseTypes = new Set(["Identifier", "Super", "ThisExpression"]); | ||||
|  | ||||
| /** | ||||
|  * Returns true iff either "undefined" or a void expression (eg. "void 0") | ||||
|  * @param {ASTNode} expression Expression to check | ||||
|  * @param {import('eslint-scope').Scope} scope Scope of the expression | ||||
|  * @returns {boolean} True iff "undefined" or "void ..." | ||||
|  */ | ||||
| function isUndefined(expression, scope) { | ||||
|     if (expression.type === "Identifier" && expression.name === "undefined") { | ||||
|         return astUtils.isReferenceToGlobalVariable(scope, expression); | ||||
|     } | ||||
|  | ||||
|     return expression.type === "UnaryExpression" && | ||||
|            expression.operator === "void" && | ||||
|            expression.argument.type === "Literal" && | ||||
|            expression.argument.value === 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true iff the reference is either an identifier or member expression | ||||
|  * @param {ASTNode} expression Expression to check | ||||
|  * @returns {boolean} True for identifiers and member expressions | ||||
|  */ | ||||
| function isReference(expression) { | ||||
|     return (expression.type === "Identifier" && expression.name !== "undefined") || | ||||
|            expression.type === "MemberExpression"; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true iff the expression checks for nullish with loose equals. | ||||
|  * Examples: value == null, value == void 0 | ||||
|  * @param {ASTNode} expression Test condition | ||||
|  * @param {import('eslint-scope').Scope} scope Scope of the expression | ||||
|  * @returns {boolean} True iff implicit nullish comparison | ||||
|  */ | ||||
| function isImplicitNullishComparison(expression, scope) { | ||||
|     if (expression.type !== "BinaryExpression" || expression.operator !== "==") { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     const reference = isReference(expression.left) ? "left" : "right"; | ||||
|     const nullish = reference === "left" ? "right" : "left"; | ||||
|  | ||||
|     return isReference(expression[reference]) && | ||||
|            (astUtils.isNullLiteral(expression[nullish]) || isUndefined(expression[nullish], scope)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Condition with two equal comparisons. | ||||
|  * @param {ASTNode} expression Condition | ||||
|  * @returns {boolean} True iff matches ? === ? || ? === ? | ||||
|  */ | ||||
| function isDoubleComparison(expression) { | ||||
|     return expression.type === "LogicalExpression" && | ||||
|            expression.operator === "||" && | ||||
|            expression.left.type === "BinaryExpression" && | ||||
|            expression.left.operator === "===" && | ||||
|            expression.right.type === "BinaryExpression" && | ||||
|            expression.right.operator === "==="; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true iff the expression checks for undefined and null. | ||||
|  * Example: value === null || value === undefined | ||||
|  * @param {ASTNode} expression Test condition | ||||
|  * @param {import('eslint-scope').Scope} scope Scope of the expression | ||||
|  * @returns {boolean} True iff explicit nullish comparison | ||||
|  */ | ||||
| function isExplicitNullishComparison(expression, scope) { | ||||
|     if (!isDoubleComparison(expression)) { | ||||
|         return false; | ||||
|     } | ||||
|     const leftReference = isReference(expression.left.left) ? "left" : "right"; | ||||
|     const leftNullish = leftReference === "left" ? "right" : "left"; | ||||
|     const rightReference = isReference(expression.right.left) ? "left" : "right"; | ||||
|     const rightNullish = rightReference === "left" ? "right" : "left"; | ||||
|  | ||||
|     return astUtils.isSameReference(expression.left[leftReference], expression.right[rightReference]) && | ||||
|            ((astUtils.isNullLiteral(expression.left[leftNullish]) && isUndefined(expression.right[rightNullish], scope)) || | ||||
|            (isUndefined(expression.left[leftNullish], scope) && astUtils.isNullLiteral(expression.right[rightNullish]))); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true for Boolean(arg) calls | ||||
|  * @param {ASTNode} expression Test condition | ||||
|  * @param {import('eslint-scope').Scope} scope Scope of the expression | ||||
|  * @returns {boolean} Whether the expression is a boolean cast | ||||
|  */ | ||||
| function isBooleanCast(expression, scope) { | ||||
|     return expression.type === "CallExpression" && | ||||
|            expression.callee.name === "Boolean" && | ||||
|            expression.arguments.length === 1 && | ||||
|            astUtils.isReferenceToGlobalVariable(scope, expression.callee); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true for: | ||||
|  * truthiness checks:  value, Boolean(value), !!value | ||||
|  * falsiness checks:   !value, !Boolean(value) | ||||
|  * nullish checks:     value == null, value === undefined || value === null | ||||
|  * @param {ASTNode} expression Test condition | ||||
|  * @param {import('eslint-scope').Scope} scope Scope of the expression | ||||
|  * @returns {?{ reference: ASTNode, operator: '??'|'||'|'&&'}} Null if not a known existence | ||||
|  */ | ||||
| function getExistence(expression, scope) { | ||||
|     const isNegated = expression.type === "UnaryExpression" && expression.operator === "!"; | ||||
|     const base = isNegated ? expression.argument : expression; | ||||
|  | ||||
|     switch (true) { | ||||
|         case isReference(base): | ||||
|             return { reference: base, operator: isNegated ? "||" : "&&" }; | ||||
|         case base.type === "UnaryExpression" && base.operator === "!" && isReference(base.argument): | ||||
|             return { reference: base.argument, operator: "&&" }; | ||||
|         case isBooleanCast(base, scope) && isReference(base.arguments[0]): | ||||
|             return { reference: base.arguments[0], operator: isNegated ? "||" : "&&" }; | ||||
|         case isImplicitNullishComparison(expression, scope): | ||||
|             return { reference: isReference(expression.left) ? expression.left : expression.right, operator: "??" }; | ||||
|         case isExplicitNullishComparison(expression, scope): | ||||
|             return { reference: isReference(expression.left.left) ? expression.left.left : expression.left.right, operator: "??" }; | ||||
|         default: return null; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Returns true iff the node is inside a with block | ||||
|  * @param {ASTNode} node Node to check | ||||
|  * @returns {boolean} True iff passed node is inside a with block | ||||
|  */ | ||||
| function isInsideWithBlock(node) { | ||||
|     if (node.type === "Program") { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     return node.parent.type === "WithStatement" && node.parent.body === node ? true : isInsideWithBlock(node.parent); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Gets the leftmost operand of a consecutive logical expression. | ||||
|  * @param {SourceCode} sourceCode The ESLint source code object | ||||
|  * @param {LogicalExpression} node LogicalExpression | ||||
|  * @returns {Expression} Leftmost operand | ||||
|  */ | ||||
| function getLeftmostOperand(sourceCode, node) { | ||||
|     let left = node.left; | ||||
|  | ||||
|     while (left.type === "LogicalExpression" && left.operator === node.operator) { | ||||
|  | ||||
|         if (astUtils.isParenthesised(sourceCode, left)) { | ||||
|  | ||||
|             /* | ||||
|              * It should have associativity, | ||||
|              * but ignore it if use parentheses to make the evaluation order clear. | ||||
|              */ | ||||
|             return left; | ||||
|         } | ||||
|         left = left.left; | ||||
|     } | ||||
|     return left; | ||||
|  | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow logical assignment operator shorthand", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/logical-assignment-operators" | ||||
|         }, | ||||
|  | ||||
|         schema: { | ||||
|             type: "array", | ||||
|             oneOf: [{ | ||||
|                 items: [ | ||||
|                     { const: "always" }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             enforceForIfStatements: { | ||||
|                                 type: "boolean" | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ], | ||||
|                 minItems: 0, // 0 for allowing passing no options | ||||
|                 maxItems: 2 | ||||
|             }, { | ||||
|                 items: [{ const: "never" }], | ||||
|                 minItems: 1, | ||||
|                 maxItems: 1 | ||||
|             }] | ||||
|         }, | ||||
|         fixable: "code", | ||||
|         hasSuggestions: true, | ||||
|         messages: { | ||||
|             assignment: "Assignment (=) can be replaced with operator assignment ({{operator}}).", | ||||
|             useLogicalOperator: "Convert this assignment to use the operator {{ operator }}.", | ||||
|             logical: "Logical expression can be replaced with an assignment ({{ operator }}).", | ||||
|             convertLogical: "Replace this logical expression with an assignment with the operator {{ operator }}.", | ||||
|             if: "'if' statement can be replaced with a logical operator assignment with operator {{ operator }}.", | ||||
|             convertIf: "Replace this 'if' statement with a logical assignment with operator {{ operator }}.", | ||||
|             unexpected: "Unexpected logical operator assignment ({{operator}}) shorthand.", | ||||
|             separate: "Separate the logical assignment into an assignment with a logical operator." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const mode = context.options[0] === "never" ? "never" : "always"; | ||||
|         const checkIf = mode === "always" && context.options.length > 1 && context.options[1].enforceForIfStatements; | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const isStrict = sourceCode.getScope(sourceCode.ast).isStrict; | ||||
|  | ||||
|         /** | ||||
|          * Returns false if the access could be a getter | ||||
|          * @param {ASTNode} node Assignment expression | ||||
|          * @returns {boolean} True iff the fix is safe | ||||
|          */ | ||||
|         function cannotBeGetter(node) { | ||||
|             return node.type === "Identifier" && | ||||
|                    (isStrict || !isInsideWithBlock(node)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check whether only a single property is accessed | ||||
|          * @param {ASTNode} node reference | ||||
|          * @returns {boolean} True iff a single property is accessed | ||||
|          */ | ||||
|         function accessesSingleProperty(node) { | ||||
|             if (!isStrict && isInsideWithBlock(node)) { | ||||
|                 return node.type === "Identifier"; | ||||
|             } | ||||
|  | ||||
|             return node.type === "MemberExpression" && | ||||
|                    baseTypes.has(node.object.type) && | ||||
|                    (!node.computed || (node.property.type !== "MemberExpression" && node.property.type !== "ChainExpression")); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Adds a fixer or suggestion whether on the fix is safe. | ||||
|          * @param {{ messageId: string, node: ASTNode }} descriptor Report descriptor without fix or suggest | ||||
|          * @param {{ messageId: string, fix: Function }} suggestion Adds the fix or the whole suggestion as only element in "suggest" to suggestion | ||||
|          * @param {boolean} shouldBeFixed Fix iff the condition is true | ||||
|          * @returns {Object} Descriptor with either an added fix or suggestion | ||||
|          */ | ||||
|         function createConditionalFixer(descriptor, suggestion, shouldBeFixed) { | ||||
|             if (shouldBeFixed) { | ||||
|                 return { | ||||
|                     ...descriptor, | ||||
|                     fix: suggestion.fix | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 ...descriptor, | ||||
|                 suggest: [suggestion] | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * Returns the operator token for assignments and binary expressions | ||||
|          * @param {ASTNode} node AssignmentExpression or BinaryExpression | ||||
|          * @returns {import('eslint').AST.Token} Operator token between the left and right expression | ||||
|          */ | ||||
|         function getOperatorToken(node) { | ||||
|             return sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); | ||||
|         } | ||||
|  | ||||
|         if (mode === "never") { | ||||
|             return { | ||||
|  | ||||
|                 // foo ||= bar | ||||
|                 "AssignmentExpression"(assignment) { | ||||
|                     if (!astUtils.isLogicalAssignmentOperator(assignment.operator)) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     const descriptor = { | ||||
|                         messageId: "unexpected", | ||||
|                         node: assignment, | ||||
|                         data: { operator: assignment.operator } | ||||
|                     }; | ||||
|                     const suggestion = { | ||||
|                         messageId: "separate", | ||||
|                         *fix(ruleFixer) { | ||||
|                             if (sourceCode.getCommentsInside(assignment).length > 0) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             const operatorToken = getOperatorToken(assignment); | ||||
|  | ||||
|                             // -> foo = bar | ||||
|                             yield ruleFixer.replaceText(operatorToken, "="); | ||||
|  | ||||
|                             const assignmentText = sourceCode.getText(assignment.left); | ||||
|                             const operator = assignment.operator.slice(0, -1); | ||||
|  | ||||
|                             // -> foo = foo || bar | ||||
|                             yield ruleFixer.insertTextAfter(operatorToken, ` ${assignmentText} ${operator}`); | ||||
|  | ||||
|                             const precedence = astUtils.getPrecedence(assignment.right) <= astUtils.getPrecedence({ type: "LogicalExpression", operator }); | ||||
|  | ||||
|                             // ?? and || / && cannot be mixed but have same precedence | ||||
|                             const mixed = assignment.operator === "??=" && astUtils.isLogicalExpression(assignment.right); | ||||
|  | ||||
|                             if (!astUtils.isParenthesised(sourceCode, assignment.right) && (precedence || mixed)) { | ||||
|  | ||||
|                                 // -> foo = foo || (bar) | ||||
|                                 yield ruleFixer.insertTextBefore(assignment.right, "("); | ||||
|                                 yield ruleFixer.insertTextAfter(assignment.right, ")"); | ||||
|                             } | ||||
|                         } | ||||
|                     }; | ||||
|  | ||||
|                     context.report(createConditionalFixer(descriptor, suggestion, cannotBeGetter(assignment.left))); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             // foo = foo || bar | ||||
|             "AssignmentExpression[operator='='][right.type='LogicalExpression']"(assignment) { | ||||
|                 const leftOperand = getLeftmostOperand(sourceCode, assignment.right); | ||||
|  | ||||
|                 if (!astUtils.isSameReference(assignment.left, leftOperand) | ||||
|                 ) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const descriptor = { | ||||
|                     messageId: "assignment", | ||||
|                     node: assignment, | ||||
|                     data: { operator: `${assignment.right.operator}=` } | ||||
|                 }; | ||||
|                 const suggestion = { | ||||
|                     messageId: "useLogicalOperator", | ||||
|                     data: { operator: `${assignment.right.operator}=` }, | ||||
|                     *fix(ruleFixer) { | ||||
|                         if (sourceCode.getCommentsInside(assignment).length > 0) { | ||||
|                             return; | ||||
|                         } | ||||
|  | ||||
|                         // No need for parenthesis around the assignment based on precedence as the precedence stays the same even with changed operator | ||||
|                         const assignmentOperatorToken = getOperatorToken(assignment); | ||||
|  | ||||
|                         // -> foo ||= foo || bar | ||||
|                         yield ruleFixer.insertTextBefore(assignmentOperatorToken, assignment.right.operator); | ||||
|  | ||||
|                         // -> foo ||= bar | ||||
|                         const logicalOperatorToken = getOperatorToken(leftOperand.parent); | ||||
|                         const firstRightOperandToken = sourceCode.getTokenAfter(logicalOperatorToken); | ||||
|  | ||||
|                         yield ruleFixer.removeRange([leftOperand.parent.range[0], firstRightOperandToken.range[0]]); | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 context.report(createConditionalFixer(descriptor, suggestion, cannotBeGetter(assignment.left))); | ||||
|             }, | ||||
|  | ||||
|             // foo || (foo = bar) | ||||
|             'LogicalExpression[right.type="AssignmentExpression"][right.operator="="]'(logical) { | ||||
|  | ||||
|                 // Right side has to be parenthesized, otherwise would be parsed as (foo || foo) = bar which is illegal | ||||
|                 if (isReference(logical.left) && astUtils.isSameReference(logical.left, logical.right.left)) { | ||||
|                     const descriptor = { | ||||
|                         messageId: "logical", | ||||
|                         node: logical, | ||||
|                         data: { operator: `${logical.operator}=` } | ||||
|                     }; | ||||
|                     const suggestion = { | ||||
|                         messageId: "convertLogical", | ||||
|                         data: { operator: `${logical.operator}=` }, | ||||
|                         *fix(ruleFixer) { | ||||
|                             if (sourceCode.getCommentsInside(logical).length > 0) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             const parentPrecedence = astUtils.getPrecedence(logical.parent); | ||||
|                             const requiresOuterParenthesis = logical.parent.type !== "ExpressionStatement" && ( | ||||
|                                 parentPrecedence === -1 || | ||||
|                                 astUtils.getPrecedence({ type: "AssignmentExpression" }) < parentPrecedence | ||||
|                             ); | ||||
|  | ||||
|                             if (!astUtils.isParenthesised(sourceCode, logical) && requiresOuterParenthesis) { | ||||
|                                 yield ruleFixer.insertTextBefore(logical, "("); | ||||
|                                 yield ruleFixer.insertTextAfter(logical, ")"); | ||||
|                             } | ||||
|  | ||||
|                             // Also removes all opening parenthesis | ||||
|                             yield ruleFixer.removeRange([logical.range[0], logical.right.range[0]]); // -> foo = bar) | ||||
|  | ||||
|                             // Also removes all ending parenthesis | ||||
|                             yield ruleFixer.removeRange([logical.right.range[1], logical.range[1]]); // -> foo = bar | ||||
|  | ||||
|                             const operatorToken = getOperatorToken(logical.right); | ||||
|  | ||||
|                             yield ruleFixer.insertTextBefore(operatorToken, logical.operator); // -> foo ||= bar | ||||
|                         } | ||||
|                     }; | ||||
|                     const fix = cannotBeGetter(logical.left) || accessesSingleProperty(logical.left); | ||||
|  | ||||
|                     context.report(createConditionalFixer(descriptor, suggestion, fix)); | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             // if (foo) foo = bar | ||||
|             "IfStatement[alternate=null]"(ifNode) { | ||||
|                 if (!checkIf) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const hasBody = ifNode.consequent.type === "BlockStatement"; | ||||
|  | ||||
|                 if (hasBody && ifNode.consequent.body.length !== 1) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const body = hasBody ? ifNode.consequent.body[0] : ifNode.consequent; | ||||
|                 const scope = sourceCode.getScope(ifNode); | ||||
|                 const existence = getExistence(ifNode.test, scope); | ||||
|  | ||||
|                 if ( | ||||
|                     body.type === "ExpressionStatement" && | ||||
|                     body.expression.type === "AssignmentExpression" && | ||||
|                     body.expression.operator === "=" && | ||||
|                     existence !== null && | ||||
|                     astUtils.isSameReference(existence.reference, body.expression.left) | ||||
|                 ) { | ||||
|                     const descriptor = { | ||||
|                         messageId: "if", | ||||
|                         node: ifNode, | ||||
|                         data: { operator: `${existence.operator}=` } | ||||
|                     }; | ||||
|                     const suggestion = { | ||||
|                         messageId: "convertIf", | ||||
|                         data: { operator: `${existence.operator}=` }, | ||||
|                         *fix(ruleFixer) { | ||||
|                             if (sourceCode.getCommentsInside(ifNode).length > 0) { | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|                             const firstBodyToken = sourceCode.getFirstToken(body); | ||||
|                             const prevToken = sourceCode.getTokenBefore(ifNode); | ||||
|  | ||||
|                             if ( | ||||
|                                 prevToken !== null && | ||||
|                                 prevToken.value !== ";" && | ||||
|                                 prevToken.value !== "{" && | ||||
|                                 firstBodyToken.type !== "Identifier" && | ||||
|                                 firstBodyToken.type !== "Keyword" | ||||
|                             ) { | ||||
|  | ||||
|                                 // Do not fix if the fixed statement could be part of the previous statement (eg. fn() if (a == null) (a) = b --> fn()(a) ??= b) | ||||
|                                 return; | ||||
|                             } | ||||
|  | ||||
|  | ||||
|                             const operatorToken = getOperatorToken(body.expression); | ||||
|  | ||||
|                             yield ruleFixer.insertTextBefore(operatorToken, existence.operator); // -> if (foo) foo ||= bar | ||||
|  | ||||
|                             yield ruleFixer.removeRange([ifNode.range[0], body.range[0]]); // -> foo ||= bar | ||||
|  | ||||
|                             yield ruleFixer.removeRange([body.range[1], ifNode.range[1]]); // -> foo ||= bar, only present if "if" had a body | ||||
|  | ||||
|                             const nextToken = sourceCode.getTokenAfter(body.expression); | ||||
|  | ||||
|                             if (hasBody && (nextToken !== null && nextToken.value !== ";")) { | ||||
|                                 yield ruleFixer.insertTextAfter(ifNode, ";"); | ||||
|                             } | ||||
|                         } | ||||
|                     }; | ||||
|                     const shouldBeFixed = cannotBeGetter(existence.reference) || | ||||
|                                           (ifNode.test.type !== "LogicalExpression" && accessesSingleProperty(existence.reference)); | ||||
|  | ||||
|                     context.report(createConditionalFixer(descriptor, suggestion, shouldBeFixed)); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										89
									
								
								node_modules/eslint/lib/rules/max-classes-per-file.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								node_modules/eslint/lib/rules/max-classes-per-file.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| /** | ||||
|  * @fileoverview Enforce a maximum number of classes per file | ||||
|  * @author James Garbutt <https://github.com/43081j> | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of classes per file", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-classes-per-file" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 1 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             ignoreExpressions: { | ||||
|                                 type: "boolean" | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 1 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             maximumExceeded: "File has too many classes ({{ classCount }}). Maximum allowed is {{ max }}." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|         const [option = {}] = context.options; | ||||
|         const [ignoreExpressions, max] = typeof option === "number" | ||||
|             ? [false, option || 1] | ||||
|             : [option.ignoreExpressions, option.max || 1]; | ||||
|  | ||||
|         let classCount = 0; | ||||
|  | ||||
|         return { | ||||
|             Program() { | ||||
|                 classCount = 0; | ||||
|             }, | ||||
|             "Program:exit"(node) { | ||||
|                 if (classCount > max) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: "maximumExceeded", | ||||
|                         data: { | ||||
|                             classCount, | ||||
|                             max | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             "ClassDeclaration"() { | ||||
|                 classCount++; | ||||
|             }, | ||||
|             "ClassExpression"() { | ||||
|                 if (!ignoreExpressions) { | ||||
|                     classCount++; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										156
									
								
								node_modules/eslint/lib/rules/max-depth.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								node_modules/eslint/lib/rules/max-depth.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to set the maximum depth block can be nested in a function. | ||||
|  * @author Ian Christian Myers | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum depth that blocks can be nested", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-depth" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             maximum: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             tooDeeply: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const functionStack = [], | ||||
|             option = context.options[0]; | ||||
|         let maxDepth = 4; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) | ||||
|         ) { | ||||
|             maxDepth = option.maximum || option.max; | ||||
|         } | ||||
|         if (typeof option === "number") { | ||||
|             maxDepth = option; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * When parsing a new function, store it in our function stack | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function startFunction() { | ||||
|             functionStack.push(0); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * When parsing is done then pop out the reference | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function endFunction() { | ||||
|             functionStack.pop(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Save the block and Evaluate the node | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function pushBlock(node) { | ||||
|             const len = ++functionStack[functionStack.length - 1]; | ||||
|  | ||||
|             if (len > maxDepth) { | ||||
|                 context.report({ node, messageId: "tooDeeply", data: { depth: len, maxDepth } }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Pop the saved block | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function popBlock() { | ||||
|             functionStack[functionStack.length - 1]--; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program: startFunction, | ||||
|             FunctionDeclaration: startFunction, | ||||
|             FunctionExpression: startFunction, | ||||
|             ArrowFunctionExpression: startFunction, | ||||
|             StaticBlock: startFunction, | ||||
|  | ||||
|             IfStatement(node) { | ||||
|                 if (node.parent.type !== "IfStatement") { | ||||
|                     pushBlock(node); | ||||
|                 } | ||||
|             }, | ||||
|             SwitchStatement: pushBlock, | ||||
|             TryStatement: pushBlock, | ||||
|             DoWhileStatement: pushBlock, | ||||
|             WhileStatement: pushBlock, | ||||
|             WithStatement: pushBlock, | ||||
|             ForStatement: pushBlock, | ||||
|             ForInStatement: pushBlock, | ||||
|             ForOfStatement: pushBlock, | ||||
|  | ||||
|             "IfStatement:exit": popBlock, | ||||
|             "SwitchStatement:exit": popBlock, | ||||
|             "TryStatement:exit": popBlock, | ||||
|             "DoWhileStatement:exit": popBlock, | ||||
|             "WhileStatement:exit": popBlock, | ||||
|             "WithStatement:exit": popBlock, | ||||
|             "ForStatement:exit": popBlock, | ||||
|             "ForInStatement:exit": popBlock, | ||||
|             "ForOfStatement:exit": popBlock, | ||||
|  | ||||
|             "FunctionDeclaration:exit": endFunction, | ||||
|             "FunctionExpression:exit": endFunction, | ||||
|             "ArrowFunctionExpression:exit": endFunction, | ||||
|             "StaticBlock:exit": endFunction, | ||||
|             "Program:exit": endFunction | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										440
									
								
								node_modules/eslint/lib/rules/max-len.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								node_modules/eslint/lib/rules/max-len.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,440 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to check for max length on a line. | ||||
|  * @author Matt DuVall <http://www.mattduvall.com> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Constants | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const OPTIONS_SCHEMA = { | ||||
|     type: "object", | ||||
|     properties: { | ||||
|         code: { | ||||
|             type: "integer", | ||||
|             minimum: 0 | ||||
|         }, | ||||
|         comments: { | ||||
|             type: "integer", | ||||
|             minimum: 0 | ||||
|         }, | ||||
|         tabWidth: { | ||||
|             type: "integer", | ||||
|             minimum: 0 | ||||
|         }, | ||||
|         ignorePattern: { | ||||
|             type: "string" | ||||
|         }, | ||||
|         ignoreComments: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreStrings: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreUrls: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreTemplateLiterals: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreRegExpLiterals: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         ignoreTrailingComments: { | ||||
|             type: "boolean" | ||||
|         } | ||||
|     }, | ||||
|     additionalProperties: false | ||||
| }; | ||||
|  | ||||
| const OPTIONS_OR_INTEGER_SCHEMA = { | ||||
|     anyOf: [ | ||||
|         OPTIONS_SCHEMA, | ||||
|         { | ||||
|             type: "integer", | ||||
|             minimum: 0 | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum line length", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-len" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             OPTIONS_OR_INTEGER_SCHEMA, | ||||
|             OPTIONS_OR_INTEGER_SCHEMA, | ||||
|             OPTIONS_SCHEMA | ||||
|         ], | ||||
|         messages: { | ||||
|             max: "This line has a length of {{lineLength}}. Maximum allowed is {{maxLength}}.", | ||||
|             maxComment: "This line has a comment length of {{lineLength}}. Maximum allowed is {{maxCommentLength}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /* | ||||
|          * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: | ||||
|          * - They're matching an entire string that we know is a URI | ||||
|          * - We're matching part of a string where we think there *might* be a URL | ||||
|          * - We're only concerned about URLs, as picking out any URI would cause | ||||
|          *   too many false positives | ||||
|          * - We don't care about matching the entire URL, any small segment is fine | ||||
|          */ | ||||
|         const URL_REGEXP = /[^:/?#]:\/\/[^?#]/u; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Computes the length of a line that may contain tabs. The width of each | ||||
|          * tab will be the number of spaces to the next tab stop. | ||||
|          * @param {string} line The line. | ||||
|          * @param {int} tabWidth The width of each tab stop in spaces. | ||||
|          * @returns {int} The computed line length. | ||||
|          * @private | ||||
|          */ | ||||
|         function computeLineLength(line, tabWidth) { | ||||
|             let extraCharacterCount = 0; | ||||
|  | ||||
|             line.replace(/\t/gu, (match, offset) => { | ||||
|                 const totalOffset = offset + extraCharacterCount, | ||||
|                     previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, | ||||
|                     spaceCount = tabWidth - previousTabStopOffset; | ||||
|  | ||||
|                 extraCharacterCount += spaceCount - 1; // -1 for the replaced tab | ||||
|             }); | ||||
|             return Array.from(line).length + extraCharacterCount; | ||||
|         } | ||||
|  | ||||
|         // The options object must be the last option specified… | ||||
|         const options = Object.assign({}, context.options[context.options.length - 1]); | ||||
|  | ||||
|         // …but max code length… | ||||
|         if (typeof context.options[0] === "number") { | ||||
|             options.code = context.options[0]; | ||||
|         } | ||||
|  | ||||
|         // …and tabWidth can be optionally specified directly as integers. | ||||
|         if (typeof context.options[1] === "number") { | ||||
|             options.tabWidth = context.options[1]; | ||||
|         } | ||||
|  | ||||
|         const maxLength = typeof options.code === "number" ? options.code : 80, | ||||
|             tabWidth = typeof options.tabWidth === "number" ? options.tabWidth : 4, | ||||
|             ignoreComments = !!options.ignoreComments, | ||||
|             ignoreStrings = !!options.ignoreStrings, | ||||
|             ignoreTemplateLiterals = !!options.ignoreTemplateLiterals, | ||||
|             ignoreRegExpLiterals = !!options.ignoreRegExpLiterals, | ||||
|             ignoreTrailingComments = !!options.ignoreTrailingComments || !!options.ignoreComments, | ||||
|             ignoreUrls = !!options.ignoreUrls, | ||||
|             maxCommentLength = options.comments; | ||||
|         let ignorePattern = options.ignorePattern || null; | ||||
|  | ||||
|         if (ignorePattern) { | ||||
|             ignorePattern = new RegExp(ignorePattern, "u"); | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Tells if a given comment is trailing: it starts on the current line and | ||||
|          * extends to or past the end of the current line. | ||||
|          * @param {string} line The source line we want to check for a trailing comment on | ||||
|          * @param {number} lineNumber The one-indexed line number for line | ||||
|          * @param {ASTNode} comment The comment to inspect | ||||
|          * @returns {boolean} If the comment is trailing on the given line | ||||
|          */ | ||||
|         function isTrailingComment(line, lineNumber, comment) { | ||||
|             return comment && | ||||
|                 (comment.loc.start.line === lineNumber && lineNumber <= comment.loc.end.line) && | ||||
|                 (comment.loc.end.line > lineNumber || comment.loc.end.column === line.length); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Tells if a comment encompasses the entire line. | ||||
|          * @param {string} line The source line with a trailing comment | ||||
|          * @param {number} lineNumber The one-indexed line number this is on | ||||
|          * @param {ASTNode} comment The comment to remove | ||||
|          * @returns {boolean} If the comment covers the entire line | ||||
|          */ | ||||
|         function isFullLineComment(line, lineNumber, comment) { | ||||
|             const start = comment.loc.start, | ||||
|                 end = comment.loc.end, | ||||
|                 isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); | ||||
|  | ||||
|             return comment && | ||||
|                 (start.line < lineNumber || (start.line === lineNumber && isFirstTokenOnLine)) && | ||||
|                 (end.line > lineNumber || (end.line === lineNumber && end.column === line.length)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if a node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {boolean} True if the node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. | ||||
|          */ | ||||
|         function isJSXEmptyExpressionInSingleLineContainer(node) { | ||||
|             if (!node || !node.parent || node.type !== "JSXEmptyExpression" || node.parent.type !== "JSXExpressionContainer") { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             return parent.loc.start.line === parent.loc.end.line; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the line after the comment and any remaining trailing whitespace is | ||||
|          * stripped. | ||||
|          * @param {string} line The source line with a trailing comment | ||||
|          * @param {ASTNode} comment The comment to remove | ||||
|          * @returns {string} Line without comment and trailing whitespace | ||||
|          */ | ||||
|         function stripTrailingComment(line, comment) { | ||||
|  | ||||
|             // loc.column is zero-indexed | ||||
|             return line.slice(0, comment.loc.start.column).replace(/\s+$/u, ""); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Ensure that an array exists at [key] on `object`, and add `value` to it. | ||||
|          * @param {Object} object the object to mutate | ||||
|          * @param {string} key the object's key | ||||
|          * @param {any} value the value to add | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function ensureArrayAndPush(object, key, value) { | ||||
|             if (!Array.isArray(object[key])) { | ||||
|                 object[key] = []; | ||||
|             } | ||||
|             object[key].push(value); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Retrieves an array containing all strings (" or ') in the source code. | ||||
|          * @returns {ASTNode[]} An array of string nodes. | ||||
|          */ | ||||
|         function getAllStrings() { | ||||
|             return sourceCode.ast.tokens.filter(token => (token.type === "String" || | ||||
|                 (token.type === "JSXText" && sourceCode.getNodeByRangeIndex(token.range[0] - 1).type === "JSXAttribute"))); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Retrieves an array containing all template literals in the source code. | ||||
|          * @returns {ASTNode[]} An array of template literal nodes. | ||||
|          */ | ||||
|         function getAllTemplateLiterals() { | ||||
|             return sourceCode.ast.tokens.filter(token => token.type === "Template"); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * Retrieves an array containing all RegExp literals in the source code. | ||||
|          * @returns {ASTNode[]} An array of RegExp literal nodes. | ||||
|          */ | ||||
|         function getAllRegExpLiterals() { | ||||
|             return sourceCode.ast.tokens.filter(token => token.type === "RegularExpression"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * | ||||
|          * reduce an array of AST nodes by line number, both start and end. | ||||
|          * @param {ASTNode[]} arr array of AST nodes | ||||
|          * @returns {Object} accululated AST nodes | ||||
|          */ | ||||
|         function groupArrayByLineNumber(arr) { | ||||
|             const obj = {}; | ||||
|  | ||||
|             for (let i = 0; i < arr.length; i++) { | ||||
|                 const node = arr[i]; | ||||
|  | ||||
|                 for (let j = node.loc.start.line; j <= node.loc.end.line; ++j) { | ||||
|                     ensureArrayAndPush(obj, j, node); | ||||
|                 } | ||||
|             } | ||||
|             return obj; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns an array of all comments in the source code. | ||||
|          * If the element in the array is a JSXEmptyExpression contained with a single line JSXExpressionContainer, | ||||
|          * the element is changed with JSXExpressionContainer node. | ||||
|          * @returns {ASTNode[]} An array of comment nodes | ||||
|          */ | ||||
|         function getAllComments() { | ||||
|             const comments = []; | ||||
|  | ||||
|             sourceCode.getAllComments() | ||||
|                 .forEach(commentNode => { | ||||
|                     const containingNode = sourceCode.getNodeByRangeIndex(commentNode.range[0]); | ||||
|  | ||||
|                     if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) { | ||||
|  | ||||
|                         // push a unique node only | ||||
|                         if (comments[comments.length - 1] !== containingNode.parent) { | ||||
|                             comments.push(containingNode.parent); | ||||
|                         } | ||||
|                     } else { | ||||
|                         comments.push(commentNode); | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|             return comments; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check the program for max length | ||||
|          * @param {ASTNode} node Node to examine | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkProgramForMaxLength(node) { | ||||
|  | ||||
|             // split (honors line-ending) | ||||
|             const lines = sourceCode.lines, | ||||
|  | ||||
|                 // list of comments to ignore | ||||
|                 comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? getAllComments() : []; | ||||
|  | ||||
|             // we iterate over comments in parallel with the lines | ||||
|             let commentsIndex = 0; | ||||
|  | ||||
|             const strings = getAllStrings(); | ||||
|             const stringsByLine = groupArrayByLineNumber(strings); | ||||
|  | ||||
|             const templateLiterals = getAllTemplateLiterals(); | ||||
|             const templateLiteralsByLine = groupArrayByLineNumber(templateLiterals); | ||||
|  | ||||
|             const regExpLiterals = getAllRegExpLiterals(); | ||||
|             const regExpLiteralsByLine = groupArrayByLineNumber(regExpLiterals); | ||||
|  | ||||
|             lines.forEach((line, i) => { | ||||
|  | ||||
|                 // i is zero-indexed, line numbers are one-indexed | ||||
|                 const lineNumber = i + 1; | ||||
|  | ||||
|                 /* | ||||
|                  * if we're checking comment length; we need to know whether this | ||||
|                  * line is a comment | ||||
|                  */ | ||||
|                 let lineIsComment = false; | ||||
|                 let textToMeasure; | ||||
|  | ||||
|                 /* | ||||
|                  * We can short-circuit the comment checks if we're already out of | ||||
|                  * comments to check. | ||||
|                  */ | ||||
|                 if (commentsIndex < comments.length) { | ||||
|                     let comment = null; | ||||
|  | ||||
|                     // iterate over comments until we find one past the current line | ||||
|                     do { | ||||
|                         comment = comments[++commentsIndex]; | ||||
|                     } while (comment && comment.loc.start.line <= lineNumber); | ||||
|  | ||||
|                     // and step back by one | ||||
|                     comment = comments[--commentsIndex]; | ||||
|  | ||||
|                     if (isFullLineComment(line, lineNumber, comment)) { | ||||
|                         lineIsComment = true; | ||||
|                         textToMeasure = line; | ||||
|                     } else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) { | ||||
|                         textToMeasure = stripTrailingComment(line, comment); | ||||
|  | ||||
|                         // ignore multiple trailing comments in the same line | ||||
|                         let lastIndex = commentsIndex; | ||||
|  | ||||
|                         while (isTrailingComment(textToMeasure, lineNumber, comments[--lastIndex])) { | ||||
|                             textToMeasure = stripTrailingComment(textToMeasure, comments[lastIndex]); | ||||
|                         } | ||||
|                     } else { | ||||
|                         textToMeasure = line; | ||||
|                     } | ||||
|                 } else { | ||||
|                     textToMeasure = line; | ||||
|                 } | ||||
|                 if (ignorePattern && ignorePattern.test(textToMeasure) || | ||||
|                     ignoreUrls && URL_REGEXP.test(textToMeasure) || | ||||
|                     ignoreStrings && stringsByLine[lineNumber] || | ||||
|                     ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || | ||||
|                     ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber] | ||||
|                 ) { | ||||
|  | ||||
|                     // ignore this line | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const lineLength = computeLineLength(textToMeasure, tabWidth); | ||||
|                 const commentLengthApplies = lineIsComment && maxCommentLength; | ||||
|  | ||||
|                 if (lineIsComment && ignoreComments) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const loc = { | ||||
|                     start: { | ||||
|                         line: lineNumber, | ||||
|                         column: 0 | ||||
|                     }, | ||||
|                     end: { | ||||
|                         line: lineNumber, | ||||
|                         column: textToMeasure.length | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 if (commentLengthApplies) { | ||||
|                     if (lineLength > maxCommentLength) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             loc, | ||||
|                             messageId: "maxComment", | ||||
|                             data: { | ||||
|                                 lineLength, | ||||
|                                 maxCommentLength | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } else if (lineLength > maxLength) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         loc, | ||||
|                         messageId: "max", | ||||
|                         data: { | ||||
|                             lineLength, | ||||
|                             maxLength | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program: checkProgramForMaxLength | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										213
									
								
								node_modules/eslint/lib/rules/max-lines-per-function.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								node_modules/eslint/lib/rules/max-lines-per-function.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to set the maximum number of line of code in a function. | ||||
|  * @author Pete Ward <peteward44@gmail.com> | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { upperCaseFirst } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Constants | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const OPTIONS_SCHEMA = { | ||||
|     type: "object", | ||||
|     properties: { | ||||
|         max: { | ||||
|             type: "integer", | ||||
|             minimum: 0 | ||||
|         }, | ||||
|         skipComments: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         skipBlankLines: { | ||||
|             type: "boolean" | ||||
|         }, | ||||
|         IIFEs: { | ||||
|             type: "boolean" | ||||
|         } | ||||
|     }, | ||||
|     additionalProperties: false | ||||
| }; | ||||
|  | ||||
| const OPTIONS_OR_INTEGER_SCHEMA = { | ||||
|     oneOf: [ | ||||
|         OPTIONS_SCHEMA, | ||||
|         { | ||||
|             type: "integer", | ||||
|             minimum: 1 | ||||
|         } | ||||
|     ] | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values. | ||||
|  * @param {Array} comments An array of comment nodes. | ||||
|  * @returns {Map<string, Node>} A map with numeric keys (source code line numbers) and comment token values. | ||||
|  */ | ||||
| function getCommentLineNumbers(comments) { | ||||
|     const map = new Map(); | ||||
|  | ||||
|     comments.forEach(comment => { | ||||
|         for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) { | ||||
|             map.set(i, comment); | ||||
|         } | ||||
|     }); | ||||
|     return map; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of lines of code in a function", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-lines-per-function" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             OPTIONS_OR_INTEGER_SCHEMA | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const lines = sourceCode.lines; | ||||
|  | ||||
|         const option = context.options[0]; | ||||
|         let maxLines = 50; | ||||
|         let skipComments = false; | ||||
|         let skipBlankLines = false; | ||||
|         let IIFEs = false; | ||||
|  | ||||
|         if (typeof option === "object") { | ||||
|             maxLines = typeof option.max === "number" ? option.max : 50; | ||||
|             skipComments = !!option.skipComments; | ||||
|             skipBlankLines = !!option.skipBlankLines; | ||||
|             IIFEs = !!option.IIFEs; | ||||
|         } else if (typeof option === "number") { | ||||
|             maxLines = option; | ||||
|         } | ||||
|  | ||||
|         const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments()); | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Tells if a comment encompasses the entire line. | ||||
|          * @param {string} line The source line with a trailing comment | ||||
|          * @param {number} lineNumber The one-indexed line number this is on | ||||
|          * @param {ASTNode} comment The comment to remove | ||||
|          * @returns {boolean} If the comment covers the entire line | ||||
|          */ | ||||
|         function isFullLineComment(line, lineNumber, comment) { | ||||
|             const start = comment.loc.start, | ||||
|                 end = comment.loc.end, | ||||
|                 isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(), | ||||
|                 isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim(); | ||||
|  | ||||
|             return comment && | ||||
|                 (start.line < lineNumber || isFirstTokenOnLine) && | ||||
|                 (end.line > lineNumber || isLastTokenOnLine); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Identifies is a node is a FunctionExpression which is part of an IIFE | ||||
|          * @param {ASTNode} node Node to test | ||||
|          * @returns {boolean} True if it's an IIFE | ||||
|          */ | ||||
|         function isIIFE(node) { | ||||
|             return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Identifies is a node is a FunctionExpression which is embedded within a MethodDefinition or Property | ||||
|          * @param {ASTNode} node Node to test | ||||
|          * @returns {boolean} True if it's a FunctionExpression embedded within a MethodDefinition or Property | ||||
|          */ | ||||
|         function isEmbedded(node) { | ||||
|             if (!node.parent) { | ||||
|                 return false; | ||||
|             } | ||||
|             if (node !== node.parent.value) { | ||||
|                 return false; | ||||
|             } | ||||
|             if (node.parent.type === "MethodDefinition") { | ||||
|                 return true; | ||||
|             } | ||||
|             if (node.parent.type === "Property") { | ||||
|                 return node.parent.method === true || node.parent.kind === "get" || node.parent.kind === "set"; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Count the lines in the function | ||||
|          * @param {ASTNode} funcNode Function AST node | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function processFunction(funcNode) { | ||||
|             const node = isEmbedded(funcNode) ? funcNode.parent : funcNode; | ||||
|  | ||||
|             if (!IIFEs && isIIFE(node)) { | ||||
|                 return; | ||||
|             } | ||||
|             let lineCount = 0; | ||||
|  | ||||
|             for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { | ||||
|                 const line = lines[i]; | ||||
|  | ||||
|                 if (skipComments) { | ||||
|                     if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { | ||||
|                         continue; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (skipBlankLines) { | ||||
|                     if (line.match(/^\s*$/u)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 lineCount++; | ||||
|             } | ||||
|  | ||||
|             if (lineCount > maxLines) { | ||||
|                 const name = upperCaseFirst(astUtils.getFunctionNameWithKind(funcNode)); | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "exceed", | ||||
|                     data: { name, lineCount, maxLines } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: processFunction, | ||||
|             FunctionExpression: processFunction, | ||||
|             ArrowFunctionExpression: processFunction | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										193
									
								
								node_modules/eslint/lib/rules/max-lines.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								node_modules/eslint/lib/rules/max-lines.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /** | ||||
|  * @fileoverview enforce a maximum file length | ||||
|  * @author Alberto Rodríguez | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Creates an array of numbers from `start` up to, but not including, `end` | ||||
|  * @param {number} start The start of the range | ||||
|  * @param {number} end The end of the range | ||||
|  * @returns {number[]} The range of numbers | ||||
|  */ | ||||
| function range(start, end) { | ||||
|     return [...Array(end - start).keys()].map(x => x + start); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of lines per file", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-lines" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             skipComments: { | ||||
|                                 type: "boolean" | ||||
|                             }, | ||||
|                             skipBlankLines: { | ||||
|                                 type: "boolean" | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: | ||||
|                 "File has too many lines ({{actual}}). Maximum allowed is {{max}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const option = context.options[0]; | ||||
|         let max = 300; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             Object.prototype.hasOwnProperty.call(option, "max") | ||||
|         ) { | ||||
|             max = option.max; | ||||
|         } else if (typeof option === "number") { | ||||
|             max = option; | ||||
|         } | ||||
|  | ||||
|         const skipComments = option && option.skipComments; | ||||
|         const skipBlankLines = option && option.skipBlankLines; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Returns whether or not a token is a comment node type | ||||
|          * @param {Token} token The token to check | ||||
|          * @returns {boolean} True if the token is a comment node | ||||
|          */ | ||||
|         function isCommentNodeType(token) { | ||||
|             return token && (token.type === "Block" || token.type === "Line"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the line numbers of a comment that don't have any code on the same line | ||||
|          * @param {Node} comment The comment node to check | ||||
|          * @returns {number[]} The line numbers | ||||
|          */ | ||||
|         function getLinesWithoutCode(comment) { | ||||
|             let start = comment.loc.start.line; | ||||
|             let end = comment.loc.end.line; | ||||
|  | ||||
|             let token; | ||||
|  | ||||
|             token = comment; | ||||
|             do { | ||||
|                 token = sourceCode.getTokenBefore(token, { | ||||
|                     includeComments: true | ||||
|                 }); | ||||
|             } while (isCommentNodeType(token)); | ||||
|  | ||||
|             if (token && astUtils.isTokenOnSameLine(token, comment)) { | ||||
|                 start += 1; | ||||
|             } | ||||
|  | ||||
|             token = comment; | ||||
|             do { | ||||
|                 token = sourceCode.getTokenAfter(token, { | ||||
|                     includeComments: true | ||||
|                 }); | ||||
|             } while (isCommentNodeType(token)); | ||||
|  | ||||
|             if (token && astUtils.isTokenOnSameLine(comment, token)) { | ||||
|                 end -= 1; | ||||
|             } | ||||
|  | ||||
|             if (start <= end) { | ||||
|                 return range(start, end + 1); | ||||
|             } | ||||
|             return []; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "Program:exit"() { | ||||
|                 let lines = sourceCode.lines.map((text, i) => ({ | ||||
|                     lineNumber: i + 1, | ||||
|                     text | ||||
|                 })); | ||||
|  | ||||
|                 /* | ||||
|                  * If file ends with a linebreak, `sourceCode.lines` will have one extra empty line at the end. | ||||
|                  * That isn't a real line, so we shouldn't count it. | ||||
|                  */ | ||||
|                 if (lines.length > 1 && lines[lines.length - 1].text === "") { | ||||
|                     lines.pop(); | ||||
|                 } | ||||
|  | ||||
|                 if (skipBlankLines) { | ||||
|                     lines = lines.filter(l => l.text.trim() !== ""); | ||||
|                 } | ||||
|  | ||||
|                 if (skipComments) { | ||||
|                     const comments = sourceCode.getAllComments(); | ||||
|  | ||||
|                     const commentLines = new Set(comments.flatMap(getLinesWithoutCode)); | ||||
|  | ||||
|                     lines = lines.filter( | ||||
|                         l => !commentLines.has(l.lineNumber) | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 if (lines.length > max) { | ||||
|                     const loc = { | ||||
|                         start: { | ||||
|                             line: lines[max].lineNumber, | ||||
|                             column: 0 | ||||
|                         }, | ||||
|                         end: { | ||||
|                             line: sourceCode.lines.length, | ||||
|                             column: sourceCode.lines[sourceCode.lines.length - 1].length | ||||
|                         } | ||||
|                     }; | ||||
|  | ||||
|                     context.report({ | ||||
|                         loc, | ||||
|                         messageId: "exceed", | ||||
|                         data: { | ||||
|                             max, | ||||
|                             actual: lines.length | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										117
									
								
								node_modules/eslint/lib/rules/max-nested-callbacks.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								node_modules/eslint/lib/rules/max-nested-callbacks.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to enforce a maximum number of nested callbacks. | ||||
|  * @author Ian Christian Myers | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum depth that callbacks can be nested", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-nested-callbacks" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             maximum: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Constants | ||||
|         //-------------------------------------------------------------------------- | ||||
|         const option = context.options[0]; | ||||
|         let THRESHOLD = 10; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) | ||||
|         ) { | ||||
|             THRESHOLD = option.maximum || option.max; | ||||
|         } else if (typeof option === "number") { | ||||
|             THRESHOLD = option; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const callbackStack = []; | ||||
|  | ||||
|         /** | ||||
|          * Checks a given function node for too many callbacks. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkFunction(node) { | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             if (parent.type === "CallExpression") { | ||||
|                 callbackStack.push(node); | ||||
|             } | ||||
|  | ||||
|             if (callbackStack.length > THRESHOLD) { | ||||
|                 const opts = { num: callbackStack.length, max: THRESHOLD }; | ||||
|  | ||||
|                 context.report({ node, messageId: "exceed", data: opts }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Pops the call stack. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function popStack() { | ||||
|             callbackStack.pop(); | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ArrowFunctionExpression: checkFunction, | ||||
|             "ArrowFunctionExpression:exit": popStack, | ||||
|  | ||||
|             FunctionExpression: checkFunction, | ||||
|             "FunctionExpression:exit": popStack | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										102
									
								
								node_modules/eslint/lib/rules/max-params.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								node_modules/eslint/lib/rules/max-params.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag when a function has too many parameters | ||||
|  * @author Ilya Volodin | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { upperCaseFirst } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of parameters in function definitions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-params" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             maximum: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: "{{name}} has too many parameters ({{count}}). Maximum allowed is {{max}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const option = context.options[0]; | ||||
|         let numParams = 3; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) | ||||
|         ) { | ||||
|             numParams = option.maximum || option.max; | ||||
|         } | ||||
|         if (typeof option === "number") { | ||||
|             numParams = option; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks a function to see if it has too many parameters. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkFunction(node) { | ||||
|             if (node.params.length > numParams) { | ||||
|                 context.report({ | ||||
|                     loc: astUtils.getFunctionHeadLoc(node, sourceCode), | ||||
|                     node, | ||||
|                     messageId: "exceed", | ||||
|                     data: { | ||||
|                         name: upperCaseFirst(astUtils.getFunctionNameWithKind(node)), | ||||
|                         count: node.params.length, | ||||
|                         max: numParams | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: checkFunction, | ||||
|             ArrowFunctionExpression: checkFunction, | ||||
|             FunctionExpression: checkFunction | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										199
									
								
								node_modules/eslint/lib/rules/max-statements-per-line.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								node_modules/eslint/lib/rules/max-statements-per-line.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,199 @@ | ||||
| /** | ||||
|  * @fileoverview Specify the maximum number of statements allowed per line. | ||||
|  * @author Kenneth Williams | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of statements allowed per line", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-statements-per-line" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     max: { | ||||
|                         type: "integer", | ||||
|                         minimum: 1, | ||||
|                         default: 1 | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode, | ||||
|             options = context.options[0] || {}, | ||||
|             maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1; | ||||
|  | ||||
|         let lastStatementLine = 0, | ||||
|             numberOfStatementsOnThisLine = 0, | ||||
|             firstExtraStatement; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u; | ||||
|  | ||||
|         /** | ||||
|          * Reports with the first extra statement, and clears it. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function reportFirstExtraStatementAndClear() { | ||||
|             if (firstExtraStatement) { | ||||
|                 context.report({ | ||||
|                     node: firstExtraStatement, | ||||
|                     messageId: "exceed", | ||||
|                     data: { | ||||
|                         numberOfStatementsOnThisLine, | ||||
|                         maxStatementsPerLine, | ||||
|                         statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements" | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             firstExtraStatement = null; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the actual last token of a given node. | ||||
|          * @param {ASTNode} node A node to get. This is a node except EmptyStatement. | ||||
|          * @returns {Token} The actual last token. | ||||
|          */ | ||||
|         function getActualLastToken(node) { | ||||
|             return sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Addresses a given node. | ||||
|          * It updates the state of this rule, then reports the node if the node violated this rule. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function enterStatement(node) { | ||||
|             const line = node.loc.start.line; | ||||
|  | ||||
|             /* | ||||
|              * Skip to allow non-block statements if this is direct child of control statements. | ||||
|              * `if (a) foo();` is counted as 1. | ||||
|              * But `if (a) foo(); else foo();` should be counted as 2. | ||||
|              */ | ||||
|             if (SINGLE_CHILD_ALLOWED.test(node.parent.type) && | ||||
|                 node.parent.alternate !== node | ||||
|             ) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Update state. | ||||
|             if (line === lastStatementLine) { | ||||
|                 numberOfStatementsOnThisLine += 1; | ||||
|             } else { | ||||
|                 reportFirstExtraStatementAndClear(); | ||||
|                 numberOfStatementsOnThisLine = 1; | ||||
|                 lastStatementLine = line; | ||||
|             } | ||||
|  | ||||
|             // Reports if the node violated this rule. | ||||
|             if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { | ||||
|                 firstExtraStatement = firstExtraStatement || node; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Updates the state of this rule with the end line of leaving node to check with the next statement. | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function leaveStatement(node) { | ||||
|             const line = getActualLastToken(node).loc.end.line; | ||||
|  | ||||
|             // Update state. | ||||
|             if (line !== lastStatementLine) { | ||||
|                 reportFirstExtraStatementAndClear(); | ||||
|                 numberOfStatementsOnThisLine = 1; | ||||
|                 lastStatementLine = line; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             BreakStatement: enterStatement, | ||||
|             ClassDeclaration: enterStatement, | ||||
|             ContinueStatement: enterStatement, | ||||
|             DebuggerStatement: enterStatement, | ||||
|             DoWhileStatement: enterStatement, | ||||
|             ExpressionStatement: enterStatement, | ||||
|             ForInStatement: enterStatement, | ||||
|             ForOfStatement: enterStatement, | ||||
|             ForStatement: enterStatement, | ||||
|             FunctionDeclaration: enterStatement, | ||||
|             IfStatement: enterStatement, | ||||
|             ImportDeclaration: enterStatement, | ||||
|             LabeledStatement: enterStatement, | ||||
|             ReturnStatement: enterStatement, | ||||
|             SwitchStatement: enterStatement, | ||||
|             ThrowStatement: enterStatement, | ||||
|             TryStatement: enterStatement, | ||||
|             VariableDeclaration: enterStatement, | ||||
|             WhileStatement: enterStatement, | ||||
|             WithStatement: enterStatement, | ||||
|             ExportNamedDeclaration: enterStatement, | ||||
|             ExportDefaultDeclaration: enterStatement, | ||||
|             ExportAllDeclaration: enterStatement, | ||||
|  | ||||
|             "BreakStatement:exit": leaveStatement, | ||||
|             "ClassDeclaration:exit": leaveStatement, | ||||
|             "ContinueStatement:exit": leaveStatement, | ||||
|             "DebuggerStatement:exit": leaveStatement, | ||||
|             "DoWhileStatement:exit": leaveStatement, | ||||
|             "ExpressionStatement:exit": leaveStatement, | ||||
|             "ForInStatement:exit": leaveStatement, | ||||
|             "ForOfStatement:exit": leaveStatement, | ||||
|             "ForStatement:exit": leaveStatement, | ||||
|             "FunctionDeclaration:exit": leaveStatement, | ||||
|             "IfStatement:exit": leaveStatement, | ||||
|             "ImportDeclaration:exit": leaveStatement, | ||||
|             "LabeledStatement:exit": leaveStatement, | ||||
|             "ReturnStatement:exit": leaveStatement, | ||||
|             "SwitchStatement:exit": leaveStatement, | ||||
|             "ThrowStatement:exit": leaveStatement, | ||||
|             "TryStatement:exit": leaveStatement, | ||||
|             "VariableDeclaration:exit": leaveStatement, | ||||
|             "WhileStatement:exit": leaveStatement, | ||||
|             "WithStatement:exit": leaveStatement, | ||||
|             "ExportNamedDeclaration:exit": leaveStatement, | ||||
|             "ExportDefaultDeclaration:exit": leaveStatement, | ||||
|             "ExportAllDeclaration:exit": leaveStatement, | ||||
|             "Program:exit": reportFirstExtraStatementAndClear | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										184
									
								
								node_modules/eslint/lib/rules/max-statements.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								node_modules/eslint/lib/rules/max-statements.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to set the maximum number of statements in a function. | ||||
|  * @author Ian Christian Myers | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
| const { upperCaseFirst } = require("../shared/string-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a maximum number of statements allowed in function blocks", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/max-statements" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 oneOf: [ | ||||
|                     { | ||||
|                         type: "integer", | ||||
|                         minimum: 0 | ||||
|                     }, | ||||
|                     { | ||||
|                         type: "object", | ||||
|                         properties: { | ||||
|                             maximum: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             }, | ||||
|                             max: { | ||||
|                                 type: "integer", | ||||
|                                 minimum: 0 | ||||
|                             } | ||||
|                         }, | ||||
|                         additionalProperties: false | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     ignoreTopLevelFunctions: { | ||||
|                         type: "boolean" | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             exceed: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         const functionStack = [], | ||||
|             option = context.options[0], | ||||
|             ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, | ||||
|             topLevelFunctions = []; | ||||
|         let maxStatements = 10; | ||||
|  | ||||
|         if ( | ||||
|             typeof option === "object" && | ||||
|             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) | ||||
|         ) { | ||||
|             maxStatements = option.maximum || option.max; | ||||
|         } else if (typeof option === "number") { | ||||
|             maxStatements = option; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports a node if it has too many statements | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @param {int} count Number of statements in node | ||||
|          * @param {int} max Maximum number of statements allowed | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function reportIfTooManyStatements(node, count, max) { | ||||
|             if (count > max) { | ||||
|                 const name = upperCaseFirst(astUtils.getFunctionNameWithKind(node)); | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "exceed", | ||||
|                     data: { name, count, max } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * When parsing a new function, store it in our function stack | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function startFunction() { | ||||
|             functionStack.push(0); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Evaluate the node at the end of function | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function endFunction(node) { | ||||
|             const count = functionStack.pop(); | ||||
|  | ||||
|             /* | ||||
|              * This rule does not apply to class static blocks, but we have to track them so | ||||
|              * that statements in them do not count as statements in the enclosing function. | ||||
|              */ | ||||
|             if (node.type === "StaticBlock") { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (ignoreTopLevelFunctions && functionStack.length === 0) { | ||||
|                 topLevelFunctions.push({ node, count }); | ||||
|             } else { | ||||
|                 reportIfTooManyStatements(node, count, maxStatements); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Increment the count of the functions | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function countStatements(node) { | ||||
|             functionStack[functionStack.length - 1] += node.body.length; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             FunctionDeclaration: startFunction, | ||||
|             FunctionExpression: startFunction, | ||||
|             ArrowFunctionExpression: startFunction, | ||||
|             StaticBlock: startFunction, | ||||
|  | ||||
|             BlockStatement: countStatements, | ||||
|  | ||||
|             "FunctionDeclaration:exit": endFunction, | ||||
|             "FunctionExpression:exit": endFunction, | ||||
|             "ArrowFunctionExpression:exit": endFunction, | ||||
|             "StaticBlock:exit": endFunction, | ||||
|  | ||||
|             "Program:exit"() { | ||||
|                 if (topLevelFunctions.length === 1) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 topLevelFunctions.forEach(element => { | ||||
|                     const count = element.count; | ||||
|                     const node = element.node; | ||||
|  | ||||
|                     reportIfTooManyStatements(node, count, maxStatements); | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										474
									
								
								node_modules/eslint/lib/rules/multiline-comment-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								node_modules/eslint/lib/rules/multiline-comment-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,474 @@ | ||||
| /** | ||||
|  * @fileoverview enforce a particular style for multiline comments | ||||
|  * @author Teddy Katz | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce a particular style for multiline comments", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/multiline-comment-style" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|         schema: { | ||||
|             anyOf: [ | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["starred-block", "bare-block"] | ||||
|                         } | ||||
|                     ], | ||||
|                     additionalItems: false | ||||
|                 }, | ||||
|                 { | ||||
|                     type: "array", | ||||
|                     items: [ | ||||
|                         { | ||||
|                             enum: ["separate-lines"] | ||||
|                         }, | ||||
|                         { | ||||
|                             type: "object", | ||||
|                             properties: { | ||||
|                                 checkJSDoc: { | ||||
|                                     type: "boolean" | ||||
|                                 } | ||||
|                             }, | ||||
|                             additionalProperties: false | ||||
|                         } | ||||
|                     ], | ||||
|                     additionalItems: false | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|         messages: { | ||||
|             expectedBlock: "Expected a block comment instead of consecutive line comments.", | ||||
|             expectedBareBlock: "Expected a block comment without padding stars.", | ||||
|             startNewline: "Expected a linebreak after '/*'.", | ||||
|             endNewline: "Expected a linebreak before '*/'.", | ||||
|             missingStar: "Expected a '*' at the start of this line.", | ||||
|             alignment: "Expected this line to be aligned with the start of the comment.", | ||||
|             expectedLines: "Expected multiple line comments instead of a block comment." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const option = context.options[0] || "starred-block"; | ||||
|         const params = context.options[1] || {}; | ||||
|         const checkJSDoc = !!params.checkJSDoc; | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Checks if a comment line is starred. | ||||
|          * @param {string} line A string representing a comment line. | ||||
|          * @returns {boolean} Whether or not the comment line is starred. | ||||
|          */ | ||||
|         function isStarredCommentLine(line) { | ||||
|             return /^\s*\*/u.test(line); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a comment group is in starred-block form. | ||||
|          * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. | ||||
|          * @returns {boolean} Whether or not the comment group is in starred block form. | ||||
|          */ | ||||
|         function isStarredBlockComment([firstComment]) { | ||||
|             if (firstComment.type !== "Block") { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); | ||||
|  | ||||
|             // The first and last lines can only contain whitespace. | ||||
|             return lines.length > 0 && lines.every((line, i) => (i === 0 || i === lines.length - 1 ? /^\s*$/u : /^\s*\*/u).test(line)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if a comment group is in JSDoc form. | ||||
|          * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. | ||||
|          * @returns {boolean} Whether or not the comment group is in JSDoc form. | ||||
|          */ | ||||
|         function isJSDocComment([firstComment]) { | ||||
|             if (firstComment.type !== "Block") { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); | ||||
|  | ||||
|             return /^\*\s*$/u.test(lines[0]) && | ||||
|                 lines.slice(1, -1).every(line => /^\s* /u.test(line)) && | ||||
|                 /^\s*$/u.test(lines[lines.length - 1]); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Processes a comment group that is currently in separate-line form, calculating the offset for each line. | ||||
|          * @param {Token[]} commentGroup A group of comments containing multiple line comments. | ||||
|          * @returns {string[]} An array of the processed lines. | ||||
|          */ | ||||
|         function processSeparateLineComments(commentGroup) { | ||||
|             const allLinesHaveLeadingSpace = commentGroup | ||||
|                 .map(({ value }) => value) | ||||
|                 .filter(line => line.trim().length) | ||||
|                 .every(line => line.startsWith(" ")); | ||||
|  | ||||
|             return commentGroup.map(({ value }) => (allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value)); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Processes a comment group that is currently in starred-block form, calculating the offset for each line. | ||||
|          * @param {Token} comment A single block comment token in starred-block form. | ||||
|          * @returns {string[]} An array of the processed lines. | ||||
|          */ | ||||
|         function processStarredBlockComment(comment) { | ||||
|             const lines = comment.value.split(astUtils.LINEBREAK_MATCHER) | ||||
|                 .filter((line, i, linesArr) => !(i === 0 || i === linesArr.length - 1)) | ||||
|                 .map(line => line.replace(/^\s*$/u, "")); | ||||
|             const allLinesHaveLeadingSpace = lines | ||||
|                 .map(line => line.replace(/\s*\*/u, "")) | ||||
|                 .filter(line => line.trim().length) | ||||
|                 .every(line => line.startsWith(" ")); | ||||
|  | ||||
|             return lines.map(line => line.replace(allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u, "")); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Processes a comment group that is currently in bare-block form, calculating the offset for each line. | ||||
|          * @param {Token} comment A single block comment token in bare-block form. | ||||
|          * @returns {string[]} An array of the processed lines. | ||||
|          */ | ||||
|         function processBareBlockComment(comment) { | ||||
|             const lines = comment.value.split(astUtils.LINEBREAK_MATCHER).map(line => line.replace(/^\s*$/u, "")); | ||||
|             const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])}   `; | ||||
|             let offset = ""; | ||||
|  | ||||
|             /* | ||||
|              * Calculate the offset of the least indented line and use that as the basis for offsetting all the lines. | ||||
|              * The first line should not be checked because it is inline with the opening block comment delimiter. | ||||
|              */ | ||||
|             for (const [i, line] of lines.entries()) { | ||||
|                 if (!line.trim().length || i === 0) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 const [, lineOffset] = line.match(/^(\s*\*?\s*)/u); | ||||
|  | ||||
|                 if (lineOffset.length < leadingWhitespace.length) { | ||||
|                     const newOffset = leadingWhitespace.slice(lineOffset.length - leadingWhitespace.length); | ||||
|  | ||||
|                     if (newOffset.length > offset.length) { | ||||
|                         offset = newOffset; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return lines.map(line => { | ||||
|                 const match = line.match(/^(\s*\*?\s*)(.*)/u); | ||||
|                 const [, lineOffset, lineContents] = match; | ||||
|  | ||||
|                 if (lineOffset.length > leadingWhitespace.length) { | ||||
|                     return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`; | ||||
|                 } | ||||
|  | ||||
|                 if (lineOffset.length < leadingWhitespace.length) { | ||||
|                     return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`; | ||||
|                 } | ||||
|  | ||||
|                 return lineContents; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets a list of comment lines in a group, formatting leading whitespace as necessary. | ||||
|          * @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment. | ||||
|          * @returns {string[]} A list of comment lines. | ||||
|          */ | ||||
|         function getCommentLines(commentGroup) { | ||||
|             const [firstComment] = commentGroup; | ||||
|  | ||||
|             if (firstComment.type === "Line") { | ||||
|                 return processSeparateLineComments(commentGroup); | ||||
|             } | ||||
|  | ||||
|             if (isStarredBlockComment(commentGroup)) { | ||||
|                 return processStarredBlockComment(firstComment); | ||||
|             } | ||||
|  | ||||
|             return processBareBlockComment(firstComment); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the initial offset (whitespace) from the beginning of a line to a given comment token. | ||||
|          * @param {Token} comment The token to check. | ||||
|          * @returns {string} The offset from the beginning of a line to the token. | ||||
|          */ | ||||
|         function getInitialOffset(comment) { | ||||
|             return sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0]); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Converts a comment into starred-block form | ||||
|          * @param {Token} firstComment The first comment of the group being converted | ||||
|          * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment | ||||
|          * @returns {string} A representation of the comment value in starred-block form, excluding start and end markers | ||||
|          */ | ||||
|         function convertToStarredBlock(firstComment, commentLinesList) { | ||||
|             const initialOffset = getInitialOffset(firstComment); | ||||
|  | ||||
|             return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Converts a comment into separate-line form | ||||
|          * @param {Token} firstComment The first comment of the group being converted | ||||
|          * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment | ||||
|          * @returns {string} A representation of the comment value in separate-line form | ||||
|          */ | ||||
|         function convertToSeparateLines(firstComment, commentLinesList) { | ||||
|             return commentLinesList.map(line => `// ${line}`).join(`\n${getInitialOffset(firstComment)}`); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Converts a comment into bare-block form | ||||
|          * @param {Token} firstComment The first comment of the group being converted | ||||
|          * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment | ||||
|          * @returns {string} A representation of the comment value in bare-block form | ||||
|          */ | ||||
|         function convertToBlock(firstComment, commentLinesList) { | ||||
|             return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)}   `)} */`; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Each method checks a group of comments to see if it's valid according to the given option. | ||||
|          * @param {Token[]} commentGroup A list of comments that appear together. This will either contain a single | ||||
|          * block comment or multiple line comments. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         const commentGroupCheckers = { | ||||
|             "starred-block"(commentGroup) { | ||||
|                 const [firstComment] = commentGroup; | ||||
|                 const commentLines = getCommentLines(commentGroup); | ||||
|  | ||||
|                 if (commentLines.some(value => value.includes("*/"))) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (commentGroup.length > 1) { | ||||
|                     context.report({ | ||||
|                         loc: { | ||||
|                             start: firstComment.loc.start, | ||||
|                             end: commentGroup[commentGroup.length - 1].loc.end | ||||
|                         }, | ||||
|                         messageId: "expectedBlock", | ||||
|                         fix(fixer) { | ||||
|                             const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]]; | ||||
|  | ||||
|                             return commentLines.some(value => value.startsWith("/")) | ||||
|                                 ? null | ||||
|                                 : fixer.replaceTextRange(range, convertToStarredBlock(firstComment, commentLines)); | ||||
|                         } | ||||
|                     }); | ||||
|                 } else { | ||||
|                     const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); | ||||
|                     const expectedLeadingWhitespace = getInitialOffset(firstComment); | ||||
|                     const expectedLinePrefix = `${expectedLeadingWhitespace} *`; | ||||
|  | ||||
|                     if (!/^\*?\s*$/u.test(lines[0])) { | ||||
|                         const start = firstComment.value.startsWith("*") ? firstComment.range[0] + 1 : firstComment.range[0]; | ||||
|  | ||||
|                         context.report({ | ||||
|                             loc: { | ||||
|                                 start: firstComment.loc.start, | ||||
|                                 end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } | ||||
|                             }, | ||||
|                             messageId: "startNewline", | ||||
|                             fix: fixer => fixer.insertTextAfterRange([start, start + 2], `\n${expectedLinePrefix}`) | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     if (!/^\s*$/u.test(lines[lines.length - 1])) { | ||||
|                         context.report({ | ||||
|                             loc: { | ||||
|                                 start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 }, | ||||
|                                 end: firstComment.loc.end | ||||
|                             }, | ||||
|                             messageId: "endNewline", | ||||
|                             fix: fixer => fixer.replaceTextRange([firstComment.range[1] - 2, firstComment.range[1]], `\n${expectedLinePrefix}/`) | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) { | ||||
|                         const lineText = sourceCode.lines[lineNumber - 1]; | ||||
|                         const errorType = isStarredCommentLine(lineText) | ||||
|                             ? "alignment" | ||||
|                             : "missingStar"; | ||||
|  | ||||
|                         if (!lineText.startsWith(expectedLinePrefix)) { | ||||
|                             context.report({ | ||||
|                                 loc: { | ||||
|                                     start: { line: lineNumber, column: 0 }, | ||||
|                                     end: { line: lineNumber, column: lineText.length } | ||||
|                                 }, | ||||
|                                 messageId: errorType, | ||||
|                                 fix(fixer) { | ||||
|                                     const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 }); | ||||
|  | ||||
|                                     if (errorType === "alignment") { | ||||
|                                         const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || []; | ||||
|                                         const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; | ||||
|  | ||||
|                                         return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix); | ||||
|                                     } | ||||
|  | ||||
|                                     const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || []; | ||||
|                                     const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; | ||||
|                                     let offset; | ||||
|  | ||||
|                                     for (const [idx, line] of lines.entries()) { | ||||
|                                         if (!/\S+/u.test(line)) { | ||||
|                                             continue; | ||||
|                                         } | ||||
|  | ||||
|                                         const lineTextToAlignWith = sourceCode.lines[firstComment.loc.start.line - 1 + idx]; | ||||
|                                         const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || []; | ||||
|  | ||||
|                                         offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`; | ||||
|  | ||||
|                                         if (/^\s*\//u.test(lineText) && offset.length === 0) { | ||||
|                                             offset += " "; | ||||
|                                         } | ||||
|                                         break; | ||||
|                                     } | ||||
|  | ||||
|                                     return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`); | ||||
|                                 } | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "separate-lines"(commentGroup) { | ||||
|                 const [firstComment] = commentGroup; | ||||
|  | ||||
|                 const isJSDoc = isJSDocComment(commentGroup); | ||||
|  | ||||
|                 if (firstComment.type !== "Block" || (!checkJSDoc && isJSDoc)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 let commentLines = getCommentLines(commentGroup); | ||||
|  | ||||
|                 if (isJSDoc) { | ||||
|                     commentLines = commentLines.slice(1, commentLines.length - 1); | ||||
|                 } | ||||
|  | ||||
|                 const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true }); | ||||
|  | ||||
|                 if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 context.report({ | ||||
|                     loc: { | ||||
|                         start: firstComment.loc.start, | ||||
|                         end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } | ||||
|                     }, | ||||
|                     messageId: "expectedLines", | ||||
|                     fix(fixer) { | ||||
|                         return fixer.replaceText(firstComment, convertToSeparateLines(firstComment, commentLines)); | ||||
|                     } | ||||
|                 }); | ||||
|             }, | ||||
|             "bare-block"(commentGroup) { | ||||
|                 if (isJSDocComment(commentGroup)) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 const [firstComment] = commentGroup; | ||||
|                 const commentLines = getCommentLines(commentGroup); | ||||
|  | ||||
|                 // Disallows consecutive line comments in favor of using a block comment. | ||||
|                 if (firstComment.type === "Line" && commentLines.length > 1 && | ||||
|                     !commentLines.some(value => value.includes("*/"))) { | ||||
|                     context.report({ | ||||
|                         loc: { | ||||
|                             start: firstComment.loc.start, | ||||
|                             end: commentGroup[commentGroup.length - 1].loc.end | ||||
|                         }, | ||||
|                         messageId: "expectedBlock", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.replaceTextRange( | ||||
|                                 [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]], | ||||
|                                 convertToBlock(firstComment, commentLines) | ||||
|                             ); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 // Prohibits block comments from having a * at the beginning of each line. | ||||
|                 if (isStarredBlockComment(commentGroup)) { | ||||
|                     context.report({ | ||||
|                         loc: { | ||||
|                             start: firstComment.loc.start, | ||||
|                             end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } | ||||
|                         }, | ||||
|                         messageId: "expectedBareBlock", | ||||
|                         fix(fixer) { | ||||
|                             return fixer.replaceText(firstComment, convertToBlock(firstComment, commentLines)); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             Program() { | ||||
|                 return sourceCode.getAllComments() | ||||
|                     .filter(comment => comment.type !== "Shebang") | ||||
|                     .filter(comment => !astUtils.COMMENTS_IGNORE_PATTERN.test(comment.value)) | ||||
|                     .filter(comment => { | ||||
|                         const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); | ||||
|  | ||||
|                         return !tokenBefore || tokenBefore.loc.end.line < comment.loc.start.line; | ||||
|                     }) | ||||
|                     .reduce((commentGroups, comment, index, commentList) => { | ||||
|                         const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); | ||||
|  | ||||
|                         if ( | ||||
|                             comment.type === "Line" && | ||||
|                             index && commentList[index - 1].type === "Line" && | ||||
|                             tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 && | ||||
|                             tokenBefore === commentList[index - 1] | ||||
|                         ) { | ||||
|                             commentGroups[commentGroups.length - 1].push(comment); | ||||
|                         } else { | ||||
|                             commentGroups.push([comment]); | ||||
|                         } | ||||
|  | ||||
|                         return commentGroups; | ||||
|                     }, []) | ||||
|                     .filter(commentGroup => !(commentGroup.length === 1 && commentGroup[0].loc.start.line === commentGroup[0].loc.end.line)) | ||||
|                     .forEach(commentGroupCheckers[option]); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										174
									
								
								node_modules/eslint/lib/rules/multiline-ternary.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								node_modules/eslint/lib/rules/multiline-ternary.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| /** | ||||
|  * @fileoverview Enforce newlines between operands of ternary expressions | ||||
|  * @author Kai Cataldo | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce newlines between operands of ternary expressions", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/multiline-ternary" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "always-multiline", "never"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             expectedTestCons: "Expected newline between test and consequent of ternary expression.", | ||||
|             expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.", | ||||
|             unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.", | ||||
|             unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression." | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace" | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|         const option = context.options[0]; | ||||
|         const multiline = option !== "never"; | ||||
|         const allowSingleLine = option === "always-multiline"; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ConditionalExpression(node) { | ||||
|                 const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken); | ||||
|                 const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken); | ||||
|  | ||||
|                 const firstTokenOfTest = sourceCode.getFirstToken(node); | ||||
|                 const lastTokenOfTest = sourceCode.getTokenBefore(questionToken); | ||||
|                 const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken); | ||||
|                 const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken); | ||||
|                 const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken); | ||||
|  | ||||
|                 const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent); | ||||
|                 const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate); | ||||
|  | ||||
|                 const hasComments = !!sourceCode.getCommentsInside(node).length; | ||||
|  | ||||
|                 if (!multiline) { | ||||
|                     if (!areTestAndConsequentOnSameLine) { | ||||
|                         context.report({ | ||||
|                             node: node.test, | ||||
|                             loc: { | ||||
|                                 start: firstTokenOfTest.loc.start, | ||||
|                                 end: lastTokenOfTest.loc.end | ||||
|                             }, | ||||
|                             messageId: "unexpectedTestCons", | ||||
|                             fix(fixer) { | ||||
|                                 if (hasComments) { | ||||
|                                     return null; | ||||
|                                 } | ||||
|                                 const fixers = []; | ||||
|                                 const areTestAndQuestionOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, questionToken); | ||||
|                                 const areQuestionAndConsOnSameLine = astUtils.isTokenOnSameLine(questionToken, firstTokenOfConsequent); | ||||
|  | ||||
|                                 if (!areTestAndQuestionOnSameLine) { | ||||
|                                     fixers.push(fixer.removeRange([lastTokenOfTest.range[1], questionToken.range[0]])); | ||||
|                                 } | ||||
|                                 if (!areQuestionAndConsOnSameLine) { | ||||
|                                     fixers.push(fixer.removeRange([questionToken.range[1], firstTokenOfConsequent.range[0]])); | ||||
|                                 } | ||||
|  | ||||
|                                 return fixers; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     if (!areConsequentAndAlternateOnSameLine) { | ||||
|                         context.report({ | ||||
|                             node: node.consequent, | ||||
|                             loc: { | ||||
|                                 start: firstTokenOfConsequent.loc.start, | ||||
|                                 end: lastTokenOfConsequent.loc.end | ||||
|                             }, | ||||
|                             messageId: "unexpectedConsAlt", | ||||
|                             fix(fixer) { | ||||
|                                 if (hasComments) { | ||||
|                                     return null; | ||||
|                                 } | ||||
|                                 const fixers = []; | ||||
|                                 const areConsAndColonOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, colonToken); | ||||
|                                 const areColonAndAltOnSameLine = astUtils.isTokenOnSameLine(colonToken, firstTokenOfAlternate); | ||||
|  | ||||
|                                 if (!areConsAndColonOnSameLine) { | ||||
|                                     fixers.push(fixer.removeRange([lastTokenOfConsequent.range[1], colonToken.range[0]])); | ||||
|                                 } | ||||
|                                 if (!areColonAndAltOnSameLine) { | ||||
|                                     fixers.push(fixer.removeRange([colonToken.range[1], firstTokenOfAlternate.range[0]])); | ||||
|                                 } | ||||
|  | ||||
|                                 return fixers; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (allowSingleLine && node.loc.start.line === node.loc.end.line) { | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     if (areTestAndConsequentOnSameLine) { | ||||
|                         context.report({ | ||||
|                             node: node.test, | ||||
|                             loc: { | ||||
|                                 start: firstTokenOfTest.loc.start, | ||||
|                                 end: lastTokenOfTest.loc.end | ||||
|                             }, | ||||
|                             messageId: "expectedTestCons", | ||||
|                             fix: fixer => (hasComments ? null : ( | ||||
|                                 fixer.replaceTextRange( | ||||
|                                     [ | ||||
|                                         lastTokenOfTest.range[1], | ||||
|                                         questionToken.range[0] | ||||
|                                     ], | ||||
|                                     "\n" | ||||
|                                 ) | ||||
|                             )) | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     if (areConsequentAndAlternateOnSameLine) { | ||||
|                         context.report({ | ||||
|                             node: node.consequent, | ||||
|                             loc: { | ||||
|                                 start: firstTokenOfConsequent.loc.start, | ||||
|                                 end: lastTokenOfConsequent.loc.end | ||||
|                             }, | ||||
|                             messageId: "expectedConsAlt", | ||||
|                             fix: (fixer => (hasComments ? null : ( | ||||
|                                 fixer.replaceTextRange( | ||||
|                                     [ | ||||
|                                         lastTokenOfConsequent.range[1], | ||||
|                                         colonToken.range[0] | ||||
|                                     ], | ||||
|                                     "\n" | ||||
|                                 ) | ||||
|                             ))) | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										276
									
								
								node_modules/eslint/lib/rules/new-cap.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								node_modules/eslint/lib/rules/new-cap.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,276 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of constructors without capital letters | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const CAPS_ALLOWED = [ | ||||
|     "Array", | ||||
|     "Boolean", | ||||
|     "Date", | ||||
|     "Error", | ||||
|     "Function", | ||||
|     "Number", | ||||
|     "Object", | ||||
|     "RegExp", | ||||
|     "String", | ||||
|     "Symbol", | ||||
|     "BigInt" | ||||
| ]; | ||||
|  | ||||
| /** | ||||
|  * Ensure that if the key is provided, it must be an array. | ||||
|  * @param {Object} obj Object to check with `key`. | ||||
|  * @param {string} key Object key to check on `obj`. | ||||
|  * @param {any} fallback If obj[key] is not present, this will be returned. | ||||
|  * @throws {TypeError} If key is not an own array type property of `obj`. | ||||
|  * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` | ||||
|  */ | ||||
| function checkArray(obj, key, fallback) { | ||||
|  | ||||
|     /* c8 ignore start */ | ||||
|     if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) { | ||||
|         throw new TypeError(`${key}, if provided, must be an Array`); | ||||
|     }/* c8 ignore stop */ | ||||
|     return obj[key] || fallback; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * A reducer function to invert an array to an Object mapping the string form of the key, to `true`. | ||||
|  * @param {Object} map Accumulator object for the reduce. | ||||
|  * @param {string} key Object key to set to `true`. | ||||
|  * @returns {Object} Returns the updated Object for further reduction. | ||||
|  */ | ||||
| function invert(map, key) { | ||||
|     map[key] = true; | ||||
|     return map; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Creates an object with the cap is new exceptions as its keys and true as their values. | ||||
|  * @param {Object} config Rule configuration | ||||
|  * @returns {Object} Object with cap is new exceptions. | ||||
|  */ | ||||
| function calculateCapIsNewExceptions(config) { | ||||
|     let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); | ||||
|  | ||||
|     if (capIsNewExceptions !== CAPS_ALLOWED) { | ||||
|         capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); | ||||
|     } | ||||
|  | ||||
|     return capIsNewExceptions.reduce(invert, {}); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require constructor names to begin with a capital letter", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/new-cap" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     newIsCap: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     }, | ||||
|                     capIsNew: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     }, | ||||
|                     newIsCapExceptions: { | ||||
|                         type: "array", | ||||
|                         items: { | ||||
|                             type: "string" | ||||
|                         } | ||||
|                     }, | ||||
|                     newIsCapExceptionPattern: { | ||||
|                         type: "string" | ||||
|                     }, | ||||
|                     capIsNewExceptions: { | ||||
|                         type: "array", | ||||
|                         items: { | ||||
|                             type: "string" | ||||
|                         } | ||||
|                     }, | ||||
|                     capIsNewExceptionPattern: { | ||||
|                         type: "string" | ||||
|                     }, | ||||
|                     properties: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             upper: "A function with a name starting with an uppercase letter should only be used as a constructor.", | ||||
|             lower: "A constructor name should not start with a lowercase letter." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const config = Object.assign({}, context.options[0]); | ||||
|  | ||||
|         config.newIsCap = config.newIsCap !== false; | ||||
|         config.capIsNew = config.capIsNew !== false; | ||||
|         const skipProperties = config.properties === false; | ||||
|  | ||||
|         const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); | ||||
|         const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null; | ||||
|  | ||||
|         const capIsNewExceptions = calculateCapIsNewExceptions(config); | ||||
|         const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null; | ||||
|  | ||||
|         const listeners = {}; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Get exact callee name from expression | ||||
|          * @param {ASTNode} node CallExpression or NewExpression node | ||||
|          * @returns {string} name | ||||
|          */ | ||||
|         function extractNameFromExpression(node) { | ||||
|             return node.callee.type === "Identifier" | ||||
|                 ? node.callee.name | ||||
|                 : astUtils.getStaticPropertyName(node.callee) || ""; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the capitalization state of the string - | ||||
|          * Whether the first character is uppercase, lowercase, or non-alphabetic | ||||
|          * @param {string} str String | ||||
|          * @returns {string} capitalization state: "non-alpha", "lower", or "upper" | ||||
|          */ | ||||
|         function getCap(str) { | ||||
|             const firstChar = str.charAt(0); | ||||
|  | ||||
|             const firstCharLower = firstChar.toLowerCase(); | ||||
|             const firstCharUpper = firstChar.toUpperCase(); | ||||
|  | ||||
|             if (firstCharLower === firstCharUpper) { | ||||
|  | ||||
|                 // char has no uppercase variant, so it's non-alphabetic | ||||
|                 return "non-alpha"; | ||||
|             } | ||||
|             if (firstChar === firstCharLower) { | ||||
|                 return "lower"; | ||||
|             } | ||||
|             return "upper"; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check if capitalization is allowed for a CallExpression | ||||
|          * @param {Object} allowedMap Object mapping calleeName to a Boolean | ||||
|          * @param {ASTNode} node CallExpression node | ||||
|          * @param {string} calleeName Capitalized callee name from a CallExpression | ||||
|          * @param {Object} pattern RegExp object from options pattern | ||||
|          * @returns {boolean} Returns true if the callee may be capitalized | ||||
|          */ | ||||
|         function isCapAllowed(allowedMap, node, calleeName, pattern) { | ||||
|             const sourceText = sourceCode.getText(node.callee); | ||||
|  | ||||
|             if (allowedMap[calleeName] || allowedMap[sourceText]) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             if (pattern && pattern.test(sourceText)) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             const callee = astUtils.skipChainExpression(node.callee); | ||||
|  | ||||
|             if (calleeName === "UTC" && callee.type === "MemberExpression") { | ||||
|  | ||||
|                 // allow if callee is Date.UTC | ||||
|                 return callee.object.type === "Identifier" && | ||||
|                     callee.object.name === "Date"; | ||||
|             } | ||||
|  | ||||
|             return skipProperties && callee.type === "MemberExpression"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the given messageId for the given node. The location will be the start of the property or the callee. | ||||
|          * @param {ASTNode} node CallExpression or NewExpression node. | ||||
|          * @param {string} messageId The messageId to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(node, messageId) { | ||||
|             let callee = astUtils.skipChainExpression(node.callee); | ||||
|  | ||||
|             if (callee.type === "MemberExpression") { | ||||
|                 callee = callee.property; | ||||
|             } | ||||
|  | ||||
|             context.report({ node, loc: callee.loc, messageId }); | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         if (config.newIsCap) { | ||||
|             listeners.NewExpression = function(node) { | ||||
|  | ||||
|                 const constructorName = extractNameFromExpression(node); | ||||
|  | ||||
|                 if (constructorName) { | ||||
|                     const capitalization = getCap(constructorName); | ||||
|                     const isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern); | ||||
|  | ||||
|                     if (!isAllowed) { | ||||
|                         report(node, "lower"); | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         if (config.capIsNew) { | ||||
|             listeners.CallExpression = function(node) { | ||||
|  | ||||
|                 const calleeName = extractNameFromExpression(node); | ||||
|  | ||||
|                 if (calleeName) { | ||||
|                     const capitalization = getCap(calleeName); | ||||
|                     const isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern); | ||||
|  | ||||
|                     if (!isAllowed) { | ||||
|                         report(node, "upper"); | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return listeners; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										93
									
								
								node_modules/eslint/lib/rules/new-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								node_modules/eslint/lib/rules/new-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag when using constructor without parentheses | ||||
|  * @author Ilya Volodin | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Enforce or disallow parentheses when invoking a constructor with no arguments", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/new-parens" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["always", "never"] | ||||
|             } | ||||
|         ], | ||||
|         messages: { | ||||
|             missing: "Missing '()' invoking a constructor.", | ||||
|             unnecessary: "Unnecessary '()' invoking a constructor with no arguments." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options; | ||||
|         const always = options[0] !== "never"; // Default is always | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         return { | ||||
|             NewExpression(node) { | ||||
|                 if (node.arguments.length !== 0) { | ||||
|                     return; // if there are arguments, there have to be parens | ||||
|                 } | ||||
|  | ||||
|                 const lastToken = sourceCode.getLastToken(node); | ||||
|                 const hasLastParen = lastToken && astUtils.isClosingParenToken(lastToken); | ||||
|  | ||||
|                 // `hasParens` is true only if the new expression ends with its own parens, e.g., new new foo() does not end with its own parens | ||||
|                 const hasParens = hasLastParen && | ||||
|                     astUtils.isOpeningParenToken(sourceCode.getTokenBefore(lastToken)) && | ||||
|                     node.callee.range[1] < node.range[1]; | ||||
|  | ||||
|                 if (always) { | ||||
|                     if (!hasParens) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "missing", | ||||
|                             fix: fixer => fixer.insertTextAfter(node, "()") | ||||
|                         }); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (hasParens) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "unnecessary", | ||||
|                             fix: fixer => [ | ||||
|                                 fixer.remove(sourceCode.getTokenBefore(lastToken)), | ||||
|                                 fixer.remove(lastToken), | ||||
|                                 fixer.insertTextBefore(node, "("), | ||||
|                                 fixer.insertTextAfter(node, ")") | ||||
|                             ] | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										253
									
								
								node_modules/eslint/lib/rules/newline-after-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								node_modules/eslint/lib/rules/newline-after-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,253 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to check empty newline after "var" statement | ||||
|  * @author Gopal Venkatesan | ||||
|  * @deprecated in ESLint v4.0.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require or disallow an empty line after variable declarations", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/newline-after-var" | ||||
|         }, | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["never", "always"] | ||||
|             } | ||||
|         ], | ||||
|         fixable: "whitespace", | ||||
|         messages: { | ||||
|             expected: "Expected blank line after variable declarations.", | ||||
|             unexpected: "Unexpected blank line after variable declarations." | ||||
|         }, | ||||
|  | ||||
|         deprecated: true, | ||||
|  | ||||
|         replacedBy: ["padding-line-between-statements"] | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         // Default `mode` to "always". | ||||
|         const mode = context.options[0] === "never" ? "never" : "always"; | ||||
|  | ||||
|         // Cache starting and ending line numbers of comments for faster lookup | ||||
|         const commentEndLine = sourceCode.getAllComments().reduce((result, token) => { | ||||
|             result[token.loc.start.line] = token.loc.end.line; | ||||
|             return result; | ||||
|         }, {}); | ||||
|  | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Gets a token from the given node to compare line to the next statement. | ||||
|          * | ||||
|          * In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy. | ||||
|          * | ||||
|          * - The last token is semicolon. | ||||
|          * - The semicolon is on a different line from the previous token of the semicolon. | ||||
|          * | ||||
|          * This behavior would address semicolon-less style code. e.g.: | ||||
|          * | ||||
|          *     var foo = 1 | ||||
|          * | ||||
|          *     ;(a || b).doSomething() | ||||
|          * @param {ASTNode} node The node to get. | ||||
|          * @returns {Token} The token to compare line to the next statement. | ||||
|          */ | ||||
|         function getLastToken(node) { | ||||
|             const lastToken = sourceCode.getLastToken(node); | ||||
|  | ||||
|             if (lastToken.type === "Punctuator" && lastToken.value === ";") { | ||||
|                 const prevToken = sourceCode.getTokenBefore(lastToken); | ||||
|  | ||||
|                 if (prevToken.loc.end.line !== lastToken.loc.start.line) { | ||||
|                     return prevToken; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return lastToken; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if provided keyword is a variable declaration | ||||
|          * @private | ||||
|          * @param {string} keyword keyword to test | ||||
|          * @returns {boolean} True if `keyword` is a type of var | ||||
|          */ | ||||
|         function isVar(keyword) { | ||||
|             return keyword === "var" || keyword === "let" || keyword === "const"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if provided keyword is a variant of for specifiers | ||||
|          * @private | ||||
|          * @param {string} keyword keyword to test | ||||
|          * @returns {boolean} True if `keyword` is a variant of for specifier | ||||
|          */ | ||||
|         function isForTypeSpecifier(keyword) { | ||||
|             return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if provided keyword is an export specifiers | ||||
|          * @private | ||||
|          * @param {string} nodeType nodeType to test | ||||
|          * @returns {boolean} True if `nodeType` is an export specifier | ||||
|          */ | ||||
|         function isExportSpecifier(nodeType) { | ||||
|             return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" || | ||||
|                 nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if provided node is the last of their parent block. | ||||
|          * @private | ||||
|          * @param {ASTNode} node node to test | ||||
|          * @returns {boolean} True if `node` is last of their parent block. | ||||
|          */ | ||||
|         function isLastNode(node) { | ||||
|             const token = sourceCode.getTokenAfter(node); | ||||
|  | ||||
|             return !token || (token.type === "Punctuator" && token.value === "}"); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the last line of a group of consecutive comments | ||||
|          * @param {number} commentStartLine The starting line of the group | ||||
|          * @returns {number} The number of the last comment line of the group | ||||
|          */ | ||||
|         function getLastCommentLineOfBlock(commentStartLine) { | ||||
|             const currentCommentEnd = commentEndLine[commentStartLine]; | ||||
|  | ||||
|             return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Determine if a token starts more than one line after a comment ends | ||||
|          * @param {token} token The token being checked | ||||
|          * @param {integer} commentStartLine The line number on which the comment starts | ||||
|          * @returns {boolean} True if `token` does not start immediately after a comment | ||||
|          */ | ||||
|         function hasBlankLineAfterComment(token, commentStartLine) { | ||||
|             return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks that a blank line exists after a variable declaration when mode is | ||||
|          * set to "always", or checks that there is no blank line when mode is set | ||||
|          * to "never" | ||||
|          * @private | ||||
|          * @param {ASTNode} node `VariableDeclaration` node to test | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkForBlankLine(node) { | ||||
|  | ||||
|             /* | ||||
|              * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will | ||||
|              * sometimes be second-last if there is a semicolon on a different line. | ||||
|              */ | ||||
|             const lastToken = getLastToken(node), | ||||
|  | ||||
|                 /* | ||||
|                  * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken | ||||
|                  * is the last token of the node. | ||||
|                  */ | ||||
|                 nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), | ||||
|                 nextLineNum = lastToken.loc.end.line + 1; | ||||
|  | ||||
|             // Ignore if there is no following statement | ||||
|             if (!nextToken) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Ignore if parent of node is a for variant | ||||
|             if (isForTypeSpecifier(node.parent.type)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Ignore if parent of node is an export specifier | ||||
|             if (isExportSpecifier(node.parent.type)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Some coding styles use multiple `var` statements, so do nothing if | ||||
|              * the next token is a `var` statement. | ||||
|              */ | ||||
|             if (nextToken.type === "Keyword" && isVar(nextToken.value)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Ignore if it is last statement in a block | ||||
|             if (isLastNode(node)) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Next statement is not a `var`... | ||||
|             const noNextLineToken = nextToken.loc.start.line > nextLineNum; | ||||
|             const hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined"); | ||||
|  | ||||
|             if (mode === "never" && noNextLineToken && !hasNextLineComment) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "unexpected", | ||||
|                     fix(fixer) { | ||||
|                         const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER); | ||||
|  | ||||
|                         return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // Token on the next line, or comment without blank line | ||||
|             if ( | ||||
|                 mode === "always" && ( | ||||
|                     !noNextLineToken || | ||||
|                     hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum) | ||||
|                 ) | ||||
|             ) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "expected", | ||||
|                     fix(fixer) { | ||||
|                         if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { | ||||
|                             return fixer.insertTextBefore(nextToken, "\n\n"); | ||||
|                         } | ||||
|  | ||||
|                         return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             VariableDeclaration: checkForBlankLine | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										217
									
								
								node_modules/eslint/lib/rules/newline-before-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								node_modules/eslint/lib/rules/newline-before-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to require newlines before `return` statement | ||||
|  * @author Kai Cataldo | ||||
|  * @deprecated in ESLint v4.0.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require an empty line before `return` statements", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/newline-before-return" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|         schema: [], | ||||
|         messages: { | ||||
|             expected: "Expected newline before return statement." | ||||
|         }, | ||||
|  | ||||
|         deprecated: true, | ||||
|         replacedBy: ["padding-line-between-statements"] | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Tests whether node is preceded by supplied tokens | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @param {Array} testTokens array of tokens to test against | ||||
|          * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens | ||||
|          * @private | ||||
|          */ | ||||
|         function isPrecededByTokens(node, testTokens) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(node); | ||||
|  | ||||
|             return testTokens.includes(tokenBefore.value); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether node is the first node after statement or in block | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @returns {boolean} Whether or not the node is the first node after statement or in block | ||||
|          * @private | ||||
|          */ | ||||
|         function isFirstNode(node) { | ||||
|             const parentType = node.parent.type; | ||||
|  | ||||
|             if (node.parent.body) { | ||||
|                 return Array.isArray(node.parent.body) | ||||
|                     ? node.parent.body[0] === node | ||||
|                     : node.parent.body === node; | ||||
|             } | ||||
|  | ||||
|             if (parentType === "IfStatement") { | ||||
|                 return isPrecededByTokens(node, ["else", ")"]); | ||||
|             } | ||||
|             if (parentType === "DoWhileStatement") { | ||||
|                 return isPrecededByTokens(node, ["do"]); | ||||
|             } | ||||
|             if (parentType === "SwitchCase") { | ||||
|                 return isPrecededByTokens(node, [":"]); | ||||
|             } | ||||
|             return isPrecededByTokens(node, [")"]); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the number of lines of comments that precede the node | ||||
|          * @param {ASTNode} node node to check for overlapping comments | ||||
|          * @param {number} lineNumTokenBefore line number of previous token, to check for overlapping comments | ||||
|          * @returns {number} Number of lines of comments that precede the node | ||||
|          * @private | ||||
|          */ | ||||
|         function calcCommentLines(node, lineNumTokenBefore) { | ||||
|             const comments = sourceCode.getCommentsBefore(node); | ||||
|             let numLinesComments = 0; | ||||
|  | ||||
|             if (!comments.length) { | ||||
|                 return numLinesComments; | ||||
|             } | ||||
|  | ||||
|             comments.forEach(comment => { | ||||
|                 numLinesComments++; | ||||
|  | ||||
|                 if (comment.type === "Block") { | ||||
|                     numLinesComments += comment.loc.end.line - comment.loc.start.line; | ||||
|                 } | ||||
|  | ||||
|                 // avoid counting lines with inline comments twice | ||||
|                 if (comment.loc.start.line === lineNumTokenBefore) { | ||||
|                     numLinesComments--; | ||||
|                 } | ||||
|  | ||||
|                 if (comment.loc.end.line === node.loc.start.line) { | ||||
|                     numLinesComments--; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             return numLinesComments; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Returns the line number of the token before the node that is passed in as an argument | ||||
|          * @param {ASTNode} node The node to use as the start of the calculation | ||||
|          * @returns {number} Line number of the token before `node` | ||||
|          * @private | ||||
|          */ | ||||
|         function getLineNumberOfTokenBefore(node) { | ||||
|             const tokenBefore = sourceCode.getTokenBefore(node); | ||||
|             let lineNumTokenBefore; | ||||
|  | ||||
|             /** | ||||
|              * Global return (at the beginning of a script) is a special case. | ||||
|              * If there is no token before `return`, then we expect no line | ||||
|              * break before the return. Comments are allowed to occupy lines | ||||
|              * before the global return, just no blank lines. | ||||
|              * Setting lineNumTokenBefore to zero in that case results in the | ||||
|              * desired behavior. | ||||
|              */ | ||||
|             if (tokenBefore) { | ||||
|                 lineNumTokenBefore = tokenBefore.loc.end.line; | ||||
|             } else { | ||||
|                 lineNumTokenBefore = 0; // global return at beginning of script | ||||
|             } | ||||
|  | ||||
|             return lineNumTokenBefore; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether node is preceded by a newline | ||||
|          * @param {ASTNode} node node to check | ||||
|          * @returns {boolean} Whether or not the node is preceded by a newline | ||||
|          * @private | ||||
|          */ | ||||
|         function hasNewlineBefore(node) { | ||||
|             const lineNumNode = node.loc.start.line; | ||||
|             const lineNumTokenBefore = getLineNumberOfTokenBefore(node); | ||||
|             const commentLines = calcCommentLines(node, lineNumTokenBefore); | ||||
|  | ||||
|             return (lineNumNode - lineNumTokenBefore - commentLines) > 1; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether it is safe to apply a fix to a given return statement. | ||||
|          * | ||||
|          * The fix is not considered safe if the given return statement has leading comments, | ||||
|          * as we cannot safely determine if the newline should be added before or after the comments. | ||||
|          * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211 | ||||
|          * @param {ASTNode} node The return statement node to check. | ||||
|          * @returns {boolean} `true` if it can fix the node. | ||||
|          * @private | ||||
|          */ | ||||
|         function canFix(node) { | ||||
|             const leadingComments = sourceCode.getCommentsBefore(node); | ||||
|             const lastLeadingComment = leadingComments[leadingComments.length - 1]; | ||||
|             const tokenBefore = sourceCode.getTokenBefore(node); | ||||
|  | ||||
|             if (leadingComments.length === 0) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * if the last leading comment ends in the same line as the previous token and | ||||
|              * does not share a line with the `return` node, we can consider it safe to fix. | ||||
|              * Example: | ||||
|              * function a() { | ||||
|              *     var b; //comment | ||||
|              *     return; | ||||
|              * } | ||||
|              */ | ||||
|             if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line && | ||||
|                 lastLeadingComment.loc.end.line !== node.loc.start.line) { | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ReturnStatement(node) { | ||||
|                 if (!isFirstNode(node) && !hasNewlineBefore(node)) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: "expected", | ||||
|                         fix(fixer) { | ||||
|                             if (canFix(node)) { | ||||
|                                 const tokenBefore = sourceCode.getTokenBefore(node); | ||||
|                                 const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n"; | ||||
|  | ||||
|                                 return fixer.insertTextBefore(node, newlines); | ||||
|                             } | ||||
|                             return null; | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										126
									
								
								node_modules/eslint/lib/rules/newline-per-chained-call.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								node_modules/eslint/lib/rules/newline-per-chained-call.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to ensure newline per method call when chaining calls | ||||
|  * @author Rajendra Patil | ||||
|  * @author Burak Yigit Kaya | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "layout", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Require a newline after each call in a method chain", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/newline-per-chained-call" | ||||
|         }, | ||||
|  | ||||
|         fixable: "whitespace", | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 ignoreChainWithDepth: { | ||||
|                     type: "integer", | ||||
|                     minimum: 1, | ||||
|                     maximum: 10, | ||||
|                     default: 2 | ||||
|                 } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|         messages: { | ||||
|             expected: "Expected line break before `{{callee}}`." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const options = context.options[0] || {}, | ||||
|             ignoreChainWithDepth = options.ignoreChainWithDepth || 2; | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Get the prefix of a given MemberExpression node. | ||||
|          * If the MemberExpression node is a computed value it returns a | ||||
|          * left bracket. If not it returns a period. | ||||
|          * @param {ASTNode} node A MemberExpression node to get | ||||
|          * @returns {string} The prefix of the node. | ||||
|          */ | ||||
|         function getPrefix(node) { | ||||
|             if (node.computed) { | ||||
|                 if (node.optional) { | ||||
|                     return "?.["; | ||||
|                 } | ||||
|                 return "["; | ||||
|             } | ||||
|             if (node.optional) { | ||||
|                 return "?."; | ||||
|             } | ||||
|             return "."; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Gets the property text of a given MemberExpression node. | ||||
|          * If the text is multiline, this returns only the first line. | ||||
|          * @param {ASTNode} node A MemberExpression node to get. | ||||
|          * @returns {string} The property text of the node. | ||||
|          */ | ||||
|         function getPropertyText(node) { | ||||
|             const prefix = getPrefix(node); | ||||
|             const lines = sourceCode.getText(node.property).split(astUtils.LINEBREAK_MATCHER); | ||||
|             const suffix = node.computed && lines.length === 1 ? "]" : ""; | ||||
|  | ||||
|             return prefix + lines[0] + suffix; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "CallExpression:exit"(node) { | ||||
|                 const callee = astUtils.skipChainExpression(node.callee); | ||||
|  | ||||
|                 if (callee.type !== "MemberExpression") { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 let parent = astUtils.skipChainExpression(callee.object); | ||||
|                 let depth = 1; | ||||
|  | ||||
|                 while (parent && parent.callee) { | ||||
|                     depth += 1; | ||||
|                     parent = astUtils.skipChainExpression(astUtils.skipChainExpression(parent.callee).object); | ||||
|                 } | ||||
|  | ||||
|                 if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) { | ||||
|                     const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); | ||||
|  | ||||
|                     context.report({ | ||||
|                         node: callee.property, | ||||
|                         loc: { | ||||
|                             start: firstTokenAfterObject.loc.start, | ||||
|                             end: callee.loc.end | ||||
|                         }, | ||||
|                         messageId: "expected", | ||||
|                         data: { | ||||
|                             callee: getPropertyText(callee) | ||||
|                         }, | ||||
|                         fix(fixer) { | ||||
|                             return fixer.insertTextBefore(firstTokenAfterObject, "\n"); | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										138
									
								
								node_modules/eslint/lib/rules/no-alert.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								node_modules/eslint/lib/rules/no-alert.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of alert, confirm, prompt | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const { | ||||
|     getStaticPropertyName: getPropertyName, | ||||
|     getVariableByName, | ||||
|     skipChainExpression | ||||
| } = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks if the given name is a prohibited identifier. | ||||
|  * @param {string} name The name to check | ||||
|  * @returns {boolean} Whether or not the name is prohibited. | ||||
|  */ | ||||
| function isProhibitedIdentifier(name) { | ||||
|     return /^(alert|confirm|prompt)$/u.test(name); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Finds the eslint-scope reference in the given scope. | ||||
|  * @param {Object} scope The scope to search. | ||||
|  * @param {ASTNode} node The identifier node. | ||||
|  * @returns {Reference|null} Returns the found reference or null if none were found. | ||||
|  */ | ||||
| function findReference(scope, node) { | ||||
|     const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && | ||||
|             reference.identifier.range[1] === node.range[1]); | ||||
|  | ||||
|     if (references.length === 1) { | ||||
|         return references[0]; | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if the given identifier node is shadowed in the given scope. | ||||
|  * @param {Object} scope The current scope. | ||||
|  * @param {string} node The identifier node to check | ||||
|  * @returns {boolean} Whether or not the name is shadowed. | ||||
|  */ | ||||
| function isShadowed(scope, node) { | ||||
|     const reference = findReference(scope, node); | ||||
|  | ||||
|     return reference && reference.resolved && reference.resolved.defs.length > 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if the given identifier node is a ThisExpression in the global scope or the global window property. | ||||
|  * @param {Object} scope The current scope. | ||||
|  * @param {string} node The identifier node to check | ||||
|  * @returns {boolean} Whether or not the node is a reference to the global object. | ||||
|  */ | ||||
| function isGlobalThisReferenceOrGlobalWindow(scope, node) { | ||||
|     if (scope.type === "global" && node.type === "ThisExpression") { | ||||
|         return true; | ||||
|     } | ||||
|     if ( | ||||
|         node.type === "Identifier" && | ||||
|         ( | ||||
|             node.name === "window" || | ||||
|             (node.name === "globalThis" && getVariableByName(scope, "globalThis")) | ||||
|         ) | ||||
|     ) { | ||||
|         return !isShadowed(scope, node); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow the use of `alert`, `confirm`, and `prompt`", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-alert" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected {{name}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         return { | ||||
|             CallExpression(node) { | ||||
|                 const callee = skipChainExpression(node.callee), | ||||
|                     currentScope = sourceCode.getScope(node); | ||||
|  | ||||
|                 // without window. | ||||
|                 if (callee.type === "Identifier") { | ||||
|                     const name = callee.name; | ||||
|  | ||||
|                     if (!isShadowed(currentScope, callee) && isProhibitedIdentifier(callee.name)) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "unexpected", | ||||
|                             data: { name } | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                 } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) { | ||||
|                     const name = getPropertyName(callee); | ||||
|  | ||||
|                     if (isProhibitedIdentifier(name)) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "unexpected", | ||||
|                             data: { name } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										133
									
								
								node_modules/eslint/lib/rules/no-array-constructor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								node_modules/eslint/lib/rules/no-array-constructor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| /** | ||||
|  * @fileoverview Disallow construction of dense arrays using the Array constructor | ||||
|  * @author Matt DuVall <http://www.mattduvall.com/> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const { | ||||
|     getVariableByName, | ||||
|     isClosingParenToken, | ||||
|     isOpeningParenToken, | ||||
|     isStartOfExpressionStatement, | ||||
|     needsPrecedingSemicolon | ||||
| } = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow `Array` constructors", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-array-constructor" | ||||
|         }, | ||||
|  | ||||
|         hasSuggestions: true, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             preferLiteral: "The array literal notation [] is preferable.", | ||||
|             useLiteral: "Replace with an array literal.", | ||||
|             useLiteralAfterSemicolon: "Replace with an array literal, add preceding semicolon." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Gets the text between the calling parentheses of a CallExpression or NewExpression. | ||||
|          * @param {ASTNode} node A CallExpression or NewExpression node. | ||||
|          * @returns {string} The text between the calling parentheses, or an empty string if there are none. | ||||
|          */ | ||||
|         function getArgumentsText(node) { | ||||
|             const lastToken = sourceCode.getLastToken(node); | ||||
|  | ||||
|             if (!isClosingParenToken(lastToken)) { | ||||
|                 return ""; | ||||
|             } | ||||
|  | ||||
|             let firstToken = node.callee; | ||||
|  | ||||
|             do { | ||||
|                 firstToken = sourceCode.getTokenAfter(firstToken); | ||||
|                 if (!firstToken || firstToken === lastToken) { | ||||
|                     return ""; | ||||
|                 } | ||||
|             } while (!isOpeningParenToken(firstToken)); | ||||
|  | ||||
|             return sourceCode.text.slice(firstToken.range[1], lastToken.range[0]); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Disallow construction of dense arrays using the Array constructor | ||||
|          * @param {ASTNode} node node to evaluate | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function check(node) { | ||||
|             if ( | ||||
|                 node.callee.type !== "Identifier" || | ||||
|                 node.callee.name !== "Array" || | ||||
|                 node.arguments.length === 1 && | ||||
|                 node.arguments[0].type !== "SpreadElement") { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             const variable = getVariableByName(sourceCode.getScope(node), "Array"); | ||||
|  | ||||
|             /* | ||||
|              * Check if `Array` is a predefined global variable: predefined globals have no declarations, | ||||
|              * meaning that the `identifiers` list of the variable object is empty. | ||||
|              */ | ||||
|             if (variable && variable.identifiers.length === 0) { | ||||
|                 const argsText = getArgumentsText(node); | ||||
|                 let fixText; | ||||
|                 let messageId; | ||||
|  | ||||
|                 /* | ||||
|                  * Check if the suggested change should include a preceding semicolon or not. | ||||
|                  * Due to JavaScript's ASI rules, a missing semicolon may be inserted automatically | ||||
|                  * before an expression like `Array()` or `new Array()`, but not when the expression | ||||
|                  * is changed into an array literal like `[]`. | ||||
|                  */ | ||||
|                 if (isStartOfExpressionStatement(node) && needsPrecedingSemicolon(sourceCode, node)) { | ||||
|                     fixText = `;[${argsText}]`; | ||||
|                     messageId = "useLiteralAfterSemicolon"; | ||||
|                 } else { | ||||
|                     fixText = `[${argsText}]`; | ||||
|                     messageId = "useLiteral"; | ||||
|                 } | ||||
|  | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "preferLiteral", | ||||
|                     suggest: [ | ||||
|                         { | ||||
|                             messageId, | ||||
|                             fix: fixer => fixer.replaceText(node, fixText) | ||||
|                         } | ||||
|                     ] | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             CallExpression: check, | ||||
|             NewExpression: check | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										39
									
								
								node_modules/eslint/lib/rules/no-async-promise-executor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								node_modules/eslint/lib/rules/no-async-promise-executor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| /** | ||||
|  * @fileoverview disallow using an async function as a Promise executor | ||||
|  * @author Teddy Katz | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow using an async function as a Promise executor", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-async-promise-executor" | ||||
|         }, | ||||
|  | ||||
|         fixable: null, | ||||
|         schema: [], | ||||
|         messages: { | ||||
|             async: "Promise executor functions should not be async." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         return { | ||||
|             "NewExpression[callee.name='Promise'][arguments.0.async=true]"(node) { | ||||
|                 context.report({ | ||||
|                     node: context.sourceCode.getFirstToken(node.arguments[0], token => token.value === "async"), | ||||
|                     messageId: "async" | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										106
									
								
								node_modules/eslint/lib/rules/no-await-in-loop.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								node_modules/eslint/lib/rules/no-await-in-loop.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to disallow uses of await inside of loops. | ||||
|  * @author Nat Mote (nmote) | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| /** | ||||
|  * Check whether it should stop traversing ancestors at the given node. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} `true` if it should stop traversing. | ||||
|  */ | ||||
| function isBoundary(node) { | ||||
|     const t = node.type; | ||||
|  | ||||
|     return ( | ||||
|         t === "FunctionDeclaration" || | ||||
|         t === "FunctionExpression" || | ||||
|         t === "ArrowFunctionExpression" || | ||||
|  | ||||
|         /* | ||||
|          * Don't report the await expressions on for-await-of loop since it's | ||||
|          * asynchronous iteration intentionally. | ||||
|          */ | ||||
|         (t === "ForOfStatement" && node.await === true) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Check whether the given node is in loop. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @param {ASTNode} parent A parent node to check. | ||||
|  * @returns {boolean} `true` if the node is in loop. | ||||
|  */ | ||||
| function isLooped(node, parent) { | ||||
|     switch (parent.type) { | ||||
|         case "ForStatement": | ||||
|             return ( | ||||
|                 node === parent.test || | ||||
|                 node === parent.update || | ||||
|                 node === parent.body | ||||
|             ); | ||||
|  | ||||
|         case "ForOfStatement": | ||||
|         case "ForInStatement": | ||||
|             return node === parent.body; | ||||
|  | ||||
|         case "WhileStatement": | ||||
|         case "DoWhileStatement": | ||||
|             return node === parent.test || node === parent.body; | ||||
|  | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow `await` inside of loops", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-await-in-loop" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpectedAwait: "Unexpected `await` inside a loop." | ||||
|         } | ||||
|     }, | ||||
|     create(context) { | ||||
|  | ||||
|         /** | ||||
|          * Validate an await expression. | ||||
|          * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function validate(awaitNode) { | ||||
|             if (awaitNode.type === "ForOfStatement" && !awaitNode.await) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             let node = awaitNode; | ||||
|             let parent = node.parent; | ||||
|  | ||||
|             while (parent && !isBoundary(parent)) { | ||||
|                 if (isLooped(node, parent)) { | ||||
|                     context.report({ | ||||
|                         node: awaitNode, | ||||
|                         messageId: "unexpectedAwait" | ||||
|                     }); | ||||
|                     return; | ||||
|                 } | ||||
|                 node = parent; | ||||
|                 parent = parent.parent; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             AwaitExpression: validate, | ||||
|             ForOfStatement: validate | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										119
									
								
								node_modules/eslint/lib/rules/no-bitwise.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								node_modules/eslint/lib/rules/no-bitwise.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag bitwise identifiers | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| /* | ||||
|  * | ||||
|  * Set of bitwise operators. | ||||
|  * | ||||
|  */ | ||||
| const BITWISE_OPERATORS = [ | ||||
|     "^", "|", "&", "<<", ">>", ">>>", | ||||
|     "^=", "|=", "&=", "<<=", ">>=", ">>>=", | ||||
|     "~" | ||||
| ]; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow bitwise operators", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-bitwise" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allow: { | ||||
|                         type: "array", | ||||
|                         items: { | ||||
|                             enum: BITWISE_OPERATORS | ||||
|                         }, | ||||
|                         uniqueItems: true | ||||
|                     }, | ||||
|                     int32Hint: { | ||||
|                         type: "boolean", | ||||
|                         default: false | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected use of '{{operator}}'." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const allowed = options.allow || []; | ||||
|         const int32Hint = options.int32Hint === true; | ||||
|  | ||||
|         /** | ||||
|          * Reports an unexpected use of a bitwise operator. | ||||
|          * @param {ASTNode} node Node which contains the bitwise operator. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(node) { | ||||
|             context.report({ node, messageId: "unexpected", data: { operator: node.operator } }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given node has a bitwise operator. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} Whether or not the node has a bitwise operator. | ||||
|          */ | ||||
|         function hasBitwiseOperator(node) { | ||||
|             return BITWISE_OPERATORS.includes(node.operator); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} Whether or not the node has a bitwise operator. | ||||
|          */ | ||||
|         function allowedOperator(node) { | ||||
|             return allowed.includes(node.operator); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {boolean} whether the node is used in integer typecasting. | ||||
|          */ | ||||
|         function isInt32Hint(node) { | ||||
|             return int32Hint && node.operator === "|" && node.right && | ||||
|               node.right.type === "Literal" && node.right.value === 0; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Report if the given node contains a bitwise operator. | ||||
|          * @param {ASTNode} node The node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkNodeForBitwiseOperator(node) { | ||||
|             if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { | ||||
|                 report(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             AssignmentExpression: checkNodeForBitwiseOperator, | ||||
|             BinaryExpression: checkNodeForBitwiseOperator, | ||||
|             UnaryExpression: checkNodeForBitwiseOperator | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										50
									
								
								node_modules/eslint/lib/rules/no-buffer-constructor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								node_modules/eslint/lib/rules/no-buffer-constructor.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| /** | ||||
|  * @fileoverview disallow use of the Buffer() constructor | ||||
|  * @author Teddy Katz | ||||
|  * @deprecated in ESLint v7.0.0 | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|  | ||||
|         replacedBy: [], | ||||
|  | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow use of the `Buffer()` constructor", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-buffer-constructor" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             deprecated: "{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //---------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //---------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             "CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']"(node) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "deprecated", | ||||
|                     data: { expr: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" } | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										46
									
								
								node_modules/eslint/lib/rules/no-caller.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								node_modules/eslint/lib/rules/no-caller.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of arguments.callee and arguments.caller. | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow the use of `arguments.caller` or `arguments.callee`", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-caller" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Avoid arguments.{{prop}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             MemberExpression(node) { | ||||
|                 const objectName = node.object.name, | ||||
|                     propertyName = node.property.name; | ||||
|  | ||||
|                 if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/u)) { | ||||
|                     context.report({ node, messageId: "unexpected", data: { prop: propertyName } }); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										64
									
								
								node_modules/eslint/lib/rules/no-case-declarations.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								node_modules/eslint/lib/rules/no-case-declarations.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of an lexical declarations inside a case clause | ||||
|  * @author Erik Arvidsson | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow lexical declarations in case clauses", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-case-declarations" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected lexical declaration in case block." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /** | ||||
|          * Checks whether or not a node is a lexical declaration. | ||||
|          * @param {ASTNode} node A direct child statement of a switch case. | ||||
|          * @returns {boolean} Whether or not the node is a lexical declaration. | ||||
|          */ | ||||
|         function isLexicalDeclaration(node) { | ||||
|             switch (node.type) { | ||||
|                 case "FunctionDeclaration": | ||||
|                 case "ClassDeclaration": | ||||
|                     return true; | ||||
|                 case "VariableDeclaration": | ||||
|                     return node.kind !== "var"; | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             SwitchCase(node) { | ||||
|                 for (let i = 0; i < node.consequent.length; i++) { | ||||
|                     const statement = node.consequent[i]; | ||||
|  | ||||
|                     if (isLexicalDeclaration(statement)) { | ||||
|                         context.report({ | ||||
|                             node: statement, | ||||
|                             messageId: "unexpected" | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										82
									
								
								node_modules/eslint/lib/rules/no-catch-shadow.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								node_modules/eslint/lib/rules/no-catch-shadow.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier | ||||
|  * @author Ian Christian Myers | ||||
|  * @deprecated in ESLint v5.1.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow `catch` clause parameters from shadowing variables in the outer scope", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-catch-shadow" | ||||
|         }, | ||||
|  | ||||
|         replacedBy: ["no-shadow"], | ||||
|  | ||||
|         deprecated: true, | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             mutable: "Value of '{{name}}' may be overwritten in IE 8 and earlier." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Check if the parameters are been shadowed | ||||
|          * @param {Object} scope current scope | ||||
|          * @param {string} name parameter name | ||||
|          * @returns {boolean} True is its been shadowed | ||||
|          */ | ||||
|         function paramIsShadowing(scope, name) { | ||||
|             return astUtils.getVariableByName(scope, name) !== null; | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public API | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             "CatchClause[param!=null]"(node) { | ||||
|                 let scope = sourceCode.getScope(node); | ||||
|  | ||||
|                 /* | ||||
|                  * When ecmaVersion >= 6, CatchClause creates its own scope | ||||
|                  * so start from one upper scope to exclude the current node | ||||
|                  */ | ||||
|                 if (scope.block === node) { | ||||
|                     scope = scope.upper; | ||||
|                 } | ||||
|  | ||||
|                 if (paramIsShadowing(scope, node.param.name)) { | ||||
|                     context.report({ node, messageId: "mutable", data: { name: node.param.name } }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										63
									
								
								node_modules/eslint/lib/rules/no-class-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								node_modules/eslint/lib/rules/no-class-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to disallow modifying variables of class declarations | ||||
|  * @author Toru Nagashima | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow reassigning class members", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-class-assign" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             class: "'{{name}}' is a class." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Finds and reports references that are non initializer and writable. | ||||
|          * @param {Variable} variable A variable to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkVariable(variable) { | ||||
|             astUtils.getModifyingReferences(variable.references).forEach(reference => { | ||||
|                 context.report({ node: reference.identifier, messageId: "class", data: { name: reference.identifier.name } }); | ||||
|  | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Finds and reports references that are non initializer and writable. | ||||
|          * @param {ASTNode} node A ClassDeclaration/ClassExpression node to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkForClass(node) { | ||||
|             sourceCode.getDeclaredVariables(node).forEach(checkVariable); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ClassDeclaration: checkForClass, | ||||
|             ClassExpression: checkForClass | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										60
									
								
								node_modules/eslint/lib/rules/no-compare-neg-zero.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								node_modules/eslint/lib/rules/no-compare-neg-zero.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| /** | ||||
|  * @fileoverview The rule should warn against code that tries to compare against -0. | ||||
|  * @author Aladdin-ADD <hh_2013@foxmail.com> | ||||
|  */ | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow comparing against -0", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-compare-neg-zero" | ||||
|         }, | ||||
|  | ||||
|         fixable: null, | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Do not use the '{{operator}}' operator to compare against -0." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Checks a given node is -0 | ||||
|          * @param {ASTNode} node A node to check. | ||||
|          * @returns {boolean} `true` if the node is -0. | ||||
|          */ | ||||
|         function isNegZero(node) { | ||||
|             return node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "Literal" && node.argument.value === 0; | ||||
|         } | ||||
|         const OPERATORS_TO_CHECK = new Set([">", ">=", "<", "<=", "==", "===", "!=", "!=="]); | ||||
|  | ||||
|         return { | ||||
|             BinaryExpression(node) { | ||||
|                 if (OPERATORS_TO_CHECK.has(node.operator)) { | ||||
|                     if (isNegZero(node.left) || isNegZero(node.right)) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "unexpected", | ||||
|                             data: { operator: node.operator } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										159
									
								
								node_modules/eslint/lib/rules/no-cond-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								node_modules/eslint/lib/rules/no-cond-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag assignment in a conditional statement's test expression | ||||
|  * @author Stephen Murray <spmurrayzzz> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const TEST_CONDITION_PARENT_TYPES = new Set(["IfStatement", "WhileStatement", "DoWhileStatement", "ForStatement", "ConditionalExpression"]); | ||||
|  | ||||
| const NODE_DESCRIPTIONS = { | ||||
|     DoWhileStatement: "a 'do...while' statement", | ||||
|     ForStatement: "a 'for' statement", | ||||
|     IfStatement: "an 'if' statement", | ||||
|     WhileStatement: "a 'while' statement" | ||||
| }; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow assignment operators in conditional expressions", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-cond-assign" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 enum: ["except-parens", "always"] | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected assignment within {{type}}.", | ||||
|  | ||||
|             // must match JSHint's error message | ||||
|             missing: "Expected a conditional expression and instead saw an assignment." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const prohibitAssign = (context.options[0] || "except-parens"); | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Check whether an AST node is the test expression for a conditional statement. | ||||
|          * @param {!Object} node The node to test. | ||||
|          * @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`. | ||||
|          */ | ||||
|         function isConditionalTestExpression(node) { | ||||
|             return node.parent && | ||||
|                 TEST_CONDITION_PARENT_TYPES.has(node.parent.type) && | ||||
|                 node === node.parent.test; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement. | ||||
|          * @param {!Object} node The node to use at the start of the search. | ||||
|          * @returns {?Object} The closest ancestor node that represents a conditional statement. | ||||
|          */ | ||||
|         function findConditionalAncestor(node) { | ||||
|             let currentAncestor = node; | ||||
|  | ||||
|             do { | ||||
|                 if (isConditionalTestExpression(currentAncestor)) { | ||||
|                     return currentAncestor.parent; | ||||
|                 } | ||||
|             } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor)); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check whether the code represented by an AST node is enclosed in two sets of parentheses. | ||||
|          * @param {!Object} node The node to test. | ||||
|          * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. | ||||
|          */ | ||||
|         function isParenthesisedTwice(node) { | ||||
|             const previousToken = sourceCode.getTokenBefore(node, 1), | ||||
|                 nextToken = sourceCode.getTokenAfter(node, 1); | ||||
|  | ||||
|             return astUtils.isParenthesised(sourceCode, node) && | ||||
|                 previousToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && | ||||
|                 astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses. | ||||
|          * @param {!Object} node The node for the conditional statement. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function testForAssign(node) { | ||||
|             if (node.test && | ||||
|                 (node.test.type === "AssignmentExpression") && | ||||
|                 (node.type === "ForStatement" | ||||
|                     ? !astUtils.isParenthesised(sourceCode, node.test) | ||||
|                     : !isParenthesisedTwice(node.test) | ||||
|                 ) | ||||
|             ) { | ||||
|  | ||||
|                 context.report({ | ||||
|                     node: node.test, | ||||
|                     messageId: "missing" | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Check whether an assignment expression is descended from a conditional statement's test expression. | ||||
|          * @param {!Object} node The node for the assignment expression. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function testForConditionalAncestor(node) { | ||||
|             const ancestor = findConditionalAncestor(node); | ||||
|  | ||||
|             if (ancestor) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "unexpected", | ||||
|                     data: { | ||||
|                         type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (prohibitAssign === "always") { | ||||
|             return { | ||||
|                 AssignmentExpression: testForConditionalAncestor | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             DoWhileStatement: testForAssign, | ||||
|             ForStatement: testForAssign, | ||||
|             IfStatement: testForAssign, | ||||
|             WhileStatement: testForAssign, | ||||
|             ConditionalExpression: testForAssign | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										92
									
								
								node_modules/eslint/lib/rules/no-confusing-arrow.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								node_modules/eslint/lib/rules/no-confusing-arrow.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to warn against using arrow functions when they could be | ||||
|  * confused with comparisons | ||||
|  * @author Jxck <https://github.com/Jxck> | ||||
|  * @deprecated in ESLint v8.53.0 | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils.js"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a node is a conditional expression. | ||||
|  * @param {ASTNode} node node to test | ||||
|  * @returns {boolean} `true` if the node is a conditional expression. | ||||
|  */ | ||||
| function isConditional(node) { | ||||
|     return node && node.type === "ConditionalExpression"; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         deprecated: true, | ||||
|         replacedBy: [], | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow arrow functions where they could be confused with comparisons", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-confusing-arrow" | ||||
|         }, | ||||
|  | ||||
|         fixable: "code", | ||||
|  | ||||
|         schema: [{ | ||||
|             type: "object", | ||||
|             properties: { | ||||
|                 allowParens: { type: "boolean", default: true }, | ||||
|                 onlyOneSimpleParam: { type: "boolean", default: false } | ||||
|             }, | ||||
|             additionalProperties: false | ||||
|         }], | ||||
|  | ||||
|         messages: { | ||||
|             confusing: "Arrow function used ambiguously with a conditional expression." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const config = context.options[0] || {}; | ||||
|         const allowParens = config.allowParens || (config.allowParens === void 0); | ||||
|         const onlyOneSimpleParam = config.onlyOneSimpleParam; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|  | ||||
|         /** | ||||
|          * Reports if an arrow function contains an ambiguous conditional. | ||||
|          * @param {ASTNode} node A node to check and report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkArrowFunc(node) { | ||||
|             const body = node.body; | ||||
|  | ||||
|             if (isConditional(body) && | ||||
|                 !(allowParens && astUtils.isParenthesised(sourceCode, body)) && | ||||
|                 !(onlyOneSimpleParam && !(node.params.length === 1 && node.params[0].type === "Identifier"))) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "confusing", | ||||
|                     fix(fixer) { | ||||
|  | ||||
|                         // if `allowParens` is not set to true don't bother wrapping in parens | ||||
|                         return allowParens && fixer.replaceText(node.body, `(${sourceCode.getText(node.body)})`); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             ArrowFunctionExpression: checkArrowFunc | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										207
									
								
								node_modules/eslint/lib/rules/no-console.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								node_modules/eslint/lib/rules/no-console.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,207 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of console object | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Requirements | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow the use of `console`", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-console" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     allow: { | ||||
|                         type: "array", | ||||
|                         items: { | ||||
|                             type: "string" | ||||
|                         }, | ||||
|                         minItems: 1, | ||||
|                         uniqueItems: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         hasSuggestions: true, | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected console statement.", | ||||
|             removeConsole: "Remove the console.{{ propertyName }}()." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}; | ||||
|         const allowed = options.allow || []; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given reference is 'console' or not. | ||||
|          * @param {eslint-scope.Reference} reference The reference to check. | ||||
|          * @returns {boolean} `true` if the reference is 'console'. | ||||
|          */ | ||||
|         function isConsole(reference) { | ||||
|             const id = reference.identifier; | ||||
|  | ||||
|             return id && id.name === "console"; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the property name of the given MemberExpression node | ||||
|          * is allowed by options or not. | ||||
|          * @param {ASTNode} node The MemberExpression node to check. | ||||
|          * @returns {boolean} `true` if the property name of the node is allowed. | ||||
|          */ | ||||
|         function isAllowed(node) { | ||||
|             const propertyName = astUtils.getStaticPropertyName(node); | ||||
|  | ||||
|             return propertyName && allowed.includes(propertyName); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks whether the given reference is a member access which is not | ||||
|          * allowed by options or not. | ||||
|          * @param {eslint-scope.Reference} reference The reference to check. | ||||
|          * @returns {boolean} `true` if the reference is a member access which | ||||
|          *      is not allowed by options. | ||||
|          */ | ||||
|         function isMemberAccessExceptAllowed(reference) { | ||||
|             const node = reference.identifier; | ||||
|             const parent = node.parent; | ||||
|  | ||||
|             return ( | ||||
|                 parent.type === "MemberExpression" && | ||||
|                 parent.object === node && | ||||
|                 !isAllowed(parent) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if removing the ExpressionStatement node will cause ASI to | ||||
|          * break. | ||||
|          * eg. | ||||
|          * foo() | ||||
|          * console.log(); | ||||
|          * [1, 2, 3].forEach(a => doSomething(a)) | ||||
|          * | ||||
|          * Removing the console.log(); statement should leave two statements, but | ||||
|          * here the two statements will become one because [ causes continuation after | ||||
|          * foo(). | ||||
|          * @param {ASTNode} node The ExpressionStatement node to check. | ||||
|          * @returns {boolean} `true` if ASI will break after removing the ExpressionStatement | ||||
|          *      node. | ||||
|          */ | ||||
|         function maybeAsiHazard(node) { | ||||
|             const SAFE_TOKENS_BEFORE = /^[:;{]$/u; // One of :;{ | ||||
|             const UNSAFE_CHARS_AFTER = /^[-[(/+`]/u; // One of [(/+-` | ||||
|  | ||||
|             const tokenBefore = sourceCode.getTokenBefore(node); | ||||
|             const tokenAfter = sourceCode.getTokenAfter(node); | ||||
|  | ||||
|             return ( | ||||
|                 Boolean(tokenAfter) && | ||||
|                 UNSAFE_CHARS_AFTER.test(tokenAfter.value) && | ||||
|                 tokenAfter.value !== "++" && | ||||
|                 tokenAfter.value !== "--" && | ||||
|                 Boolean(tokenBefore) && | ||||
|                 !SAFE_TOKENS_BEFORE.test(tokenBefore.value) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks if the MemberExpression node's parent.parent.parent is a | ||||
|          * Program, BlockStatement, StaticBlock, or SwitchCase node. This check | ||||
|          * is necessary to avoid providing a suggestion that might cause a syntax error. | ||||
|          * | ||||
|          * eg. if (a) console.log(b), removing console.log() here will lead to a | ||||
|          *     syntax error. | ||||
|          *     if (a) { console.log(b) }, removing console.log() here is acceptable. | ||||
|          * | ||||
|          * Additionally, it checks if the callee of the CallExpression node is | ||||
|          * the node itself. | ||||
|          * | ||||
|          * eg. foo(console.log), cannot provide a suggestion here. | ||||
|          * @param {ASTNode} node The MemberExpression node to check. | ||||
|          * @returns {boolean} `true` if a suggestion can be provided for a node. | ||||
|          */ | ||||
|         function canProvideSuggestions(node) { | ||||
|             return ( | ||||
|                 node.parent.type === "CallExpression" && | ||||
|                 node.parent.callee === node && | ||||
|                 node.parent.parent.type === "ExpressionStatement" && | ||||
|                 astUtils.STATEMENT_LIST_PARENTS.has(node.parent.parent.parent.type) && | ||||
|                 !maybeAsiHazard(node.parent.parent) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports the given reference as a violation. | ||||
|          * @param {eslint-scope.Reference} reference The reference to report. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function report(reference) { | ||||
|             const node = reference.identifier.parent; | ||||
|  | ||||
|             const propertyName = astUtils.getStaticPropertyName(node); | ||||
|  | ||||
|             context.report({ | ||||
|                 node, | ||||
|                 loc: node.loc, | ||||
|                 messageId: "unexpected", | ||||
|                 suggest: canProvideSuggestions(node) | ||||
|                     ? [{ | ||||
|                         messageId: "removeConsole", | ||||
|                         data: { propertyName }, | ||||
|                         fix(fixer) { | ||||
|                             return fixer.remove(node.parent.parent); | ||||
|                         } | ||||
|                     }] | ||||
|                     : [] | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             "Program:exit"(node) { | ||||
|                 const scope = sourceCode.getScope(node); | ||||
|                 const consoleVar = astUtils.getVariableByName(scope, "console"); | ||||
|                 const shadowed = consoleVar && consoleVar.defs.length > 0; | ||||
|  | ||||
|                 /* | ||||
|                  * 'scope.through' includes all references to undefined | ||||
|                  * variables. If the variable 'console' is not defined, it uses | ||||
|                  * 'scope.through'. | ||||
|                  */ | ||||
|                 const references = consoleVar | ||||
|                     ? consoleVar.references | ||||
|                     : scope.through.filter(isConsole); | ||||
|  | ||||
|                 if (!shadowed) { | ||||
|                     references | ||||
|                         .filter(isMemberAccessExceptAllowed) | ||||
|                         .forEach(report); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										56
									
								
								node_modules/eslint/lib/rules/no-const-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								node_modules/eslint/lib/rules/no-const-assign.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /** | ||||
|  * @fileoverview A rule to disallow modifying variables that are declared using `const` | ||||
|  * @author Toru Nagashima | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const astUtils = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow reassigning `const` variables", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-const-assign" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             const: "'{{name}}' is constant." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         /** | ||||
|          * Finds and reports references that are non initializer and writable. | ||||
|          * @param {Variable} variable A variable to check. | ||||
|          * @returns {void} | ||||
|          */ | ||||
|         function checkVariable(variable) { | ||||
|             astUtils.getModifyingReferences(variable.references).forEach(reference => { | ||||
|                 context.report({ node: reference.identifier, messageId: "const", data: { name: reference.identifier.name } }); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             VariableDeclaration(node) { | ||||
|                 if (node.kind === "const") { | ||||
|                     sourceCode.getDeclaredVariables(node).forEach(checkVariable); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										509
									
								
								node_modules/eslint/lib/rules/no-constant-binary-expression.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										509
									
								
								node_modules/eslint/lib/rules/no-constant-binary-expression.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,509 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag constant comparisons and logical expressions that always/never short circuit | ||||
|  * @author Jordan Eldredge <https://jordaneldredge.com> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const globals = require("globals"); | ||||
| const { isNullLiteral, isConstant, isReferenceToGlobalVariable, isLogicalAssignmentOperator } = require("./utils/ast-utils"); | ||||
|  | ||||
| const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set(["+", "-", "*", "/", "%", "|", "^", "&", "**", "<<", ">>", ">>>"]); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** | ||||
|  * Checks whether or not a node is `null` or `undefined`. Similar to the one | ||||
|  * found in ast-utils.js, but this one correctly handles the edge case that | ||||
|  * `undefined` has been redefined. | ||||
|  * @param {Scope} scope Scope in which the expression was found. | ||||
|  * @param {ASTNode} node A node to check. | ||||
|  * @returns {boolean} Whether or not the node is a `null` or `undefined`. | ||||
|  * @public | ||||
|  */ | ||||
| function isNullOrUndefined(scope, node) { | ||||
|     return ( | ||||
|         isNullLiteral(node) || | ||||
|         (node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) || | ||||
|         (node.type === "UnaryExpression" && node.operator === "void") | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Test if an AST node has a statically knowable constant nullishness. Meaning, | ||||
|  * it will always resolve to a constant value of either: `null`, `undefined` | ||||
|  * or not `null` _or_ `undefined`. An expression that can vary between those | ||||
|  * three states at runtime would return `false`. | ||||
|  * @param {Scope} scope The scope in which the node was found. | ||||
|  * @param {ASTNode} node The AST node being tested. | ||||
|  * @param {boolean} nonNullish if `true` then nullish values are not considered constant. | ||||
|  * @returns {boolean} Does `node` have constant nullishness? | ||||
|  */ | ||||
| function hasConstantNullishness(scope, node, nonNullish) { | ||||
|     if (nonNullish && isNullOrUndefined(scope, node)) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     switch (node.type) { | ||||
|         case "ObjectExpression": // Objects are never nullish | ||||
|         case "ArrayExpression": // Arrays are never nullish | ||||
|         case "ArrowFunctionExpression": // Functions never nullish | ||||
|         case "FunctionExpression": // Functions are never nullish | ||||
|         case "ClassExpression": // Classes are never nullish | ||||
|         case "NewExpression": // Objects are never nullish | ||||
|         case "Literal": // Nullish, or non-nullish, literals never change | ||||
|         case "TemplateLiteral": // A string is never nullish | ||||
|         case "UpdateExpression": // Numbers are never nullish | ||||
|         case "BinaryExpression": // Numbers, strings, or booleans are never nullish | ||||
|             return true; | ||||
|         case "CallExpression": { | ||||
|             if (node.callee.type !== "Identifier") { | ||||
|                 return false; | ||||
|             } | ||||
|             const functionName = node.callee.name; | ||||
|  | ||||
|             return (functionName === "Boolean" || functionName === "String" || functionName === "Number") && | ||||
|                 isReferenceToGlobalVariable(scope, node.callee); | ||||
|         } | ||||
|         case "LogicalExpression": { | ||||
|             return node.operator === "??" && hasConstantNullishness(scope, node.right, true); | ||||
|         } | ||||
|         case "AssignmentExpression": | ||||
|             if (node.operator === "=") { | ||||
|                 return hasConstantNullishness(scope, node.right, nonNullish); | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Handling short-circuiting assignment operators would require | ||||
|              * walking the scope. We won't attempt that (for now...) / | ||||
|              */ | ||||
|             if (isLogicalAssignmentOperator(node.operator)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * The remaining assignment expressions all result in a numeric or | ||||
|              * string (non-nullish) value: | ||||
|              *   "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "|=", "^=", "&=" | ||||
|              */ | ||||
|  | ||||
|             return true; | ||||
|         case "UnaryExpression": | ||||
|  | ||||
|             /* | ||||
|              * "void" Always returns `undefined` | ||||
|              * "typeof" All types are strings, and thus non-nullish | ||||
|              * "!" Boolean is never nullish | ||||
|              * "delete" Returns a boolean, which is never nullish | ||||
|              * Math operators always return numbers or strings, neither of which | ||||
|              * are non-nullish "+", "-", "~" | ||||
|              */ | ||||
|  | ||||
|             return true; | ||||
|         case "SequenceExpression": { | ||||
|             const last = node.expressions[node.expressions.length - 1]; | ||||
|  | ||||
|             return hasConstantNullishness(scope, last, nonNullish); | ||||
|         } | ||||
|         case "Identifier": | ||||
|             return node.name === "undefined" && isReferenceToGlobalVariable(scope, node); | ||||
|         case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior. | ||||
|         case "JSXFragment": | ||||
|             return false; | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Test if an AST node is a boolean value that never changes. Specifically we | ||||
|  * test for: | ||||
|  * 1. Literal booleans (`true` or `false`) | ||||
|  * 2. Unary `!` expressions with a constant value | ||||
|  * 3. Constant booleans created via the `Boolean` global function | ||||
|  * @param {Scope} scope The scope in which the node was found. | ||||
|  * @param {ASTNode} node The node to test | ||||
|  * @returns {boolean} Is `node` guaranteed to be a boolean? | ||||
|  */ | ||||
| function isStaticBoolean(scope, node) { | ||||
|     switch (node.type) { | ||||
|         case "Literal": | ||||
|             return typeof node.value === "boolean"; | ||||
|         case "CallExpression": | ||||
|             return node.callee.type === "Identifier" && node.callee.name === "Boolean" && | ||||
|               isReferenceToGlobalVariable(scope, node.callee) && | ||||
|               (node.arguments.length === 0 || isConstant(scope, node.arguments[0], true)); | ||||
|         case "UnaryExpression": | ||||
|             return node.operator === "!" && isConstant(scope, node.argument, true); | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Test if an AST node will always give the same result when compared to a | ||||
|  * boolean value. Note that comparison to boolean values is different than | ||||
|  * truthiness. | ||||
|  * https://262.ecma-international.org/5.1/#sec-11.9.3 | ||||
|  * | ||||
|  * Javascript `==` operator works by converting the boolean to `1` (true) or | ||||
|  * `+0` (false) and then checks the values `==` equality to that number. | ||||
|  * @param {Scope} scope The scope in which node was found. | ||||
|  * @param {ASTNode} node The node to test. | ||||
|  * @returns {boolean} Will `node` always coerce to the same boolean value? | ||||
|  */ | ||||
| function hasConstantLooseBooleanComparison(scope, node) { | ||||
|     switch (node.type) { | ||||
|         case "ObjectExpression": | ||||
|         case "ClassExpression": | ||||
|  | ||||
|             /** | ||||
|              * In theory objects like: | ||||
|              * | ||||
|              * `{toString: () => a}` | ||||
|              * `{valueOf: () => a}` | ||||
|              * | ||||
|              * Or a classes like: | ||||
|              * | ||||
|              * `class { static toString() { return a } }` | ||||
|              * `class { static valueOf() { return a } }` | ||||
|              * | ||||
|              * Are not constant verifiably when `inBooleanPosition` is | ||||
|              * false, but it's an edge case we've opted not to handle. | ||||
|              */ | ||||
|             return true; | ||||
|         case "ArrayExpression": { | ||||
|             const nonSpreadElements = node.elements.filter(e => | ||||
|  | ||||
|                 // Elements can be `null` in sparse arrays: `[,,]`; | ||||
|                 e !== null && e.type !== "SpreadElement"); | ||||
|  | ||||
|  | ||||
|             /* | ||||
|              * Possible future direction if needed: We could check if the | ||||
|              * single value would result in variable boolean comparison. | ||||
|              * For now we will err on the side of caution since `[x]` could | ||||
|              * evaluate to `[0]` or `[1]`. | ||||
|              */ | ||||
|             return node.elements.length === 0 || nonSpreadElements.length > 1; | ||||
|         } | ||||
|         case "ArrowFunctionExpression": | ||||
|         case "FunctionExpression": | ||||
|             return true; | ||||
|         case "UnaryExpression": | ||||
|             if (node.operator === "void" || // Always returns `undefined` | ||||
|                 node.operator === "typeof" // All `typeof` strings, when coerced to number, are not 0 or 1. | ||||
|             ) { | ||||
|                 return true; | ||||
|             } | ||||
|             if (node.operator === "!") { | ||||
|                 return isConstant(scope, node.argument, true); | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * We won't try to reason about +, -, ~, or delete | ||||
|              * In theory, for the mathematical operators, we could look at the | ||||
|              * argument and try to determine if it coerces to a constant numeric | ||||
|              * value. | ||||
|              */ | ||||
|             return false; | ||||
|         case "NewExpression": // Objects might have custom `.valueOf` or `.toString`. | ||||
|             return false; | ||||
|         case "CallExpression": { | ||||
|             if (node.callee.type === "Identifier" && | ||||
|                 node.callee.name === "Boolean" && | ||||
|                 isReferenceToGlobalVariable(scope, node.callee) | ||||
|             ) { | ||||
|                 return node.arguments.length === 0 || isConstant(scope, node.arguments[0], true); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         case "Literal": // True or false, literals never change | ||||
|             return true; | ||||
|         case "Identifier": | ||||
|             return node.name === "undefined" && isReferenceToGlobalVariable(scope, node); | ||||
|         case "TemplateLiteral": | ||||
|  | ||||
|             /* | ||||
|              * In theory we could try to check if the quasi are sufficient to | ||||
|              * prove that the expression will always be true, but it would be | ||||
|              * tricky to get right. For example: `000.${foo}000` | ||||
|              */ | ||||
|             return node.expressions.length === 0; | ||||
|         case "AssignmentExpression": | ||||
|             if (node.operator === "=") { | ||||
|                 return hasConstantLooseBooleanComparison(scope, node.right); | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Handling short-circuiting assignment operators would require | ||||
|              * walking the scope. We won't attempt that (for now...) | ||||
|              * | ||||
|              * The remaining assignment expressions all result in a numeric or | ||||
|              * string (non-nullish) values which could be truthy or falsy: | ||||
|              *   "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "|=", "^=", "&=" | ||||
|              */ | ||||
|             return false; | ||||
|         case "SequenceExpression": { | ||||
|             const last = node.expressions[node.expressions.length - 1]; | ||||
|  | ||||
|             return hasConstantLooseBooleanComparison(scope, last); | ||||
|         } | ||||
|         case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior. | ||||
|         case "JSXFragment": | ||||
|             return false; | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Test if an AST node will always give the same result when _strictly_ compared | ||||
|  * to a boolean value. This can happen if the expression can never be boolean, or | ||||
|  * if it is always the same boolean value. | ||||
|  * @param {Scope} scope The scope in which the node was found. | ||||
|  * @param {ASTNode} node The node to test | ||||
|  * @returns {boolean} Will `node` always give the same result when compared to a | ||||
|  * static boolean value? | ||||
|  */ | ||||
| function hasConstantStrictBooleanComparison(scope, node) { | ||||
|     switch (node.type) { | ||||
|         case "ObjectExpression": // Objects are not booleans | ||||
|         case "ArrayExpression": // Arrays are not booleans | ||||
|         case "ArrowFunctionExpression": // Functions are not booleans | ||||
|         case "FunctionExpression": | ||||
|         case "ClassExpression": // Classes are not booleans | ||||
|         case "NewExpression": // Objects are not booleans | ||||
|         case "TemplateLiteral": // Strings are not booleans | ||||
|         case "Literal": // True, false, or not boolean, literals never change. | ||||
|         case "UpdateExpression": // Numbers are not booleans | ||||
|             return true; | ||||
|         case "BinaryExpression": | ||||
|             return NUMERIC_OR_STRING_BINARY_OPERATORS.has(node.operator); | ||||
|         case "UnaryExpression": { | ||||
|             if (node.operator === "delete") { | ||||
|                 return false; | ||||
|             } | ||||
|             if (node.operator === "!") { | ||||
|                 return isConstant(scope, node.argument, true); | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * The remaining operators return either strings or numbers, neither | ||||
|              * of which are boolean. | ||||
|              */ | ||||
|             return true; | ||||
|         } | ||||
|         case "SequenceExpression": { | ||||
|             const last = node.expressions[node.expressions.length - 1]; | ||||
|  | ||||
|             return hasConstantStrictBooleanComparison(scope, last); | ||||
|         } | ||||
|         case "Identifier": | ||||
|             return node.name === "undefined" && isReferenceToGlobalVariable(scope, node); | ||||
|         case "AssignmentExpression": | ||||
|             if (node.operator === "=") { | ||||
|                 return hasConstantStrictBooleanComparison(scope, node.right); | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * Handling short-circuiting assignment operators would require | ||||
|              * walking the scope. We won't attempt that (for now...) | ||||
|              */ | ||||
|             if (isLogicalAssignmentOperator(node.operator)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * The remaining assignment expressions all result in either a number | ||||
|              * or a string, neither of which can ever be boolean. | ||||
|              */ | ||||
|             return true; | ||||
|         case "CallExpression": { | ||||
|             if (node.callee.type !== "Identifier") { | ||||
|                 return false; | ||||
|             } | ||||
|             const functionName = node.callee.name; | ||||
|  | ||||
|             if ( | ||||
|                 (functionName === "String" || functionName === "Number") && | ||||
|                 isReferenceToGlobalVariable(scope, node.callee) | ||||
|             ) { | ||||
|                 return true; | ||||
|             } | ||||
|             if (functionName === "Boolean" && isReferenceToGlobalVariable(scope, node.callee)) { | ||||
|                 return ( | ||||
|                     node.arguments.length === 0 || isConstant(scope, node.arguments[0], true)); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior. | ||||
|         case "JSXFragment": | ||||
|             return false; | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Test if an AST node will always result in a newly constructed object | ||||
|  * @param {Scope} scope The scope in which the node was found. | ||||
|  * @param {ASTNode} node The node to test | ||||
|  * @returns {boolean} Will `node` always be new? | ||||
|  */ | ||||
| function isAlwaysNew(scope, node) { | ||||
|     switch (node.type) { | ||||
|         case "ObjectExpression": | ||||
|         case "ArrayExpression": | ||||
|         case "ArrowFunctionExpression": | ||||
|         case "FunctionExpression": | ||||
|         case "ClassExpression": | ||||
|             return true; | ||||
|         case "NewExpression": { | ||||
|             if (node.callee.type !== "Identifier") { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * All the built-in constructors are always new, but | ||||
|              * user-defined constructors could return a sentinel | ||||
|              * object. | ||||
|              * | ||||
|              * Catching these is especially useful for primitive constructors | ||||
|              * which return boxed values, a surprising gotcha' in JavaScript. | ||||
|              */ | ||||
|             return Object.hasOwnProperty.call(globals.builtin, node.callee.name) && | ||||
|               isReferenceToGlobalVariable(scope, node.callee); | ||||
|         } | ||||
|         case "Literal": | ||||
|  | ||||
|             // Regular expressions are objects, and thus always new | ||||
|             return typeof node.regex === "object"; | ||||
|         case "SequenceExpression": { | ||||
|             const last = node.expressions[node.expressions.length - 1]; | ||||
|  | ||||
|             return isAlwaysNew(scope, last); | ||||
|         } | ||||
|         case "AssignmentExpression": | ||||
|             if (node.operator === "=") { | ||||
|                 return isAlwaysNew(scope, node.right); | ||||
|             } | ||||
|             return false; | ||||
|         case "ConditionalExpression": | ||||
|             return isAlwaysNew(scope, node.consequent) && isAlwaysNew(scope, node.alternate); | ||||
|         case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior. | ||||
|         case "JSXFragment": | ||||
|             return false; | ||||
|         default: | ||||
|             return false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Checks if one operand will cause the result to be constant. | ||||
|  * @param {Scope} scope Scope in which the expression was found. | ||||
|  * @param {ASTNode} a One side of the expression | ||||
|  * @param {ASTNode} b The other side of the expression | ||||
|  * @param {string} operator The binary expression operator | ||||
|  * @returns {ASTNode | null} The node which will cause the expression to have a constant result. | ||||
|  */ | ||||
| function findBinaryExpressionConstantOperand(scope, a, b, operator) { | ||||
|     if (operator === "==" || operator === "!=") { | ||||
|         if ( | ||||
|             (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) || | ||||
|             (isStaticBoolean(scope, a) && hasConstantLooseBooleanComparison(scope, b)) | ||||
|         ) { | ||||
|             return b; | ||||
|         } | ||||
|     } else if (operator === "===" || operator === "!==") { | ||||
|         if ( | ||||
|             (isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) || | ||||
|             (isStaticBoolean(scope, a) && hasConstantStrictBooleanComparison(scope, b)) | ||||
|         ) { | ||||
|             return b; | ||||
|         } | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|         docs: { | ||||
|             description: "Disallow expressions where the operation doesn't affect the value", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-constant-binary-expression" | ||||
|         }, | ||||
|         schema: [], | ||||
|         messages: { | ||||
|             constantBinaryOperand: "Unexpected constant binary expression. Compares constantly with the {{otherSide}}-hand side of the `{{operator}}`.", | ||||
|             constantShortCircuit: "Unexpected constant {{property}} on the left-hand side of a `{{operator}}` expression.", | ||||
|             alwaysNew: "Unexpected comparison to newly constructed object. These two values can never be equal.", | ||||
|             bothAlwaysNew: "Unexpected comparison of two newly constructed objects. These two values can never be equal." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         return { | ||||
|             LogicalExpression(node) { | ||||
|                 const { operator, left } = node; | ||||
|                 const scope = sourceCode.getScope(node); | ||||
|  | ||||
|                 if ((operator === "&&" || operator === "||") && isConstant(scope, left, true)) { | ||||
|                     context.report({ node: left, messageId: "constantShortCircuit", data: { property: "truthiness", operator } }); | ||||
|                 } else if (operator === "??" && hasConstantNullishness(scope, left, false)) { | ||||
|                     context.report({ node: left, messageId: "constantShortCircuit", data: { property: "nullishness", operator } }); | ||||
|                 } | ||||
|             }, | ||||
|             BinaryExpression(node) { | ||||
|                 const scope = sourceCode.getScope(node); | ||||
|                 const { right, left, operator } = node; | ||||
|                 const rightConstantOperand = findBinaryExpressionConstantOperand(scope, left, right, operator); | ||||
|                 const leftConstantOperand = findBinaryExpressionConstantOperand(scope, right, left, operator); | ||||
|  | ||||
|                 if (rightConstantOperand) { | ||||
|                     context.report({ node: rightConstantOperand, messageId: "constantBinaryOperand", data: { operator, otherSide: "left" } }); | ||||
|                 } else if (leftConstantOperand) { | ||||
|                     context.report({ node: leftConstantOperand, messageId: "constantBinaryOperand", data: { operator, otherSide: "right" } }); | ||||
|                 } else if (operator === "===" || operator === "!==") { | ||||
|                     if (isAlwaysNew(scope, left)) { | ||||
|                         context.report({ node: left, messageId: "alwaysNew" }); | ||||
|                     } else if (isAlwaysNew(scope, right)) { | ||||
|                         context.report({ node: right, messageId: "alwaysNew" }); | ||||
|                     } | ||||
|                 } else if (operator === "==" || operator === "!=") { | ||||
|  | ||||
|                     /* | ||||
|                      * If both sides are "new", then both sides are objects and | ||||
|                      * therefore they will be compared by reference even with `==` | ||||
|                      * equality. | ||||
|                      */ | ||||
|                     if (isAlwaysNew(scope, left) && isAlwaysNew(scope, right)) { | ||||
|                         context.report({ node: left, messageId: "bothAlwaysNew" }); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|  | ||||
|             /* | ||||
|              * In theory we could handle short-circuiting assignment operators, | ||||
|              * for some constant values, but that would require walking the | ||||
|              * scope to find the value of the variable being assigned. This is | ||||
|              * dependant on https://github.com/eslint/eslint/issues/13776 | ||||
|              * | ||||
|              * AssignmentExpression() {}, | ||||
|              */ | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										150
									
								
								node_modules/eslint/lib/rules/no-constant-condition.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								node_modules/eslint/lib/rules/no-constant-condition.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use constant conditions | ||||
|  * @author Christian Schulz <http://rndm.de> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const { isConstant } = require("./utils/ast-utils"); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Helpers | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow constant expressions in conditions", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-constant-condition" | ||||
|         }, | ||||
|  | ||||
|         schema: [ | ||||
|             { | ||||
|                 type: "object", | ||||
|                 properties: { | ||||
|                     checkLoops: { | ||||
|                         type: "boolean", | ||||
|                         default: true | ||||
|                     } | ||||
|                 }, | ||||
|                 additionalProperties: false | ||||
|             } | ||||
|         ], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected constant condition." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const options = context.options[0] || {}, | ||||
|             checkLoops = options.checkLoops !== false, | ||||
|             loopSetStack = []; | ||||
|         const sourceCode = context.sourceCode; | ||||
|  | ||||
|         let loopsInCurrentScope = new Set(); | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Helpers | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         /** | ||||
|          * Tracks when the given node contains a constant condition. | ||||
|          * @param {ASTNode} node The AST node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function trackConstantConditionLoop(node) { | ||||
|             if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) { | ||||
|                 loopsInCurrentScope.add(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports when the set contains the given constant condition node | ||||
|          * @param {ASTNode} node The AST node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkConstantConditionLoopInSet(node) { | ||||
|             if (loopsInCurrentScope.has(node)) { | ||||
|                 loopsInCurrentScope.delete(node); | ||||
|                 context.report({ node: node.test, messageId: "unexpected" }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports when the given node contains a constant condition. | ||||
|          * @param {ASTNode} node The AST node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function reportIfConstant(node) { | ||||
|             if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) { | ||||
|                 context.report({ node: node.test, messageId: "unexpected" }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Stores current set of constant loops in loopSetStack temporarily | ||||
|          * and uses a new set to track constant loops | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function enterFunction() { | ||||
|             loopSetStack.push(loopsInCurrentScope); | ||||
|             loopsInCurrentScope = new Set(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Reports when the set still contains stored constant conditions | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function exitFunction() { | ||||
|             loopsInCurrentScope = loopSetStack.pop(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Checks node when checkLoops option is enabled | ||||
|          * @param {ASTNode} node The AST node to check. | ||||
|          * @returns {void} | ||||
|          * @private | ||||
|          */ | ||||
|         function checkLoop(node) { | ||||
|             if (checkLoops) { | ||||
|                 trackConstantConditionLoop(node); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //-------------------------------------------------------------------------- | ||||
|         // Public | ||||
|         //-------------------------------------------------------------------------- | ||||
|  | ||||
|         return { | ||||
|             ConditionalExpression: reportIfConstant, | ||||
|             IfStatement: reportIfConstant, | ||||
|             WhileStatement: checkLoop, | ||||
|             "WhileStatement:exit": checkConstantConditionLoopInSet, | ||||
|             DoWhileStatement: checkLoop, | ||||
|             "DoWhileStatement:exit": checkConstantConditionLoopInSet, | ||||
|             ForStatement: checkLoop, | ||||
|             "ForStatement > .test": node => checkLoop(node.parent), | ||||
|             "ForStatement:exit": checkConstantConditionLoopInSet, | ||||
|             FunctionDeclaration: enterFunction, | ||||
|             "FunctionDeclaration:exit": exitFunction, | ||||
|             FunctionExpression: enterFunction, | ||||
|             "FunctionExpression:exit": exitFunction, | ||||
|             YieldExpression: () => loopsInCurrentScope.clear() | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										62
									
								
								node_modules/eslint/lib/rules/no-constructor-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								node_modules/eslint/lib/rules/no-constructor-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to disallow returning value from constructor. | ||||
|  * @author Pig Fang <https://github.com/g-plane> | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow returning value from constructor", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-constructor-return" | ||||
|         }, | ||||
|  | ||||
|         schema: {}, | ||||
|  | ||||
|         fixable: null, | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected return statement in constructor." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|         const stack = []; | ||||
|  | ||||
|         return { | ||||
|             onCodePathStart(_, node) { | ||||
|                 stack.push(node); | ||||
|             }, | ||||
|             onCodePathEnd() { | ||||
|                 stack.pop(); | ||||
|             }, | ||||
|             ReturnStatement(node) { | ||||
|                 const last = stack[stack.length - 1]; | ||||
|  | ||||
|                 if (!last.parent) { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if ( | ||||
|                     last.parent.type === "MethodDefinition" && | ||||
|                     last.parent.kind === "constructor" && | ||||
|                     (node.parent.parent === last || node.argument) | ||||
|                 ) { | ||||
|                     context.report({ | ||||
|                         node, | ||||
|                         messageId: "unexpected" | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										39
									
								
								node_modules/eslint/lib/rules/no-continue.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								node_modules/eslint/lib/rules/no-continue.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of continue statement | ||||
|  * @author Borislav Zhivkov | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow `continue` statements", | ||||
|             recommended: false, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-continue" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected use of continue statement." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         return { | ||||
|             ContinueStatement(node) { | ||||
|                 context.report({ node, messageId: "unexpected" }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										138
									
								
								node_modules/eslint/lib/rules/no-control-regex.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								node_modules/eslint/lib/rules/no-control-regex.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to forbid control characters from regular expressions. | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| const RegExpValidator = require("@eslint-community/regexpp").RegExpValidator; | ||||
| const collector = new (class { | ||||
|     constructor() { | ||||
|         this._source = ""; | ||||
|         this._controlChars = []; | ||||
|         this._validator = new RegExpValidator(this); | ||||
|     } | ||||
|  | ||||
|     onPatternEnter() { | ||||
|  | ||||
|         /* | ||||
|          * `RegExpValidator` may parse the pattern twice in one `validatePattern`. | ||||
|          * So `this._controlChars` should be cleared here as well. | ||||
|          * | ||||
|          * For example, the `/(?<a>\x1f)/` regex will parse the pattern twice. | ||||
|          * This is based on the content described in Annex B. | ||||
|          * If the regex contains a `GroupName` and the `u` flag is not used, `ParseText` will be called twice. | ||||
|          * See https://tc39.es/ecma262/2023/multipage/additional-ecmascript-features-for-web-browsers.html#sec-parsepattern-annexb | ||||
|          */ | ||||
|         this._controlChars = []; | ||||
|     } | ||||
|  | ||||
|     onCharacter(start, end, cp) { | ||||
|         if (cp >= 0x00 && | ||||
|             cp <= 0x1F && | ||||
|             ( | ||||
|                 this._source.codePointAt(start) === cp || | ||||
|                 this._source.slice(start, end).startsWith("\\x") || | ||||
|                 this._source.slice(start, end).startsWith("\\u") | ||||
|             ) | ||||
|         ) { | ||||
|             this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     collectControlChars(regexpStr, flags) { | ||||
|         const uFlag = typeof flags === "string" && flags.includes("u"); | ||||
|         const vFlag = typeof flags === "string" && flags.includes("v"); | ||||
|  | ||||
|         this._controlChars = []; | ||||
|         this._source = regexpStr; | ||||
|  | ||||
|         try { | ||||
|             this._validator.validatePattern(regexpStr, void 0, void 0, { unicode: uFlag, unicodeSets: vFlag }); // Call onCharacter hook | ||||
|         } catch { | ||||
|  | ||||
|             // Ignore syntax errors in RegExp. | ||||
|         } | ||||
|         return this._controlChars; | ||||
|     } | ||||
| })(); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow control characters in regular expressions", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-control-regex" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         /** | ||||
|          * Get the regex expression | ||||
|          * @param {ASTNode} node `Literal` node to evaluate | ||||
|          * @returns {{ pattern: string, flags: string | null } | null} Regex if found (the given node is either a regex literal | ||||
|          * or a string literal that is the pattern argument of a RegExp constructor call). Otherwise `null`. If flags cannot be determined, | ||||
|          * the `flags` property will be `null`. | ||||
|          * @private | ||||
|          */ | ||||
|         function getRegExp(node) { | ||||
|             if (node.regex) { | ||||
|                 return node.regex; | ||||
|             } | ||||
|             if (typeof node.value === "string" && | ||||
|                 (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") && | ||||
|                 node.parent.callee.type === "Identifier" && | ||||
|                 node.parent.callee.name === "RegExp" && | ||||
|                 node.parent.arguments[0] === node | ||||
|             ) { | ||||
|                 const pattern = node.value; | ||||
|                 const flags = | ||||
|                     node.parent.arguments.length > 1 && | ||||
|                     node.parent.arguments[1].type === "Literal" && | ||||
|                     typeof node.parent.arguments[1].value === "string" | ||||
|                         ? node.parent.arguments[1].value | ||||
|                         : null; | ||||
|  | ||||
|                 return { pattern, flags }; | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             Literal(node) { | ||||
|                 const regExp = getRegExp(node); | ||||
|  | ||||
|                 if (regExp) { | ||||
|                     const { pattern, flags } = regExp; | ||||
|                     const controlCharacters = collector.collectControlChars(pattern, flags); | ||||
|  | ||||
|                     if (controlCharacters.length > 0) { | ||||
|                         context.report({ | ||||
|                             node, | ||||
|                             messageId: "unexpected", | ||||
|                             data: { | ||||
|                                 controlChars: controlCharacters.join(", ") | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										43
									
								
								node_modules/eslint/lib/rules/no-debugger.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								node_modules/eslint/lib/rules/no-debugger.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag use of a debugger statement | ||||
|  * @author Nicholas C. Zakas | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "problem", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow the use of `debugger`", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-debugger" | ||||
|         }, | ||||
|  | ||||
|         fixable: null, | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Unexpected 'debugger' statement." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         return { | ||||
|             DebuggerStatement(node) { | ||||
|                 context.report({ | ||||
|                     node, | ||||
|                     messageId: "unexpected" | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										42
									
								
								node_modules/eslint/lib/rules/no-delete-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								node_modules/eslint/lib/rules/no-delete-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| /** | ||||
|  * @fileoverview Rule to flag when deleting variables | ||||
|  * @author Ilya Volodin | ||||
|  */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Rule Definition | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| /** @type {import('../shared/types').Rule} */ | ||||
| module.exports = { | ||||
|     meta: { | ||||
|         type: "suggestion", | ||||
|  | ||||
|         docs: { | ||||
|             description: "Disallow deleting variables", | ||||
|             recommended: true, | ||||
|             url: "https://eslint.org/docs/latest/rules/no-delete-var" | ||||
|         }, | ||||
|  | ||||
|         schema: [], | ||||
|  | ||||
|         messages: { | ||||
|             unexpected: "Variables should not be deleted." | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     create(context) { | ||||
|  | ||||
|         return { | ||||
|  | ||||
|             UnaryExpression(node) { | ||||
|                 if (node.operator === "delete" && node.argument.type === "Identifier") { | ||||
|                     context.report({ node, messageId: "unexpected" }); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| }; | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user