{"version":3,"file":"generate-patched-file.js","sourceRoot":"","sources":["../../src/eslint-bulk-suppressions/generate-patched-file.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,4CAAoB;AACpB,2CAGqB;AAErB;;;;GAIG;AACH,SAAgB,yCAAyC,CACvD,aAAqB,EACrB,cAAsB;IAEtB,MAAM,mBAAmB,GACvB,OAAO,CAAC,GAAG,CAAC,2DAA+C,CAAC,CAAC;IAC/D,IAAI,mBAAmB,KAAK,MAAM,IAAI,mBAAmB,KAAK,GAAG,IAAI,YAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnG,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAW,YAAE,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEpE,IAAI,UAAU,GAAW,CAAC,CAAC;IAE3B;;;OAGG;IACH,SAAS,eAAe,CAAC,MAAc;QACrC,MAAM,aAAa,GAAW,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAExD,IAAI,MAAM,GAAW,EAAE,CAAC;QACxB,IAAI,OAAO,GAAW,EAAE,CAAC;QAEzB,OAAO,UAAU,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,GAAW,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7C,MAAM,IAAI,IAAI,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,IAAI,IAAI,CAAC;YAClB,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBACpC,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,SAAS,gBAAgB;QACvB,IAAI,MAAM,GAAW,EAAE,CAAC;QAExB,OAAO,UAAU,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,GAAW,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7C,MAAM,IAAI,IAAI,CAAC;YACf,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,YAAY;QACnB,MAAM,MAAM,GAAW,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACvD,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;QAC9B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,SAAS,0BAA0B,CAAC,SAAiB;QACnD,MAAM,IAAI,GAAW,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAEpD,MAAM,eAAe,GAAW,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEpD,MAAM,2BAA2B,GAAW,iBAAiB,CAAC;QAE9D,MAAM,uBAAuB,GAAW,IAAI,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAElF,IAAI,uBAAuB,KAAK,CAAC,CAAC,IAAI,uBAAuB,GAAG,eAAe,EAAE,CAAC;YAChF,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QAED,MAAM,gBAAgB,GACpB,IAAI,CAAC,OAAO,CAAC,2BAA2B,CAAC,GAAG,2BAA2B,CAAC,MAAM,CAAC;QAEjF,MAAM,cAAc,GAClB,IAAI,CAAC,gBAAgB,CAAC,KAAK,GAAG;YAC9B,IAAI,CAAC,gBAAgB,CAAC,KAAK,GAAG;YAC9B,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC1F,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAElG,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,SAAS,GAAG,gBAAgB,CAAC;QACtC,CAAC;QAED,OAAO,0BAA0B,CAAC,SAAS,GAAG,gBAAgB,CAAC,CAAC;IAClE,CAAC;IAED,SAAS,cAAc,CAAC,aAAqB;QAC3C,MAAM,MAAM,GAAW,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QACtE,UAAU,GAAG,aAAa,CAAC;QAC3B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,UAAU,GAAW,EAAE,CAAC;IAE5B,cAAc;IACd,sFAAsF;IACtF,qBAAqB;IACrB,sFAAsF;IACtF,UAAU,IAAI,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACjD,UAAU,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,UAAU,IAAI,gBAAgB,EAAE,CAAC;IAEjC,UAAU,IAAI;;oDAEoC,+CAAmC;;CAEtF,CAAC;IAEA,cAAc;IACd,sFAAsF;IACtF,iBAAiB;IACjB,sFAAsF;IACtF,MAAM,cAAc,GAAW,eAAe,CAAC,aAAa,CAAC,CAAC;IAE9D,6BAA6B;IAC7B,EAAE;IACF,mCAAmC;IACnC,4CAA4C;IAC5C,2CAA2C;IAC3C,EAAE;IACF,kCAAkC;IAClC,EAAE;IACF,mCAAmC;IACnC,8DAA8D;IAC9D,6DAA6D;IAC7D,EAAE;IACF,UAAU,IAAI,cAAc,CAAC,OAAO,CAAC,wCAAwC,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;;QAC/F,MAAM,UAAU,GAAW,MAAA,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,EAAE,mCAAI,EAAE,CAAC;QAE1C,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,EAAE,EAAE,CAAC;gBACP,OAAO,8BAA8B,EAAE,IAAI,CAAC;YAC9C,CAAC;YACD,IAAI,EAAE,EAAE,CAAC;gBACP,OAAO,8BAA8B,EAAE,IAAI,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,aAAa;QACb,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,UAAU,IAAI;CACf,CAAC;IAEA,cAAc;IACd,MAAM;IACN,wCAAwC;IACxC,qDAAqD;IACrD,qBAAqB;IACrB,uBAAuB;IACvB,yBAAyB;IACzB,yBAAyB;IACzB,0BAA0B;IAC1B,aAAa;IACb,OAAO;IACP,gDAAgD;IAChD,EAAE;IACF,6DAA6D;IAC7D,+GAA+G;IAC/G,OAAO;IACP,MAAM;IACN,EAAE;IACF,kCAAkC;IAClC,MAAM;IACN,wCAAwC;IACxC,qDAAqD;IACrD,qBAAqB;IACrB,uBAAuB;IACvB,yBAAyB;IACzB,yBAAyB;IACzB,0BAA0B;IAC1B,aAAa;IACb,OAAO;IACP,gDAAgD;IAChD,mCAAmC;IACnC,8FAA8F;IAC9F,iCAAiC;IACjC,EAAE;IACF,6DAA6D;IAC7D,+GAA+G;IAC/G,OAAO;IACP,MAAM;IACN,UAAU,IAAI,eAAe,CAAC,4CAA4C,CAAC,CAAC;IAC5E,UAAU,IAAI;;;;CAIf,CAAC;IAEA,UAAU,IAAI,eAAe,CAAC,sCAAsC,CAAC,CAAC;IACtE,UAAU,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,UAAU,IAAI,gBAAgB,EAAE,CAAC;IACjC,UAAU,IAAI,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAChD,UAAU,IAAI,gBAAgB,EAAE,CAAC;IACjC,UAAU,IAAI;;;;;;;;;;;;;;;;;;;;;;;;CAwBf,CAAC;IAEA,IAAI,uBAAuB,GAAW,0BAA0B,CAAC,UAAU,CAAC,CAAC;IAC7E,OAAO,uBAAuB,KAAK,CAAC,CAAC,EAAE,CAAC;QACtC,UAAU,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;QACtD,UAAU,IAAI,gBAAgB,EAAE,CAAC;QACjC,UAAU,IAAI;;;CAGjB,CAAC;QACE,uBAAuB,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,UAAU,IAAI,YAAY,EAAE,CAAC;IAE7B,YAAE,CAAC,aAAa,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAC/C,CAAC;AAhPD,8FAgPC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport fs from 'fs';\nimport {\n ESLINT_BULK_FORCE_REGENERATE_PATCH_ENV_VAR_NAME,\n ESLINT_BULK_PATCH_PATH_ENV_VAR_NAME\n} from './constants';\n\n/**\n * Dynamically generate file to properly patch many versions of ESLint\n * @param inputFilePath - Must be an iteration of https://github.com/eslint/eslint/blob/main/lib/linter/linter.js\n * @param outputFilePath - Some small changes to linter.js\n */\nexport function generatePatchedLinterJsFileIfDoesNotExist(\n inputFilePath: string,\n outputFilePath: string\n): void {\n const generateEnvVarValue: string | undefined =\n process.env[ESLINT_BULK_FORCE_REGENERATE_PATCH_ENV_VAR_NAME];\n if (generateEnvVarValue !== 'true' && generateEnvVarValue !== '1' && fs.existsSync(outputFilePath)) {\n return;\n }\n\n const inputFile: string = fs.readFileSync(inputFilePath).toString();\n\n let inputIndex: number = 0;\n\n /**\n * Extract from the stream until marker is reached. When matching marker,\n * ignore whitespace in the stream and in the marker. Return the extracted text.\n */\n function scanUntilMarker(marker: string): string {\n const trimmedMarker: string = marker.replace(/\\s/g, '');\n\n let output: string = '';\n let trimmed: string = '';\n\n while (inputIndex < inputFile.length) {\n const char: string = inputFile[inputIndex++];\n output += char;\n if (!/^\\s$/.test(char)) {\n trimmed += char;\n }\n if (trimmed.endsWith(trimmedMarker)) {\n return output;\n }\n }\n\n throw new Error('Unexpected end of input while looking for ' + JSON.stringify(marker));\n }\n\n function scanUntilNewline(): string {\n let output: string = '';\n\n while (inputIndex < inputFile.length) {\n const char: string = inputFile[inputIndex++];\n output += char;\n if (char === '\\n') {\n return output;\n }\n }\n\n throw new Error('Unexpected end of input while looking for new line');\n }\n\n function scanUntilEnd(): string {\n const output: string = inputFile.substring(inputIndex);\n inputIndex = inputFile.length;\n return output;\n }\n\n /**\n * Returns index of next public method\n * @param fromIndex - index of inputFile to search if public method still exists\n * @returns -1 if public method does not exist or index of next public method\n */\n function getIndexOfNextPublicMethod(fromIndex: number): number {\n const rest: string = inputFile.substring(fromIndex);\n\n const endOfClassIndex: number = rest.indexOf('\\n}');\n\n const markerForStartOfClassMethod: string = '\\n */\\n ';\n\n const startOfClassMethodIndex: number = rest.indexOf(markerForStartOfClassMethod);\n\n if (startOfClassMethodIndex === -1 || startOfClassMethodIndex > endOfClassIndex) {\n return -1;\n }\n\n const afterMarkerIndex: number =\n rest.indexOf(markerForStartOfClassMethod) + markerForStartOfClassMethod.length;\n\n const isPublicMethod: boolean =\n rest[afterMarkerIndex] !== '_' &&\n rest[afterMarkerIndex] !== '#' &&\n !rest.substring(afterMarkerIndex, rest.indexOf('\\n', afterMarkerIndex)).includes('static') &&\n !rest.substring(afterMarkerIndex, rest.indexOf('\\n', afterMarkerIndex)).includes('constructor');\n\n if (isPublicMethod) {\n return fromIndex + afterMarkerIndex;\n }\n\n return getIndexOfNextPublicMethod(fromIndex + afterMarkerIndex);\n }\n\n function scanUntilIndex(indexToScanTo: number): string {\n const output: string = inputFile.substring(inputIndex, indexToScanTo);\n inputIndex = indexToScanTo;\n return output;\n }\n\n let outputFile: string = '';\n\n // Match this:\n // //------------------------------------------------------------------------------\n // // Requirements\n // //------------------------------------------------------------------------------\n outputFile += scanUntilMarker('// Requirements');\n outputFile += scanUntilMarker('//--');\n outputFile += scanUntilNewline();\n\n outputFile += `\n// --- BEGIN MONKEY PATCH ---\nconst bulkSuppressionsPatch = require(process.env.${ESLINT_BULK_PATCH_PATH_ENV_VAR_NAME});\nconst requireFromPathToLinterJS = bulkSuppressionsPatch.requireFromPathToLinterJS;\n`;\n\n // Match this:\n // //------------------------------------------------------------------------------\n // // Typedefs\n // //------------------------------------------------------------------------------\n const requireSection: string = scanUntilMarker('// Typedefs');\n\n // Match something like this:\n //\n // const path = require('path'),\n // eslintScope = require('eslint-scope'),\n // evk = require('eslint-visitor-keys'),\n //\n // Convert to something like this:\n //\n // const path = require('path'),\n // eslintScope = requireFromPathToLinterJS('eslint-scope'),\n // evk = requireFromPathToLinterJS('eslint-visitor-keys'),\n //\n outputFile += requireSection.replace(/require\\s*\\((?:'([^']+)'|\"([^\"]+)\")\\)/g, (match, p1, p2) => {\n const importPath: string = p1 ?? p2 ?? '';\n\n if (importPath !== 'path') {\n if (p1) {\n return `requireFromPathToLinterJS('${p1}')`;\n }\n if (p2) {\n return `requireFromPathToLinterJS(\"${p2}\")`;\n }\n }\n\n // Keep as-is\n return match;\n });\n outputFile += `--- END MONKEY PATCH ---\n`;\n\n // Match this:\n // ```\n // if (reportTranslator === null) {\n // reportTranslator = createReportTranslator({\n // ruleId,\n // severity,\n // sourceCode,\n // messageIds,\n // disableFixes\n // });\n // }\n // const problem = reportTranslator(...args);\n //\n // if (problem.fix && !(rule.meta && rule.meta.fixable)) {\n // throw new Error(\"Fixable rules must set the `meta.fixable` property to \\\"code\\\" or \\\"whitespace\\\".\");\n // }\n // ```\n //\n // Convert to something like this:\n // ```\n // if (reportTranslator === null) {\n // reportTranslator = createReportTranslator({\n // ruleId,\n // severity,\n // sourceCode,\n // messageIds,\n // disableFixes\n // });\n // }\n // const problem = reportTranslator(...args);\n // // --- BEGIN MONKEY PATCH ---\n // if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId })) return;\n // // --- END MONKEY PATCH ---\n //\n // if (problem.fix && !(rule.meta && rule.meta.fixable)) {\n // throw new Error(\"Fixable rules must set the `meta.fixable` property to \\\"code\\\" or \\\"whitespace\\\".\");\n // }\n // ```\n outputFile += scanUntilMarker('const problem = reportTranslator(...args);');\n outputFile += `\n // --- BEGIN MONKEY PATCH ---\n if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId, problem })) return;\n // --- END MONKEY PATCH ---\n`;\n\n outputFile += scanUntilMarker('nodeQueue.forEach(traversalInfo => {');\n outputFile += scanUntilMarker('});');\n outputFile += scanUntilNewline();\n outputFile += scanUntilMarker('class Linter {');\n outputFile += scanUntilNewline();\n outputFile += `\n // --- BEGIN MONKEY PATCH ---\n /**\n * We intercept ESLint execution at the .eslintrc.js file, but unfortunately the Linter class is\n * initialized before the .eslintrc.js file is executed. This means the internalSlotsMap that all\n * the patched methods refer to is not initialized. This method checks if the internalSlotsMap is\n * initialized, and if not, initializes it.\n */\n _conditionallyReinitialize({ cwd, configType } = {}) {\n if (internalSlotsMap.get(this) === undefined) {\n internalSlotsMap.set(this, {\n cwd: normalizeCwd(cwd),\n lastConfigArray: null,\n lastSourceCode: null,\n lastSuppressedMessages: [],\n configType, // TODO: Remove after flat config conversion\n parserMap: new Map([['espree', espree]]),\n ruleMap: new Rules()\n });\n\n this.version = pkg.version;\n }\n }\n // --- END MONKEY PATCH ---\n`;\n\n let indexOfNextPublicMethod: number = getIndexOfNextPublicMethod(inputIndex);\n while (indexOfNextPublicMethod !== -1) {\n outputFile += scanUntilIndex(indexOfNextPublicMethod);\n outputFile += scanUntilNewline();\n outputFile += ` // --- BEGIN MONKEY PATCH ---\n this._conditionallyReinitialize();\n // --- END MONKEY PATCH ---\n`;\n indexOfNextPublicMethod = getIndexOfNextPublicMethod(inputIndex);\n }\n\n outputFile += scanUntilEnd();\n\n fs.writeFileSync(outputFilePath, outputFile);\n}\n"]}