diff --git a/.github/actions/prepare-build/action.yml b/.github/actions/prepare-build/action.yml index 227b60733b3..e88bd2cfb93 100644 --- a/.github/actions/prepare-build/action.yml +++ b/.github/actions/prepare-build/action.yml @@ -6,7 +6,7 @@ description: 'Prepares the repo for a job by running the build' runs: using: 'composite' steps: - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: build-cache with: path: '**/dist/**' diff --git a/.github/actions/prepare-install/action.yml b/.github/actions/prepare-install/action.yml index 4f701841d79..2334ef0b406 100644 --- a/.github/actions/prepare-install/action.yml +++ b/.github/actions/prepare-install/action.yml @@ -31,7 +31,7 @@ runs: run: echo ${{ github.ref }} - name: Use Node.js ${{ inputs.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} registry-url: ${{ inputs.registry-url }} @@ -47,7 +47,7 @@ runs: # Yarn rotates the downloaded cache archives, @see https://github.com/actions/setup-node/issues/325 # Yarn cache is also reusable between arch and os. - name: Restore yarn cache - uses: actions/cache@v3 + uses: actions/cache@v4 id: yarn-download-cache with: path: ${{ steps.yarn-config.outputs.CACHE_FOLDER }} @@ -58,7 +58,7 @@ runs: # Invalidated on yarn.lock changes - name: Restore yarn install state id: yarn-install-state-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: .yarn/ci-cache/ key: ${{ runner.os }}-yarn-install-state-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }} diff --git a/.github/actions/wait-for-netlify/action.yml b/.github/actions/wait-for-netlify/action.yml index f5095651e30..15111ea9c4d 100644 --- a/.github/actions/wait-for-netlify/action.yml +++ b/.github/actions/wait-for-netlify/action.yml @@ -11,5 +11,5 @@ inputs: description: How long to wait between retries of the Netlify api runs: - using: node16 + using: node20 main: index.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9951a2cc4bc..225405e2f4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -156,10 +156,10 @@ jobs: matrix: exclude: - os: windows-latest - node-version: 16 + node-version: 18 os: [ubuntu-latest, windows-latest] # just run on the oldest and latest supported versions and assume the intermediate versions are good - node-version: [16, 20] + node-version: [18, 20] package: [ 'ast-spec', diff --git a/docs/maintenance/pull-requests/Dependency_Version_Upgrades.mdx b/docs/maintenance/pull-requests/Dependency_Version_Upgrades.mdx index 73d4e4fbed2..6f14a129f17 100644 --- a/docs/maintenance/pull-requests/Dependency_Version_Upgrades.mdx +++ b/docs/maintenance/pull-requests/Dependency_Version_Upgrades.mdx @@ -116,6 +116,7 @@ A single PR can remove support for old TypeScript versions as a breaking change: 1. Update the `SUPPORTED_TYPESCRIPT_VERSIONS` constant in `warnAboutTSVersion.ts` 1. Update the `versions` constant in `version-check.ts` 1. Update [Users > Dependency Versions > TypeScript](../../users/Dependency_Versions.mdx#typescript) +1. Update `MIN_TS_VERSION_SEMVER` in `packages/website/src/components/OptionsSelector.tsx` 1. Search for source code comments (excluding `CHANGELOG.md` files) that mention a now-unsupported version of TypeScript. - For example, to remove support for v4.3, searches might include: - `4.3` diff --git a/docs/users/Dependency_Versions.mdx b/docs/users/Dependency_Versions.mdx index 1954306a646..386cb3a3d68 100644 --- a/docs/users/Dependency_Versions.mdx +++ b/docs/users/Dependency_Versions.mdx @@ -7,13 +7,25 @@ import packageJson from '../../package.json'; ## ESLint -> The version range of ESLint currently supported is `^7.0.0 || ^8.0.0`. +
+

+ The version range of ESLint currently supported is{' '} + {packageJson.devDependencies.eslint}. +

+
-We generally support at least the latest two major versions of ESLint. +We generally support at least the latest two major versions of ESLint; though sometimes we may restrict this if the APIs change too much between major releases. ## Node -This project makes an effort to support Active LTS and Maintenance LTS release statuses of Node according to [Node's release document](https://github.com/nodejs/release#release-schedule). +
+

+ The version range of NodeJS currently supported is{' '} + {packageJson.engines.node}. +

+
+ +We make an effort to support Active LTS and Maintenance LTS release statuses of Node according to [Node's release document](https://github.com/nodejs/release#release-schedule). Support for specific Current status releases are considered periodically. ## TypeScript @@ -25,7 +37,7 @@ Support for specific Current status releases are considered periodically.

-Note that we mirror [DefinitelyTyped's version support window](https://github.com/DefinitelyTyped/DefinitelyTyped/#support-window) - meaning we only support versions of TypeScript less than 2 years old. +We mirror [DefinitelyTyped's version support window](https://github.com/DefinitelyTyped/DefinitelyTyped/#support-window) - meaning we only support versions of TypeScript less than 2 years old. You may find that our tooling works on older TypeScript versions however we provide no guarantees and **_we will not accept issues against unsupported versions_**. diff --git a/package.json b/package.json index 23da68e6698..2baa28a19e7 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "typecheck": "npx nx run-many --target=typecheck --parallel" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "devDependencies": { "@actions/core": "^1.10.0", @@ -63,7 +63,6 @@ "@nx/eslint": "17.2.8", "@nx/jest": "17.2.8", "@nx/workspace": "17.2.8", - "@prettier/sync": "^0.5.0", "@swc/core": "^1.3.68", "@swc/jest": "^0.2.26", "@types/babel__code-frame": "^7.0.3", @@ -84,7 +83,7 @@ "cross-fetch": "^4.0.0", "cspell": "^7.0.0", "downlevel-dts": ">=0.11.0", - "eslint": "^8.56.0", + "eslint": "8.56.0", "eslint-plugin-deprecation": "^2.0.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^5.2.1", @@ -117,7 +116,7 @@ "ts-node": "10.7.0", "tslint": "^6.1.3", "tsx": "^4.6.2", - "typescript": ">=4.3.5 <5.4.0", + "typescript": ">=4.7.4 <5.4.0", "typescript-eslint": "workspace:^", "yargs": "17.7.2" }, @@ -139,6 +138,7 @@ "@types/estree": "link:./tools/dummypkg", "@types/node": "^20.0.0", "@types/react": "^18.2.14", + "eslint": "8.56.0", "eslint-visitor-keys": "^3.4.1", "jest-config": "^29", "jest-resolve": "^29", diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 89505dd0085..8e31ab2be3f 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -13,7 +13,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@prettier/sync": "*", + "@prettier/sync": "^0.5.0", "@typescript-eslint/rule-tester": "6.21.0", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/type-utils": "6.21.0", diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts index 4c13b42b9cc..19cb2d33fb1 100644 --- a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -2,7 +2,6 @@ import prettier from '@prettier/sync'; import { getContextualType } from '@typescript-eslint/type-utils'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -148,7 +147,6 @@ export default createRule({ }, ], create(context, [{ formatWithPrettier }]) { - const sourceCode = getSourceCode(context); const services = ESLintUtils.getParserServices(context); const checker = services.program.getTypeChecker(); @@ -326,7 +324,10 @@ export default createRule({ }); } - const parentIndent = getExpectedIndentForNode(literal, sourceCode.lines); + const parentIndent = getExpectedIndentForNode( + literal, + context.sourceCode.lines, + ); if (lastLine.length !== parentIndent) { return context.report({ node: literal, diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index ab3e3c3cfd8..2b0924bb783 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -49,7 +49,7 @@ "@typescript-eslint/utils": "6.21.0" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", + "eslint": "^8.56.0", "tslint": "^5.0.0 || ^6.0.0", "typescript": "*" }, diff --git a/packages/eslint-plugin-tslint/src/rules/config.ts b/packages/eslint-plugin-tslint/src/rules/config.ts index c9170531b50..89abe0507f5 100644 --- a/packages/eslint-plugin-tslint/src/rules/config.ts +++ b/packages/eslint-plugin-tslint/src/rules/config.ts @@ -1,9 +1,4 @@ import { ESLintUtils } from '@typescript-eslint/utils'; -import { - getCwd, - getFilename, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import path from 'path'; import type { RuleSeverity } from 'tslint'; import { Configuration } from 'tslint'; @@ -124,8 +119,7 @@ export default createRule({ context, [{ rules: tslintRules, rulesDirectory: tslintRulesDirectory, lintFile }], ) { - const fileName = path.resolve(getCwd(context), getFilename(context)); - const sourceCode = getSourceCode(context).text; + const fileName = path.resolve(context.cwd, context.filename); const services = ESLintUtils.getParserServices(context); const program = services.program; @@ -144,7 +138,7 @@ export default createRule({ tslintRules, tslintRulesDirectory, ); - tslint.lint(fileName, sourceCode, configuration); + tslint.lint(fileName, context.sourceCode.text, configuration); const result = tslint.getResult(); diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 66e90db95e5..8c19df75b90 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -51,8 +51,8 @@ "generate:breaking-changes": "yarn tsx tools/generate-breaking-changes.mts", "generate:configs": "npx nx run repo-tools:generate-configs", "lint": "npx nx lint", - "test": "jest --coverage --logHeapUsage", - "test-single": "jest --no-coverage", + "test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --logHeapUsage", + "test-single": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --no-coverage", "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { @@ -69,7 +69,6 @@ "ts-api-utils": "^1.0.1" }, "devDependencies": { - "@prettier/sync": "*", "@types/debug": "*", "@types/marked": "*", "@types/natural-compare": "*", @@ -77,7 +76,9 @@ "@typescript-eslint/rule-tester": "6.21.0", "ajv": "^6.12.6", "chalk": "^5.3.0", + "cross-env": "^7.0.3", "cross-fetch": "*", + "eslint": "*", "grapheme-splitter": "^1.0.4", "jest": "29.7.0", "jest-specific-snapshot": "^8.0.0", @@ -92,7 +93,7 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index b55e7202f55..52a40e2519c 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getNameFromMember, MemberNameType } from '../util'; @@ -31,8 +30,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); - interface Method { name: string; static: boolean; @@ -74,7 +71,7 @@ export default createRule({ } case AST_NODE_TYPES.TSMethodSignature: return { - ...getNameFromMember(member, sourceCode), + ...getNameFromMember(member, context.sourceCode), static: isStatic, callSignature: false, }; @@ -94,7 +91,7 @@ export default createRule({ }; case AST_NODE_TYPES.MethodDefinition: return { - ...getNameFromMember(member, sourceCode), + ...getNameFromMember(member, context.sourceCode), static: isStatic, callSignature: false, }; diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index 1474e330c03..fc8d5f32f80 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isParenthesized } from '../util'; @@ -135,8 +134,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); - const defaultOption = options.default; const readonlyOption = options.readonly ?? defaultOption; @@ -145,7 +142,7 @@ export default createRule({ */ function getMessageType(node: TSESTree.Node): string { if (isSimpleType(node)) { - return sourceCode.getText(node); + return context.sourceCode.getText(node); } return 'T'; } @@ -254,7 +251,7 @@ export default createRule({ const parentParens = readonlyPrefix && node.parent.type === AST_NODE_TYPES.TSArrayType && - !isParenthesized(node.parent.elementType, sourceCode); + !isParenthesized(node.parent.elementType, context.sourceCode); const start = `${parentParens ? '(' : ''}${readonlyPrefix}${ typeParens ? '(' : '' diff --git a/packages/eslint-plugin/src/rules/await-thenable.ts b/packages/eslint-plugin/src/rules/await-thenable.ts index e2c3767e913..084ea2447e8 100644 --- a/packages/eslint-plugin/src/rules/await-thenable.ts +++ b/packages/eslint-plugin/src/rules/await-thenable.ts @@ -1,5 +1,4 @@ import type { TSESLint } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import { @@ -51,9 +50,8 @@ export default createRule({ { messageId: 'removeAwait', fix(fixer): TSESLint.RuleFix { - const sourceCode = getSourceCode(context); const awaitKeyword = nullThrows( - sourceCode.getFirstToken(node, isAwaitKeyword), + context.sourceCode.getFirstToken(node, isAwaitKeyword), NullThrowsReasons.MissingToken('await', 'await expression'), ); diff --git a/packages/eslint-plugin/src/rules/ban-ts-comment.ts b/packages/eslint-plugin/src/rules/ban-ts-comment.ts index 5c70c7b9179..b0f964f58d1 100644 --- a/packages/eslint-plugin/src/rules/ban-ts-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-ts-comment.ts @@ -1,5 +1,4 @@ import { AST_TOKEN_TYPES, type TSESLint } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getStringLength } from '../util'; @@ -103,7 +102,6 @@ export default createRule<[Options], MessageIds>({ /^\/*\s*@ts-(?expect-error|ignore|check|nocheck)(?.*)/; const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@ts-(?expect-error|ignore|check|nocheck)(?.*)/; - const sourceCode = getSourceCode(context); const descriptionFormats = new Map(); for (const directive of [ @@ -120,7 +118,7 @@ export default createRule<[Options], MessageIds>({ return { Program(): void { - const comments = sourceCode.getAllComments(); + const comments = context.sourceCode.getAllComments(); comments.forEach(comment => { const regExp = diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts index 32189a2e3f1..4c84981a9fa 100644 --- a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -1,5 +1,4 @@ import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -32,10 +31,9 @@ export default createRule({ }, defaultOptions: [], create: context => { - const sourceCode = getSourceCode(context); return { Program(): void { - const comments = sourceCode.getAllComments(); + const comments = context.sourceCode.getAllComments(); comments.forEach(c => { if (ENABLE_DISABLE_REGEX.test(c.value)) { context.report({ @@ -43,11 +41,11 @@ export default createRule({ node: c, messageId: 'commentDetected', fix(fixer) { - const rangeStart = sourceCode.getIndexFromLoc({ + const rangeStart = context.sourceCode.getIndexFromLoc({ column: c.loc.start.column > 0 ? c.loc.start.column - 1 : 0, line: c.loc.start.line, }); - const rangeEnd = sourceCode.getIndexFromLoc({ + const rangeEnd = context.sourceCode.getIndexFromLoc({ column: c.loc.end.column, line: c.loc.end.line, }); diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 574c16937e9..da2d79716a3 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, objectReduceKey } from '../util'; @@ -219,7 +218,7 @@ export default createRule({ function checkBannedTypes( typeNode: TSESTree.Node, - name = stringifyNode(typeNode, getSourceCode(context)), + name = stringifyNode(typeNode, context.sourceCode), ): void { const bannedType = bannedTypes.get(name); diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index ac71dbb1d2b..e127bb1a6a0 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -33,7 +32,6 @@ export default createRule({ defaultOptions: ['always'], create(context, [whenToApplyOption]) { - const sourceCode = getSourceCode(context); const baseRules = baseRule.create(context); const always = whenToApplyOption !== 'never'; const messageId = always ? 'missing' : 'extra'; @@ -46,7 +44,7 @@ export default createRule({ ): TSESTree.PunctuatorToken { // guaranteed for enums // This is the only change made here from the base rule - return sourceCode.getFirstToken(node, { + return context.sourceCode.getFirstToken(node, { filter: token => token.type === AST_TOKEN_TYPES.Punctuator && token.value === '{', }) as TSESTree.PunctuatorToken; @@ -66,7 +64,7 @@ export default createRule({ function isValid(left: TSESTree.Token, right: TSESTree.Token): boolean { return ( !isTokenOnSameLine(left, right) || - sourceCode.isSpaceBetween!(left, right) === always + context.sourceCode.isSpaceBetween(left, right) === always ); } @@ -76,11 +74,11 @@ export default createRule({ function checkSpacingInsideBraces(node: TSESTree.TSEnumDeclaration): void { // Gets braces and the first/last token of content. const openBrace = getOpenBrace(node); - const closeBrace = sourceCode.getLastToken(node)!; - const firstToken = sourceCode.getTokenAfter(openBrace, { + const closeBrace = context.sourceCode.getLastToken(node)!; + const firstToken = context.sourceCode.getTokenAfter(openBrace, { includeComments: true, })!; - const lastToken = sourceCode.getTokenBefore(closeBrace, { + const lastToken = context.sourceCode.getTokenBefore(closeBrace, { includeComments: true, })!; diff --git a/packages/eslint-plugin/src/rules/brace-style.ts b/packages/eslint-plugin/src/rules/brace-style.ts index 6ab52b48ab2..ed76480e75f 100644 --- a/packages/eslint-plugin/src/rules/brace-style.ts +++ b/packages/eslint-plugin/src/rules/brace-style.ts @@ -1,5 +1,4 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -35,7 +34,7 @@ export default createRule({ context.options; const isAllmanStyle = style === 'allman'; - const sourceCode = getSourceCode(context); + const rules = baseRule.create(context); /** @@ -53,11 +52,11 @@ export default createRule({ } const tokenBeforeOpeningCurly = - sourceCode.getTokenBefore(openingCurlyToken)!; + context.sourceCode.getTokenBefore(openingCurlyToken)!; const tokenBeforeClosingCurly = - sourceCode.getTokenBefore(closingCurlyToken)!; + context.sourceCode.getTokenBefore(closingCurlyToken)!; const tokenAfterOpeningCurly = - sourceCode.getTokenAfter(openingCurlyToken)!; + context.sourceCode.getTokenAfter(openingCurlyToken)!; if ( !isAllmanStyle && @@ -71,7 +70,7 @@ export default createRule({ tokenBeforeOpeningCurly.range[1], openingCurlyToken.range[0], ]; - const textBetween = sourceCode.text.slice( + const textBetween = context.sourceCode.text.slice( textRange[0], textRange[1], ); @@ -124,14 +123,14 @@ export default createRule({ 'TSInterfaceBody, TSModuleBlock'( node: TSESTree.TSInterfaceBody | TSESTree.TSModuleBlock, ): void { - const openingCurly = sourceCode.getFirstToken(node)!; - const closingCurly = sourceCode.getLastToken(node)!; + const openingCurly = context.sourceCode.getFirstToken(node)!; + const closingCurly = context.sourceCode.getLastToken(node)!; validateCurlyPair(openingCurly, closingCurly); }, TSEnumDeclaration(node): void { - const closingCurly = sourceCode.getLastToken(node)!; - const openingCurly = sourceCode.getTokenBefore( + const closingCurly = context.sourceCode.getLastToken(node)!; + const openingCurly = context.sourceCode.getTokenBefore( node.members.length ? node.members[0] : closingCurly, )!; diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index d2212e8e751..483ad9a4080 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getStaticStringValue } from '../util'; @@ -66,10 +65,10 @@ export default createRule({ }, defaultOptions: ['fields'], create(context, [style]) { - const sourceCode = getSourceCode(context); - function getMethodName(node: TSESTree.MethodDefinition): string { - return getStaticStringValue(node.key) ?? sourceCode.getText(node.key); + return ( + getStaticStringValue(node.key) ?? context.sourceCode.getText(node.key) + ); } return { @@ -117,13 +116,13 @@ export default createRule({ { messageId: 'preferFieldStyleSuggestion', fix(fixer): TSESLint.RuleFix { - const name = sourceCode.getText(node.key); + const name = context.sourceCode.getText(node.key); let text = ''; text += printNodeModifiers(node, 'readonly'); text += node.computed ? `[${name}]` : name; - text += ` = ${sourceCode.getText(argument)};`; + text += ` = ${context.sourceCode.getText(argument)};`; return fixer.replaceText(node, text); }, @@ -151,14 +150,13 @@ export default createRule({ { messageId: 'preferGetterStyleSuggestion', fix(fixer): TSESLint.RuleFix { - const sourceCode = getSourceCode(context); - const name = sourceCode.getText(node.key); + const name = context.sourceCode.getText(node.key); let text = ''; text += printNodeModifiers(node, 'get'); text += node.computed ? `[${name}]` : name; - text += `() { return ${sourceCode.getText(value)}; }`; + text += `() { return ${context.sourceCode.getText(value)}; }`; return fixer.replaceText(node, text); }, diff --git a/packages/eslint-plugin/src/rules/class-methods-use-this.ts b/packages/eslint-plugin/src/rules/class-methods-use-this.ts index d6240415b06..6236a46ddb7 100644 --- a/packages/eslint-plugin/src/rules/class-methods-use-this.ts +++ b/packages/eslint-plugin/src/rules/class-methods-use-this.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -109,8 +108,6 @@ export default createRule({ }; let stack: Stack | undefined; - const sourceCode = getSourceCode(context); - function pushContext( member?: TSESTree.MethodDefinition | TSESTree.PropertyDefinition, ): void { @@ -220,7 +217,7 @@ export default createRule({ if (isIncludedInstanceMethod(stackContext.member)) { context.report({ node, - loc: getFunctionHeadLoc(node, sourceCode), + loc: getFunctionHeadLoc(node, context.sourceCode), messageId: 'missingThis', data: { name: getFunctionNameWithKind(node), diff --git a/packages/eslint-plugin/src/rules/comma-dangle.ts b/packages/eslint-plugin/src/rules/comma-dangle.ts index 45d94c4a491..60b48ecd0b2 100644 --- a/packages/eslint-plugin/src/rules/comma-dangle.ts +++ b/packages/eslint-plugin/src/rules/comma-dangle.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -97,7 +96,7 @@ export default createRule({ defaultOptions: ['never'], create(context, [options]) { const rules = baseRule.create(context); - const sourceCode = getSourceCode(context); + const normalizedOptions = normalizeOptions(options); const predicate = { @@ -129,13 +128,13 @@ export default createRule({ function getTrailingToken(node: TSESTree.Node): TSESTree.Token | null { const last = getLastItem(node); - const trailing = last && sourceCode.getTokenAfter(last); + const trailing = last && context.sourceCode.getTokenAfter(last); return trailing; } function isMultiline(node: TSESTree.Node): boolean { const last = getLastItem(node); - const lastToken = sourceCode.getLastToken(node); + const lastToken = context.sourceCode.getLastToken(node); return last?.loc.end.line !== lastToken?.loc.end.line; } diff --git a/packages/eslint-plugin/src/rules/comma-spacing.ts b/packages/eslint-plugin/src/rules/comma-spacing.ts index 09abc747b5a..e22bbaa73f4 100644 --- a/packages/eslint-plugin/src/rules/comma-spacing.ts +++ b/packages/eslint-plugin/src/rules/comma-spacing.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -58,8 +57,7 @@ export default createRule({ }, ], create(context, [{ before: spaceBefore, after: spaceAfter }]) { - const sourceCode = getSourceCode(context); - const tokensAndComments = sourceCode.tokensAndComments; + const tokensAndComments = context.sourceCode.tokensAndComments; const ignoredTokens = new Set(); /** @@ -69,16 +67,16 @@ export default createRule({ function addNullElementsToIgnoreList( node: TSESTree.ArrayExpression | TSESTree.ArrayPattern, ): void { - let previousToken = sourceCode.getFirstToken(node); + let previousToken = context.sourceCode.getFirstToken(node); for (const element of node.elements) { let token: TSESTree.Token | null; if (element == null) { - token = sourceCode.getTokenAfter(previousToken!); + token = context.sourceCode.getTokenAfter(previousToken!); if (token && isCommaToken(token)) { ignoredTokens.add(token); } } else { - token = sourceCode.getTokenAfter(element); + token = context.sourceCode.getTokenAfter(element); } previousToken = token; @@ -95,7 +93,7 @@ export default createRule({ const paramLength = node.params.length; if (paramLength) { const param = node.params[paramLength - 1]; - const afterToken = sourceCode.getTokenAfter(param); + const afterToken = context.sourceCode.getTokenAfter(param); if (afterToken && isCommaToken(afterToken)) { ignoredTokens.add(afterToken); } @@ -116,8 +114,7 @@ export default createRule({ if ( prevToken && isTokenOnSameLine(prevToken, commaToken) && - // eslint-disable-next-line deprecation/deprecation -- TODO - switch once our min ESLint version is 6.7.0 - spaceBefore !== sourceCode.isSpaceBetweenTokens(prevToken, commaToken) + spaceBefore !== context.sourceCode.isSpaceBetween(prevToken, commaToken) ) { context.report({ node: commaToken, @@ -154,8 +151,7 @@ export default createRule({ if ( nextToken && isTokenOnSameLine(commaToken, nextToken) && - // eslint-disable-next-line deprecation/deprecation -- TODO - switch once our min ESLint version is 6.7.0 - spaceAfter !== sourceCode.isSpaceBetweenTokens(commaToken, nextToken) + spaceAfter !== context.sourceCode.isSpaceBetween(commaToken, nextToken) ) { context.report({ node: commaToken, diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index 1913cdfc4e5..5ef447ede85 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -32,7 +31,6 @@ export default createRule({ }, defaultOptions: ['constructor'], create(context, [mode]) { - const sourceCode = getSourceCode(context); return { 'VariableDeclarator,PropertyDefinition,:matches(FunctionDeclaration,FunctionExpression) > AssignmentPattern'( node: @@ -79,7 +77,8 @@ export default createRule({ if (!lhs && rhs.typeArguments) { const { typeArguments, callee } = rhs; const typeAnnotation = - sourceCode.getText(callee) + sourceCode.getText(typeArguments); + context.sourceCode.getText(callee) + + context.sourceCode.getText(typeArguments); context.report({ node, messageId: 'preferTypeAnnotation', @@ -95,7 +94,7 @@ export default createRule({ } // If the property's computed, we have to attach the // annotation after the square bracket, not the enclosed expression - return sourceCode.getTokenAfter(node.key)!; + return context.sourceCode.getTokenAfter(node.key)!; } return [ fixer.remove(typeArguments), @@ -111,11 +110,12 @@ export default createRule({ } if (lhs?.typeArguments && !rhs.typeArguments) { - const hasParens = sourceCode.getTokenAfter(rhs.callee)?.value === '('; + const hasParens = + context.sourceCode.getTokenAfter(rhs.callee)?.value === '('; const extraComments = new Set( - sourceCode.getCommentsInside(lhs.parent), + context.sourceCode.getCommentsInside(lhs.parent), ); - sourceCode + context.sourceCode .getCommentsInside(lhs.typeArguments) .forEach(c => extraComments.delete(c)); context.report({ @@ -126,12 +126,12 @@ export default createRule({ for (const comment of extraComments) { yield fixer.insertTextAfter( rhs.callee, - sourceCode.getText(comment), + context.sourceCode.getText(comment), ); } yield fixer.insertTextAfter( rhs.callee, - sourceCode.getText(lhs.typeArguments), + context.sourceCode.getText(lhs.typeArguments), ); if (!hasParens) { yield fixer.insertTextAfter(rhs.callee, '()'); diff --git a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts index 601c47c4621..f0f91cc32b8 100644 --- a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts +++ b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -29,8 +28,6 @@ export default createRule({ }, defaultOptions: ['record'], create(context, [mode]) { - const sourceCode = getSourceCode(context); - function checkMembers( members: TSESTree.TypeElement[], node: TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeLiteral, @@ -64,7 +61,7 @@ export default createRule({ } if (parentId) { - const scope = getScope(context); + const scope = context.sourceCode.getScope(parentId); const superVar = ASTUtils.findVariable(scope, parentId.name); if (superVar) { const isCircular = superVar.references.some( @@ -84,8 +81,10 @@ export default createRule({ messageId: 'preferRecord', fix: safeFix ? (fixer): TSESLint.RuleFix => { - const key = sourceCode.getText(keyType.typeAnnotation); - const value = sourceCode.getText(valueType.typeAnnotation); + const key = context.sourceCode.getText(keyType.typeAnnotation); + const value = context.sourceCode.getText( + valueType.typeAnnotation, + ); const record = member.readonly ? `Readonly>` : `Record<${key}, ${value}>`; @@ -115,8 +114,8 @@ export default createRule({ node, messageId: 'preferIndexSignature', fix(fixer) { - const key = sourceCode.getText(params[0]); - const type = sourceCode.getText(params[1]); + const key = context.sourceCode.getText(params[0]); + const type = context.sourceCode.getText(params[1]); return fixer.replaceText(node, `{ [key: ${key}]: ${type} }`); }, }); @@ -132,7 +131,7 @@ export default createRule({ if (node.typeParameters?.params.length) { genericTypes = `<${node.typeParameters.params - .map(p => sourceCode.getText(p)) + .map(p => context.sourceCode.getText(p)) .join(', ')}>`; } diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index ed3b0bf487a..418cfa48f92 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as ts from 'typescript'; import { @@ -91,7 +90,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); const parserServices = getParserServices(context, true); function isConst(node: TSESTree.TypeNode): boolean { @@ -110,12 +108,12 @@ export default createRule({ let beforeCount = 0; let afterCount = 0; - if (isParenthesized(node, sourceCode)) { - const bodyOpeningParen = sourceCode.getTokenBefore( + if (isParenthesized(node, context.sourceCode)) { + const bodyOpeningParen = context.sourceCode.getTokenBefore( node, isOpeningParenToken, )!; - const bodyClosingParen = sourceCode.getTokenAfter( + const bodyClosingParen = context.sourceCode.getTokenAfter( node, isClosingParenToken, )!; @@ -124,7 +122,7 @@ export default createRule({ afterCount = bodyClosingParen.range[1] - node.range[1]; } - return sourceCode.getText(node, beforeCount, afterCount); + return context.sourceCode.getText(node, beforeCount, afterCount); } function reportIncorrectAssertionType( @@ -141,7 +139,7 @@ export default createRule({ messageId, data: messageId !== 'never' - ? { cast: sourceCode.getText(node.typeAnnotation) } + ? { cast: context.sourceCode.getText(node.typeAnnotation) } : {}, fix: messageId === 'as' @@ -154,8 +152,10 @@ export default createRule({ * AsExpression has lower precedence than TypeAssertionExpression, * so we don't need to wrap expression and typeAnnotation in parens. */ - const expressionCode = sourceCode.getText(node.expression); - const typeAnnotationCode = sourceCode.getText( + const expressionCode = context.sourceCode.getText( + node.expression, + ); + const typeAnnotationCode = context.sourceCode.getText( node.typeAnnotation, ); @@ -177,7 +177,7 @@ export default createRule({ const text = `${expressionCode} as ${typeAnnotationCode}`; return fixer.replaceText( node, - isParenthesized(node, sourceCode) + isParenthesized(node, context.sourceCode) ? text : getWrappedCode(text, asPrecedence, parentPrecedence), ); @@ -235,11 +235,11 @@ export default createRule({ const { parent } = node; suggest.push({ messageId: 'replaceObjectTypeAssertionWithAnnotation', - data: { cast: sourceCode.getText(node.typeAnnotation) }, + data: { cast: context.sourceCode.getText(node.typeAnnotation) }, fix: fixer => [ fixer.insertTextAfter( parent.id, - `: ${sourceCode.getText(node.typeAnnotation)}`, + `: ${context.sourceCode.getText(node.typeAnnotation)}`, ), fixer.replaceText(node, getTextWithParentheses(node.expression)), ], @@ -247,14 +247,12 @@ export default createRule({ } suggest.push({ messageId: 'replaceObjectTypeAssertionWithSatisfies', - data: { cast: sourceCode.getText(node.typeAnnotation) }, + data: { cast: context.sourceCode.getText(node.typeAnnotation) }, fix: fixer => [ fixer.replaceText(node, getTextWithParentheses(node.expression)), fixer.insertTextAfter( node, - ` satisfies ${getSourceCode(context).getText( - node.typeAnnotation, - )}`, + ` satisfies ${context.sourceCode.getText(node.typeAnnotation)}`, ), ], }); diff --git a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts index 7a10fd392fe..1b0f405f73e 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts @@ -1,9 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { - getAncestors, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -30,19 +26,21 @@ export default createRule({ }, defaultOptions: ['interface'], create(context, [option]) { - const sourceCode = getSourceCode(context); - /** * Iterates from the highest parent to the currently traversed node * to determine whether any node in tree is globally declared module declaration */ - function isCurrentlyTraversedNodeWithinModuleDeclaration(): boolean { - return getAncestors(context).some( - node => - node.type === AST_NODE_TYPES.TSModuleDeclaration && - node.declare && - node.global, - ); + function isCurrentlyTraversedNodeWithinModuleDeclaration( + node: TSESTree.Node, + ): boolean { + return context.sourceCode + .getAncestors(node) + .some( + node => + node.type === AST_NODE_TYPES.TSModuleDeclaration && + node.declare && + node.global, + ); } return { @@ -57,7 +55,7 @@ export default createRule({ const typeNode = node.typeParameters ?? node.id; const fixes: TSESLint.RuleFix[] = []; - const firstToken = sourceCode.getTokenBefore(node.id); + const firstToken = context.sourceCode.getTokenBefore(node.id); if (firstToken) { fixes.push(fixer.replaceText(firstToken, 'interface')); fixes.push( @@ -68,7 +66,9 @@ export default createRule({ ); } - const afterToken = sourceCode.getTokenAfter(node.typeAnnotation); + const afterToken = context.sourceCode.getTokenAfter( + node.typeAnnotation, + ); if ( afterToken && afterToken.type === AST_TOKEN_TYPES.Punctuator && @@ -84,13 +84,13 @@ export default createRule({ }), ...(option === 'type' && { TSInterfaceDeclaration(node): void { - const fix = isCurrentlyTraversedNodeWithinModuleDeclaration() + const fix = isCurrentlyTraversedNodeWithinModuleDeclaration(node) ? null : (fixer: TSESLint.RuleFixer): TSESLint.RuleFix[] => { const typeNode = node.typeParameters ?? node.id; const fixes: TSESLint.RuleFix[] = []; - const firstToken = sourceCode.getTokenBefore(node.id); + const firstToken = context.sourceCode.getTokenBefore(node.id); if (firstToken) { fixes.push(fixer.replaceText(firstToken, 'type')); fixes.push( @@ -102,7 +102,7 @@ export default createRule({ } node.extends.forEach(heritage => { - const typeIdentifier = sourceCode.getText(heritage); + const typeIdentifier = context.sourceCode.getText(heritage); fixes.push( fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`), ); diff --git a/packages/eslint-plugin/src/rules/consistent-type-exports.ts b/packages/eslint-plugin/src/rules/consistent-type-exports.ts index 78efc59bb85..236659d13ad 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-exports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-exports.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { SymbolFlags } from 'typescript'; import { @@ -75,7 +74,6 @@ export default createRule({ ], create(context, [{ fixMixedExportsWithInlineTypeSpecifier }]) { - const sourceCode = getSourceCode(context); const sourceExportsMap: Record = {}; const services = getParserServices(context); @@ -181,7 +179,11 @@ export default createRule({ node: report.node, messageId: 'typeOverValue', *fix(fixer) { - yield* fixExportInsertType(fixer, sourceCode, report.node); + yield* fixExportInsertType( + fixer, + context.sourceCode, + report.node, + ); }, }); continue; @@ -203,7 +205,11 @@ export default createRule({ if (fixMixedExportsWithInlineTypeSpecifier) { yield* fixAddTypeSpecifierToNamedExports(fixer, report); } else { - yield* fixSeparateNamedExports(fixer, sourceCode, report); + yield* fixSeparateNamedExports( + fixer, + context.sourceCode, + report, + ); } }, }); @@ -218,7 +224,11 @@ export default createRule({ if (fixMixedExportsWithInlineTypeSpecifier) { yield* fixAddTypeSpecifierToNamedExports(fixer, report); } else { - yield* fixSeparateNamedExports(fixer, sourceCode, report); + yield* fixSeparateNamedExports( + fixer, + context.sourceCode, + report, + ); } }, }); diff --git a/packages/eslint-plugin/src/rules/consistent-type-imports.ts b/packages/eslint-plugin/src/rules/consistent-type-imports.ts index b6d2a0fdce8..b4d0dbd52ac 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-imports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-imports.ts @@ -1,9 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { - getDeclaredVariables, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -108,7 +104,6 @@ export default createRule({ const prefer = option.prefer ?? 'type-imports'; const disallowTypeAnnotations = option.disallowTypeAnnotations !== false; const fixStyle = option.fixStyle ?? 'separate-type-imports'; - const sourceCode = getSourceCode(context); const sourceImportsMap: Record = {}; @@ -172,7 +167,8 @@ export default createRule({ continue; } - const [variable] = getDeclaredVariables(context, specifier); + const [variable] = + context.sourceCode.getDeclaredVariables(specifier); if (variable.references.length === 0) { unusedSpecifiers.push(specifier); } else { @@ -456,18 +452,18 @@ export default createRule({ // import Foo, {Type1, Type2} from 'foo' // import DefType, {Type1, Type2} from 'foo' const openingBraceToken = nullThrows( - sourceCode.getTokenBefore( + context.sourceCode.getTokenBefore( subsetNamedSpecifiers[0], isOpeningBraceToken, ), NullThrowsReasons.MissingToken('{', node.type), ); const commaToken = nullThrows( - sourceCode.getTokenBefore(openingBraceToken, isCommaToken), + context.sourceCode.getTokenBefore(openingBraceToken, isCommaToken), NullThrowsReasons.MissingToken(',', node.type), ); const closingBraceToken = nullThrows( - sourceCode.getFirstTokenBetween( + context.sourceCode.getFirstTokenBetween( openingBraceToken, node.source, isClosingBraceToken, @@ -482,7 +478,7 @@ export default createRule({ ); typeNamedSpecifiersTexts.push( - sourceCode.text.slice( + context.sourceCode.text.slice( openingBraceToken.range[1], closingBraceToken.range[0], ), @@ -508,7 +504,9 @@ export default createRule({ ); removeTypeNamedSpecifiers.push(fixer.removeRange(removeRange)); - typeNamedSpecifiersTexts.push(sourceCode.text.slice(...textRange)); + typeNamedSpecifiersTexts.push( + context.sourceCode.text.slice(...textRange), + ); } } return { @@ -531,7 +529,7 @@ export default createRule({ const last = namedSpecifierGroup[namedSpecifierGroup.length - 1]; const removeRange: TSESTree.Range = [first.range[0], last.range[1]]; const textRange: TSESTree.Range = [...removeRange]; - const before = sourceCode.getTokenBefore(first)!; + const before = context.sourceCode.getTokenBefore(first)!; textRange[0] = before.range[1]; if (isCommaToken(before)) { removeRange[0] = before.range[0]; @@ -541,7 +539,7 @@ export default createRule({ const isFirst = allNamedSpecifiers[0] === first; const isLast = allNamedSpecifiers[allNamedSpecifiers.length - 1] === last; - const after = sourceCode.getTokenAfter(last)!; + const after = context.sourceCode.getTokenAfter(last)!; textRange[1] = after.range[0]; if (isFirst || isLast) { if (isCommaToken(after)) { @@ -567,14 +565,14 @@ export default createRule({ insertText: string, ): TSESLint.RuleFix { const closingBraceToken = nullThrows( - sourceCode.getFirstTokenBetween( - sourceCode.getFirstToken(target)!, + context.sourceCode.getFirstTokenBetween( + context.sourceCode.getFirstToken(target)!, target.source, isClosingBraceToken, ), NullThrowsReasons.MissingToken('}', target.type), ); - const before = sourceCode.getTokenBefore(closingBraceToken)!; + const before = context.sourceCode.getTokenBefore(closingBraceToken)!; if (!isCommaToken(before) && !isOpeningBraceToken(before)) { insertText = `,${insertText}`; } @@ -592,7 +590,7 @@ export default createRule({ typeSpecifiers: TSESTree.ImportSpecifier[], ): IterableIterator { for (const spec of typeSpecifiers) { - const insertText = sourceCode.text.slice(...spec.range); + const insertText = context.sourceCode.text.slice(...spec.range); yield fixer.replaceTextRange(spec.range, `type ${insertText}`); } } @@ -717,17 +715,21 @@ export default createRule({ node, `import {${typeNamedSpecifiers .map(spec => { - const insertText = sourceCode.text.slice(...spec.range); + const insertText = context.sourceCode.text.slice( + ...spec.range, + ); return `type ${insertText}`; }) - .join(', ')}} from ${sourceCode.getText(node.source)};\n`, + .join( + ', ', + )}} from ${context.sourceCode.getText(node.source)};\n`, ); } else { yield fixer.insertTextBefore( node, `import type {${ fixesNamedSpecifiers.typeNamedSpecifiersText - }} from ${sourceCode.getText(node.source)};\n`, + }} from ${context.sourceCode.getText(node.source)};\n`, ); } } @@ -742,7 +744,7 @@ export default createRule({ // import DefType, * as Type from 'foo' // import DefType, * as Type from 'foo' const commaToken = nullThrows( - sourceCode.getTokenBefore(namespaceSpecifier, isCommaToken), + context.sourceCode.getTokenBefore(namespaceSpecifier, isCommaToken), NullThrowsReasons.MissingToken(',', node.type), ); @@ -756,9 +758,9 @@ export default createRule({ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ insert yield fixer.insertTextBefore( node, - `import type ${sourceCode.getText( + `import type ${context.sourceCode.getText( namespaceSpecifier, - )} from ${sourceCode.getText(node.source)};\n`, + )} from ${context.sourceCode.getText(node.source)};\n`, ); } if ( @@ -767,7 +769,7 @@ export default createRule({ ) { if (report.typeSpecifiers.length === node.specifiers.length) { const importToken = nullThrows( - sourceCode.getFirstToken(node, isImportKeyword), + context.sourceCode.getFirstToken(node, isImportKeyword), NullThrowsReasons.MissingToken('import', node.type), ); // import type Type from 'foo' @@ -775,22 +777,24 @@ export default createRule({ yield fixer.insertTextAfter(importToken, ' type'); } else { const commaToken = nullThrows( - sourceCode.getTokenAfter(defaultSpecifier, isCommaToken), + context.sourceCode.getTokenAfter(defaultSpecifier, isCommaToken), NullThrowsReasons.MissingToken(',', defaultSpecifier.type), ); // import Type , {...} from 'foo' // ^^^^^ pick - const defaultText = sourceCode.text + const defaultText = context.sourceCode.text .slice(defaultSpecifier.range[0], commaToken.range[0]) .trim(); yield fixer.insertTextBefore( node, - `import type ${defaultText} from ${sourceCode.getText( + `import type ${defaultText} from ${context.sourceCode.getText( node.source, )};\n`, ); const afterToken = nullThrows( - sourceCode.getTokenAfter(commaToken, { includeComments: true }), + context.sourceCode.getTokenAfter(commaToken, { + includeComments: true, + }), NullThrowsReasons.MissingToken('any token', node.type), ); // import Type , {...} from 'foo' @@ -816,14 +820,14 @@ export default createRule({ // import type Foo from 'foo' // ^^^^^ insert const importToken = nullThrows( - sourceCode.getFirstToken(node, isImportKeyword), + context.sourceCode.getFirstToken(node, isImportKeyword), NullThrowsReasons.MissingToken('import', node.type), ); yield fixer.insertTextAfter(importToken, ' type'); if (isDefaultImport) { // Has default import - const openingBraceToken = sourceCode.getFirstTokenBetween( + const openingBraceToken = context.sourceCode.getFirstTokenBetween( importToken, node.source, isOpeningBraceToken, @@ -831,11 +835,11 @@ export default createRule({ if (openingBraceToken) { // Only braces. e.g. import Foo, {} from 'foo' const commaToken = nullThrows( - sourceCode.getTokenBefore(openingBraceToken, isCommaToken), + context.sourceCode.getTokenBefore(openingBraceToken, isCommaToken), NullThrowsReasons.MissingToken(',', node.type), ); const closingBraceToken = nullThrows( - sourceCode.getFirstTokenBetween( + context.sourceCode.getFirstTokenBetween( openingBraceToken, node.source, isClosingBraceToken, @@ -849,14 +853,14 @@ export default createRule({ commaToken.range[0], closingBraceToken.range[1], ]); - const specifiersText = sourceCode.text.slice( + const specifiersText = context.sourceCode.text.slice( commaToken.range[1], closingBraceToken.range[1], ); if (node.specifiers.length > 1) { yield fixer.insertTextAfter( node, - `\nimport type${specifiersText} from ${sourceCode.getText( + `\nimport type${specifiersText} from ${context.sourceCode.getText( node.source, )};`, ); @@ -944,7 +948,7 @@ export default createRule({ node, `import {${ fixesNamedSpecifiers.typeNamedSpecifiersText - }} from ${sourceCode.getText(node.source)};\n`, + }} from ${context.sourceCode.getText(node.source)};\n`, ); } } @@ -961,11 +965,11 @@ export default createRule({ // import type Foo from 'foo' // ^^^^ remove const importToken = nullThrows( - sourceCode.getFirstToken(node, isImportKeyword), + context.sourceCode.getFirstToken(node, isImportKeyword), NullThrowsReasons.MissingToken('import', node.type), ); const typeToken = nullThrows( - sourceCode.getFirstTokenBetween( + context.sourceCode.getFirstTokenBetween( importToken, node.specifiers[0]?.local ?? node.source, isTypeKeyword, @@ -973,7 +977,7 @@ export default createRule({ NullThrowsReasons.MissingToken('type', node.type), ); const afterToken = nullThrows( - sourceCode.getTokenAfter(typeToken, { includeComments: true }), + context.sourceCode.getTokenAfter(typeToken, { includeComments: true }), NullThrowsReasons.MissingToken('any token', node.type), ); yield fixer.removeRange([typeToken.range[0], afterToken.range[0]]); @@ -986,11 +990,11 @@ export default createRule({ // import { type Foo } from 'foo' // ^^^^ remove const typeToken = nullThrows( - sourceCode.getFirstToken(node, isTypeKeyword), + context.sourceCode.getFirstToken(node, isTypeKeyword), NullThrowsReasons.MissingToken('type', node.type), ); const afterToken = nullThrows( - sourceCode.getTokenAfter(typeToken, { includeComments: true }), + context.sourceCode.getTokenAfter(typeToken, { includeComments: true }), NullThrowsReasons.MissingToken('any token', node.type), ); yield fixer.removeRange([typeToken.range[0], afterToken.range[0]]); diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index e6201df8e9e..d135f4c1a0d 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; import { @@ -99,7 +98,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); function isAllowedFunction( node: | TSESTree.ArrowFunctionExpression @@ -196,7 +194,7 @@ export default createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, context.sourceCode, loc => context.report({ node, loc, @@ -212,7 +210,7 @@ export default createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => + checkFunctionReturnType(node, options, context.sourceCode, loc => context.report({ node, loc, diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 18919815cd1..52453371540 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getNameFromMember } from '../util'; @@ -99,7 +98,6 @@ export default createRule({ }, defaultOptions: [{ accessibility: 'explicit' }], create(context, [option]) { - const sourceCode = getSourceCode(context); const baseCheck: AccessibilityLevel = option.accessibility ?? 'explicit'; const overrides = option.overrides ?? {}; const ctorCheck = overrides.constructors ?? baseCheck; @@ -138,7 +136,7 @@ export default createRule({ const { name: methodName } = getNameFromMember( methodDefinition, - sourceCode, + context.sourceCode, ); if (check === 'off' || ignoredMethodNames.has(methodName)) { @@ -183,7 +181,7 @@ export default createRule({ | TSESTree.TSParameterProperty, ): TSESLint.ReportFixFunction { return function (fixer: TSESLint.RuleFixer): TSESLint.RuleFix { - const tokens = sourceCode.getTokens(node); + const tokens = context.sourceCode.getTokens(node); let rangeToRemove: TSESLint.AST.Range; for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; @@ -192,7 +190,7 @@ export default createRule({ token.value === 'public' ) { const commensAfterPublicKeyword = - sourceCode.getCommentsAfter(token); + context.sourceCode.getCommentsAfter(token); if (commensAfterPublicKeyword.length) { // public /* Hi there! */ static foo() // ^^^^^^^ @@ -230,7 +228,7 @@ export default createRule({ ): TSESLint.RuleFix | null { if (node.decorators.length) { const lastDecorator = node.decorators[node.decorators.length - 1]; - const nextToken = sourceCode.getTokenAfter(lastDecorator)!; + const nextToken = context.sourceCode.getTokenAfter(lastDecorator)!; return fixer.insertTextBefore(nextToken, `${accessibility} `); } return fixer.insertTextBefore(node, `${accessibility} `); @@ -272,7 +270,7 @@ export default createRule({ const { name: propertyName } = getNameFromMember( propertyDefinition, - sourceCode, + context.sourceCode, ); if ( propCheck === 'no-public' && diff --git a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts index 092179f8187..f04a71de8b6 100644 --- a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts +++ b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts @@ -1,7 +1,6 @@ import { DefinitionType } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isFunction } from '../util'; import type { @@ -99,8 +98,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); - // tracks all of the functions we've already checked const checkedFunctions = new Set(); @@ -295,7 +292,7 @@ export default createRule({ } function followReference(node: TSESTree.Identifier): void { - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); const variable = scope.set.get(node.name); /* istanbul ignore if */ if (!variable) { return; @@ -436,13 +433,18 @@ export default createRule({ return; } - checkFunctionExpressionReturnType(node, options, sourceCode, loc => { - context.report({ - node, - loc, - messageId: 'missingReturnType', - }); - }); + checkFunctionExpressionReturnType( + node, + options, + context.sourceCode, + loc => { + context.report({ + node, + loc, + messageId: 'missingReturnType', + }); + }, + ); checkParameters(node); } @@ -457,7 +459,7 @@ export default createRule({ return; } - checkFunctionReturnType(node, options, sourceCode, loc => { + checkFunctionReturnType(node, options, context.sourceCode, loc => { context.report({ node, loc, diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index 510730fca99..4e87b7c6d07 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -1,5 +1,4 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -77,8 +76,7 @@ export default createRule({ }, defaultOptions: ['never', {}], create(context, [option, config]) { - const sourceCode = getSourceCode(context); - const text = sourceCode.getText(); + const text = context.sourceCode.getText(); /** * Check if open space is present in a function name @@ -90,11 +88,10 @@ export default createRule({ ): void { const isOptionalCall = isOptionalCallExpression(node); - const closingParenToken = sourceCode.getLastToken(node)!; - const lastCalleeTokenWithoutPossibleParens = sourceCode.getLastToken( - node.typeArguments ?? node.callee, - )!; - const openingParenToken = sourceCode.getFirstTokenBetween( + const closingParenToken = context.sourceCode.getLastToken(node)!; + const lastCalleeTokenWithoutPossibleParens = + context.sourceCode.getLastToken(node.typeArguments ?? node.callee)!; + const openingParenToken = context.sourceCode.getFirstTokenBetween( lastCalleeTokenWithoutPossibleParens, closingParenToken, isOpeningParenToken, @@ -103,7 +100,7 @@ export default createRule({ // new expression with no parens... return; } - const lastCalleeToken = sourceCode.getTokenBefore( + const lastCalleeToken = context.sourceCode.getTokenBefore( openingParenToken, isNotOptionalChainPunctuator, )!; diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index c2d61583405..1f25bd79451 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -7,7 +7,6 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -381,8 +380,7 @@ export default createRule({ }, TSMappedType(node: TSESTree.TSMappedType) { - const sourceCode = getSourceCode(context); - const squareBracketStart = sourceCode.getTokenBefore( + const squareBracketStart = context.sourceCode.getTokenBefore( node.typeParameter, )!; diff --git a/packages/eslint-plugin/src/rules/key-spacing.ts b/packages/eslint-plugin/src/rules/key-spacing.ts index bb882d1e8b4..28ba361e7a7 100644 --- a/packages/eslint-plugin/src/rules/key-spacing.ts +++ b/packages/eslint-plugin/src/rules/key-spacing.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -43,7 +42,6 @@ export default createRule({ defaultOptions: [{}], create(context, [options]) { - const sourceCode = getSourceCode(context); const baseRules = baseRule.create(context); /** @@ -52,7 +50,7 @@ export default createRule({ function adjustedColumn(position: TSESTree.Position): number { const line = position.line - 1; // position.line is 1-indexed return getStringLength( - sourceCode.lines.at(line)!.slice(0, position.column), + context.sourceCode.lines.at(line)!.slice(0, position.column), ); } @@ -61,9 +59,9 @@ export default createRule({ * until it finds the last token before a colon punctuator and returns it. */ function getLastTokenBeforeColon(node: TSESTree.Node): TSESTree.Token { - const colonToken = sourceCode.getTokenAfter(node, isColonToken)!; + const colonToken = context.sourceCode.getTokenAfter(node, isColonToken)!; - return sourceCode.getTokenBefore(colonToken)!; + return context.sourceCode.getTokenBefore(colonToken)!; } type KeyTypeNode = @@ -100,13 +98,13 @@ export default createRule({ */ function getKeyText(node: KeyTypeNodeWithTypeAnnotation): string { if (node.type !== AST_NODE_TYPES.TSIndexSignature) { - return sourceCode.getText(node.key); + return context.sourceCode.getText(node.key); } - const code = sourceCode.getText(node); + const code = context.sourceCode.getText(node); return code.slice( 0, - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( node.parameters.at(-1)!, isClosingBracketToken, )!.range[1] - node.range[0], @@ -165,8 +163,8 @@ export default createRule({ mode: 'minimum' | 'strict', ): void { const { typeAnnotation } = node; - const colonToken = sourceCode.getFirstToken(typeAnnotation)!; - const typeStart = sourceCode.getTokenAfter(colonToken, { + const colonToken = context.sourceCode.getFirstToken(typeAnnotation)!; + const typeStart = context.sourceCode.getTokenAfter(colonToken, { includeComments: true, })!.loc.start.column; const difference = @@ -218,7 +216,7 @@ export default createRule({ * last comment is adjacent to the candidate property, and that successive * comments are adjacent to each other. */ - const leadingComments = sourceCode.getCommentsBefore(candidate); + const leadingComments = context.sourceCode.getCommentsBefore(candidate); if ( leadingComments.length && diff --git a/packages/eslint-plugin/src/rules/keyword-spacing.ts b/packages/eslint-plugin/src/rules/keyword-spacing.ts index b3690006298..ff3878ec634 100644 --- a/packages/eslint-plugin/src/rules/keyword-spacing.ts +++ b/packages/eslint-plugin/src/rules/keyword-spacing.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; import type { @@ -52,13 +51,12 @@ export default createRule({ defaultOptions: [{}], create(context, [{ after, overrides }]) { - const sourceCode = getSourceCode(context); const baseRules = baseRule.create(context); return { ...baseRules, TSAsExpression(node): void { const asToken = nullThrows( - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( node.expression, token => token.value === 'as', ), @@ -81,8 +79,8 @@ export default createRule({ node: TSESTree.ImportDeclaration, ): void { const { type: typeOptionOverride = {} } = overrides ?? {}; - const typeToken = sourceCode.getFirstToken(node, { skip: 1 })!; - const punctuatorToken = sourceCode.getTokenAfter(typeToken)!; + const typeToken = context.sourceCode.getFirstToken(node, { skip: 1 })!; + const punctuatorToken = context.sourceCode.getTokenAfter(typeToken)!; if ( node.specifiers[0]?.type === AST_NODE_TYPES.ImportDefaultSpecifier ) { diff --git a/packages/eslint-plugin/src/rules/lines-around-comment.ts b/packages/eslint-plugin/src/rules/lines-around-comment.ts index 9c25d24351a..1e731bbdf76 100644 --- a/packages/eslint-plugin/src/rules/lines-around-comment.ts +++ b/packages/eslint-plugin/src/rules/lines-around-comment.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -151,10 +150,9 @@ export default createRule({ const defaultIgnoreRegExp = COMMENTS_IGNORE_PATTERN; const customIgnoreRegExp = new RegExp(options.ignorePattern ?? '', 'u'); - const sourceCode = getSourceCode(context); - const comments = sourceCode.getAllComments(); + const comments = context.sourceCode.getAllComments(); - const lines = sourceCode.lines; + const lines = context.sourceCode.lines; const commentLines = getCommentLineNums(comments); const emptyLines = getEmptyLineNums(lines); const commentAndEmptyLines = new Set(commentLines.concat(emptyLines)); @@ -166,7 +164,7 @@ export default createRule({ let currentToken: TSESTree.Token | null = token; do { - currentToken = sourceCode.getTokenBefore(currentToken, { + currentToken = context.sourceCode.getTokenBefore(currentToken, { includeComments: true, }); } while (currentToken && isCommentToken(currentToken)); @@ -177,7 +175,7 @@ export default createRule({ currentToken = token; do { - currentToken = sourceCode.getTokenAfter(currentToken, { + currentToken = context.sourceCode.getTokenAfter(currentToken, { includeComments: true, }); } while (currentToken && isCommentToken(currentToken)); @@ -203,7 +201,7 @@ export default createRule({ * @returns the parent node that contains the given token. */ function getParentNodeOfToken(token: TSESTree.Token): TSESTree.Node | null { - const node = sourceCode.getNodeByRangeIndex(token.range[0]); + const node = context.sourceCode.getNodeByRangeIndex(token.range[0]); return node; } @@ -346,10 +344,10 @@ export default createRule({ enumEndAllowed || moduleEndAllowed; - const previousTokenOrComment = sourceCode.getTokenBefore(token, { + const previousTokenOrComment = context.sourceCode.getTokenBefore(token, { includeComments: true, }); - const nextTokenOrComment = sourceCode.getTokenAfter(token, { + const nextTokenOrComment = context.sourceCode.getTokenAfter(token, { includeComments: true, }); diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index 08e44c52abe..428f31f3667 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; import { createRule, deepMerge } from '../util'; @@ -203,8 +202,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); - // use the base options as the defaults for the cases const baseOptions = options; const overrides = baseOptions.overrides ?? {}; @@ -242,7 +239,7 @@ export default createRule({ let messageId: MessageIds | null = null; let missingDelimiter = false; - const lastToken = sourceCode.getLastToken(member, { + const lastToken = context.sourceCode.getLastToken(member, { includeComments: false, }); @@ -250,11 +247,11 @@ export default createRule({ return; } - const commentsAfterLastToken = sourceCode + const commentsAfterLastToken = context.sourceCode .getCommentsAfter(lastToken) .pop(); - const sourceCodeLines = sourceCode.getLines(); + const sourceCodeLines = context.sourceCode.getLines(); const lastTokenLine = sourceCodeLines[lastToken.loc.start.line - 1]; const optsSemi = getOption('semi'); diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 34fed637e6c..949758785b2 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -1,6 +1,5 @@ import type { JSONSchema, TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import naturalCompare from 'natural-compare'; import { @@ -766,7 +765,7 @@ export default createRule({ // Find first member which isn't correctly sorted for (const member of members) { const rank = getRank(member, groupOrder, supportsModifiers); - const name = getMemberName(member, getSourceCode(context)); + const name = getMemberName(member, context.sourceCode); const rankLastMember = previousRanks[previousRanks.length - 1]; if (rank === -1) { @@ -815,7 +814,7 @@ export default createRule({ // Find first member which isn't correctly sorted members.forEach(member => { - const name = getMemberName(member, getSourceCode(context)); + const name = getMemberName(member, context.sourceCode); // Note: Not all members have names if (name) { @@ -885,7 +884,7 @@ export default createRule({ messageId: 'incorrectRequiredMembersOrder', loc: member.loc, data: { - member: getMemberName(member, getSourceCode(context)), + member: getMemberName(member, context.sourceCode), optionalOrRequired: optionalityOrder === 'required-first' ? 'required' : 'optional', }, diff --git a/packages/eslint-plugin/src/rules/method-signature-style.ts b/packages/eslint-plugin/src/rules/method-signature-style.ts index 6ab9c1c2ec8..0a17da9c091 100644 --- a/packages/eslint-plugin/src/rules/method-signature-style.ts +++ b/packages/eslint-plugin/src/rules/method-signature-style.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -38,12 +37,10 @@ export default createRule({ defaultOptions: ['property'], create(context, [mode]) { - const sourceCode = getSourceCode(context); - function getMethodKey( node: TSESTree.TSMethodSignature | TSESTree.TSPropertySignature, ): string { - let key = sourceCode.getText(node.key); + let key = context.sourceCode.getText(node.key); if (node.computed) { key = `[${key}]`; } @@ -62,24 +59,27 @@ export default createRule({ let params = '()'; if (node.params.length > 0) { const openingParen = nullThrows( - sourceCode.getTokenBefore(node.params[0], isOpeningParenToken), + context.sourceCode.getTokenBefore( + node.params[0], + isOpeningParenToken, + ), 'Missing opening paren before first parameter', ); const closingParen = nullThrows( - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( node.params[node.params.length - 1], isClosingParenToken, ), 'Missing closing paren after last parameter', ); - params = sourceCode.text.substring( + params = context.sourceCode.text.substring( openingParen.range[0], closingParen.range[1], ); } if (node.typeParameters != null) { - const typeParams = sourceCode.getText(node.typeParameters); + const typeParams = context.sourceCode.getText(node.typeParameters); params = `${typeParams}${params}`; } return params; @@ -92,11 +92,11 @@ export default createRule({ ? // if the method has no return type, it implicitly has an `any` return type // we just make it explicit here so we can do the fix 'any' - : sourceCode.getText(node.returnType.typeAnnotation); + : context.sourceCode.getText(node.returnType.typeAnnotation); } function getDelimiter(node: TSESTree.Node): string { - const lastToken = sourceCode.getLastToken(node); + const lastToken = context.sourceCode.getLastToken(node); if ( lastToken && (isSemicolonToken(lastToken) || isCommaToken(lastToken)) @@ -175,9 +175,10 @@ export default createRule({ `${key}: ${typeString}${delimiter}`, ); for (const node of duplicatedKeyMethodNodes) { - const lastToken = sourceCode.getLastToken(node); + const lastToken = context.sourceCode.getLastToken(node); if (lastToken) { - const nextToken = sourceCode.getTokenAfter(lastToken); + const nextToken = + context.sourceCode.getTokenAfter(lastToken); if (nextToken) { yield fixer.remove(node); yield fixer.replaceTextRange( diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 2ffbf7b665b..4af3fd2502c 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -1,7 +1,6 @@ import { PatternVisitor } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import type { ScriptTarget } from 'typescript'; import { @@ -159,7 +158,7 @@ export default createRule({ const unusedVariables = collectUnusedVariables(context); function isUnused( name: string, - initialScope: TSESLint.Scope.Scope | null = getScope(context), + initialScope: TSESLint.Scope.Scope | null, ): boolean { let variable: TSESLint.Scope.Variable | null = null; let scope: TSESLint.Scope.Scope | null = initialScope; @@ -275,7 +274,7 @@ export default createRule({ baseModifiers.add(Modifiers.const); } - if (isGlobal(getScope(context))) { + if (isGlobal(context.sourceCode.getScope(node))) { baseModifiers.add(Modifiers.global); } } @@ -287,11 +286,12 @@ export default createRule({ modifiers.add(Modifiers.destructured); } - if (isExported(parent, id.name, getScope(context))) { + const scope = context.sourceCode.getScope(id); + if (isExported(parent, id.name, scope)) { modifiers.add(Modifiers.exported); } - if (isUnused(id.name)) { + if (isUnused(id.name, scope)) { modifiers.add(Modifiers.unused); } @@ -323,7 +323,7 @@ export default createRule({ const modifiers = new Set(); // functions create their own nested scope - const scope = getScope(context).upper; + const scope = context.sourceCode.getScope(node).upper; if (isGlobal(scope)) { modifiers.add(Modifiers.global); @@ -374,7 +374,7 @@ export default createRule({ modifiers.add(Modifiers.destructured); } - if (isUnused(i.name)) { + if (isUnused(i.name, context.sourceCode.getScope(i))) { modifiers.add(Modifiers.unused); } @@ -577,7 +577,7 @@ export default createRule({ const modifiers = new Set(); // classes create their own nested scope - const scope = getScope(context).upper; + const scope = context.sourceCode.getScope(node).upper; if (node.abstract) { modifiers.add(Modifiers.abstract); @@ -603,7 +603,7 @@ export default createRule({ validator: validators.interface, handler: (node, validator): void => { const modifiers = new Set(); - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); if (isExported(node, node.id.name, scope)) { modifiers.add(Modifiers.exported); @@ -625,7 +625,7 @@ export default createRule({ validator: validators.typeAlias, handler: (node, validator): void => { const modifiers = new Set(); - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); if (isExported(node, node.id.name, scope)) { modifiers.add(Modifiers.exported); @@ -648,7 +648,7 @@ export default createRule({ handler: (node, validator): void => { const modifiers = new Set(); // enums create their own nested scope - const scope = getScope(context).upper; + const scope = context.sourceCode.getScope(node).upper; if (isExported(node, node.id.name, scope)) { modifiers.add(Modifiers.exported); @@ -670,7 +670,7 @@ export default createRule({ validator: validators.typeParameter, handler: (node: TSESTree.TSTypeParameter, validator): void => { const modifiers = new Set(); - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); if (isUnused(node.name.name, scope)) { modifiers.add(Modifiers.unused); diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 694fafe14d6..b164e5713e6 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isOptionalCallExpression } from '../util'; @@ -42,7 +41,7 @@ export default createRule({ if (node.arguments.length === 0) { return fixer.replaceText(node, '[]'); } - const fullText = getSourceCode(context).getText(node); + const fullText = context.sourceCode.getText(node); const preambleLength = node.callee.range[1] - node.range[0]; return fixer.replaceText( diff --git a/packages/eslint-plugin/src/rules/no-array-delete.ts b/packages/eslint-plugin/src/rules/no-array-delete.ts index 141332e0638..d9900a1df10 100644 --- a/packages/eslint-plugin/src/rules/no-array-delete.ts +++ b/packages/eslint-plugin/src/rules/no-array-delete.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type * as ts from 'typescript'; import { @@ -83,8 +82,7 @@ export default createRule<[], MessageId>({ let suggestion = `${target}.splice(${key}, 1)`; - const sourceCode = getSourceCode(context); - const comments = sourceCode.getCommentsInside(node); + const comments = context.sourceCode.getCommentsInside(node); if (comments.length > 0) { const indentationCount = node.loc.start.column; diff --git a/packages/eslint-plugin/src/rules/no-base-to-string.ts b/packages/eslint-plugin/src/rules/no-base-to-string.ts index 8cca081f412..131579e8457 100644 --- a/packages/eslint-plugin/src/rules/no-base-to-string.ts +++ b/packages/eslint-plugin/src/rules/no-base-to-string.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as ts from 'typescript'; import { createRule, getParserServices, getTypeName } from '../util'; @@ -72,7 +71,7 @@ export default createRule({ context.report({ data: { certainty, - name: getSourceCode(context).getText(node), + name: context.sourceCode.getText(node), }, messageId: 'baseToString', node, diff --git a/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts index 76e60100422..9caf777aaba 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -29,7 +28,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); return { 'BinaryExpression, AssignmentExpression'( node: TSESTree.AssignmentExpression | TSESTree.BinaryExpression, @@ -46,8 +44,8 @@ export default createRule({ node.operator === '=' ) { const isAssign = node.operator === '='; - const leftHandFinalToken = sourceCode.getLastToken(node.left); - const tokenAfterLeft = sourceCode.getTokenAfter(node.left); + const leftHandFinalToken = context.sourceCode.getLastToken(node.left); + const tokenAfterLeft = context.sourceCode.getTokenAfter(node.left); if ( leftHandFinalToken?.type === AST_TOKEN_TYPES.Punctuator && leftHandFinalToken.value === '!' && diff --git a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts index 3eae588d007..95764e92bb9 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -103,9 +102,8 @@ export default createRule({ return; } - const sourceCode = getSourceCode(context); const wrapVoidFix = (fixer: TSESLint.RuleFixer): TSESLint.RuleFix => { - const nodeText = sourceCode.getText(node); + const nodeText = context.sourceCode.getText(node); const newNodeText = `void ${nodeText}`; return fixer.replaceText(node, newNodeText); }; @@ -132,14 +130,14 @@ export default createRule({ return null; } const arrowBody = arrowFunction.body; - const arrowBodyText = sourceCode.getText(arrowBody); + const arrowBodyText = context.sourceCode.getText(arrowBody); const newArrowBodyText = `{ ${arrowBodyText}; }`; - if (isParenthesized(arrowBody, sourceCode)) { - const bodyOpeningParen = sourceCode.getTokenBefore( + if (isParenthesized(arrowBody, context.sourceCode)) { + const bodyOpeningParen = context.sourceCode.getTokenBefore( arrowBody, isOpeningParenToken, )!; - const bodyClosingParen = sourceCode.getTokenAfter( + const bodyClosingParen = context.sourceCode.getTokenAfter( arrowBody, isClosingParenToken, )!; @@ -177,9 +175,9 @@ export default createRule({ return null; } const returnValue = returnStmt.argument!; - const returnValueText = sourceCode.getText(returnValue); + const returnValueText = context.sourceCode.getText(returnValue); let newReturnStmtText = `${returnValueText};`; - if (isPreventingASI(returnValue, sourceCode)) { + if (isPreventingASI(returnValue)) { // put a semicolon at the beginning of the line newReturnStmtText = `;${newReturnStmtText}`; } @@ -194,9 +192,9 @@ export default createRule({ messageId: 'invalidVoidExprReturn', fix(fixer) { const returnValue = returnStmt.argument!; - const returnValueText = sourceCode.getText(returnValue); + const returnValueText = context.sourceCode.getText(returnValue); let newReturnStmtText = `${returnValueText}; return;`; - if (isPreventingASI(returnValue, sourceCode)) { + if (isPreventingASI(returnValue)) { // put a semicolon at the beginning of the line newReturnStmtText = `;${newReturnStmtText}`; } @@ -333,12 +331,9 @@ export default createRule({ * * This happens if the line begins with `(`, `[` or `` ` `` */ - function isPreventingASI( - node: TSESTree.Expression, - sourceCode: Readonly, - ): boolean { + function isPreventingASI(node: TSESTree.Expression): boolean { const startToken = nullThrows( - sourceCode.getFirstToken(node), + context.sourceCode.getFirstToken(node), NullThrowsReasons.MissingToken('first token', node.type), ); diff --git a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts index 09c734a7558..08dd0b35d3b 100644 --- a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts +++ b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts @@ -50,23 +50,9 @@ export default createRule({ return { ...rules, - // for ESLint <= v7 - ...(rules.MethodDefinition - ? { - MethodDefinition: wrapMemberDefinitionListener( - rules.MethodDefinition, - ), - } - : {}), - // for ESLint v8 - ...(rules['MethodDefinition, PropertyDefinition'] - ? { - 'MethodDefinition, PropertyDefinition': - wrapMemberDefinitionListener( - rules['MethodDefinition, PropertyDefinition'], - ), - } - : {}), + 'MethodDefinition, PropertyDefinition': wrapMemberDefinitionListener( + rules['MethodDefinition, PropertyDefinition'], + ), }; }, }); diff --git a/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts b/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts index 7c99a1d92b7..58bd5ad6db2 100644 --- a/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-duplicate-type-constituents.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { Type } from 'typescript'; import { createRule, getParserServices } from '../util'; @@ -153,18 +152,17 @@ export default createRule({ }, parentNode: TSESTree.TSIntersectionType | TSESTree.TSUnionType, ): void { - const sourceCode = getSourceCode(context); - const beforeTokens = sourceCode.getTokensBefore( + const beforeTokens = context.sourceCode.getTokensBefore( duplicateConstituent.duplicated, { filter: token => token.value === '|' || token.value === '&' }, ); const beforeUnionOrIntersectionToken = beforeTokens[beforeTokens.length - 1]; - const bracketBeforeTokens = sourceCode.getTokensBetween( + const bracketBeforeTokens = context.sourceCode.getTokensBetween( beforeUnionOrIntersectionToken, duplicateConstituent.duplicated, ); - const bracketAfterTokens = sourceCode.getTokensAfter( + const bracketAfterTokens = context.sourceCode.getTokensAfter( duplicateConstituent.duplicated, { count: bracketBeforeTokens.length }, ); @@ -181,7 +179,9 @@ export default createRule({ parentNode.type === AST_NODE_TYPES.TSIntersectionType ? 'Intersection' : 'Union', - previous: sourceCode.getText(duplicateConstituent.duplicatePrevious), + previous: context.sourceCode.getText( + duplicateConstituent.duplicatePrevious, + ), }, messageId: 'duplicate', node: duplicateConstituent.duplicated, diff --git a/packages/eslint-plugin/src/rules/no-dynamic-delete.ts b/packages/eslint-plugin/src/rules/no-dynamic-delete.ts index 5d99e32a149..35c9b65937a 100644 --- a/packages/eslint-plugin/src/rules/no-dynamic-delete.ts +++ b/packages/eslint-plugin/src/rules/no-dynamic-delete.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import { createRule } from '../util'; @@ -67,11 +66,9 @@ export default createRule({ } function getTokenRange(property: TSESTree.Expression): [number, number] { - const sourceCode = getSourceCode(context); - return [ - sourceCode.getTokenBefore(property)!.range[0], - sourceCode.getTokenAfter(property)!.range[1], + context.sourceCode.getTokenBefore(property)!.range[0], + context.sourceCode.getTokenAfter(property)!.range[1], ]; } }, diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 44f8eb97700..674b86d44bf 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -1,11 +1,6 @@ import { ScopeType } from '@typescript-eslint/scope-manager'; import type { TSESLint } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { - getFilename, - getScope, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { createRule, isDefinitionFile } from '../util'; @@ -51,9 +46,6 @@ export default createRule({ create(context, [{ allowSingleExtends }]) { return { TSInterfaceDeclaration(node): void { - const sourceCode = getSourceCode(context); - const filename = getFilename(context); - if (node.body.body.length !== 0) { // interface contains members --> Nothing to report return; @@ -71,16 +63,16 @@ export default createRule({ const fix = (fixer: TSESLint.RuleFixer): TSESLint.RuleFix => { let typeParam = ''; if (node.typeParameters) { - typeParam = sourceCode.getText(node.typeParameters); + typeParam = context.sourceCode.getText(node.typeParameters); } return fixer.replaceText( node, - `type ${sourceCode.getText( + `type ${context.sourceCode.getText( node.id, - )}${typeParam} = ${sourceCode.getText(extend[0])}`, + )}${typeParam} = ${context.sourceCode.getText(extend[0])}`, ); }; - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); const mergedWithClassDeclaration = scope.set .get(node.id.name) @@ -89,7 +81,7 @@ export default createRule({ ); const isInAmbientDeclaration = !!( - isDefinitionFile(filename) && + isDefinitionFile(context.filename) && scope.type === ScopeType.tsModule && scope.block.declare ); diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 8360df8e3ee..0ed0f4c6b4d 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -3,7 +3,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -34,7 +33,6 @@ export default createRule({ }, defaultOptions: ['all'], create(context) { - const sourceCode = getSourceCode(context); const rules = baseRule.create(context); function binaryExp( @@ -88,8 +86,11 @@ export default createRule({ if ( node.arguments.length === 1 && // is there any opening parenthesis in type arguments - sourceCode.getTokenAfter(node.callee, isOpeningParenToken) !== - sourceCode.getTokenBefore(node.arguments[0], isOpeningParenToken) + context.sourceCode.getTokenAfter(node.callee, isOpeningParenToken) !== + context.sourceCode.getTokenBefore( + node.arguments[0], + isOpeningParenToken, + ) ) { return rule({ ...node, @@ -202,8 +203,31 @@ export default createRule({ } return rules.ConditionalExpression(node); }, + ForInStatement(node): void { + if (isTypeAssertion(node.right)) { + // as of 7.20.0 there's no way to skip checking the right of the ForIn + // so just don't validate it at all + return; + } + + return rules.ForInStatement(node); + }, + ForOfStatement(node): void { + if (isTypeAssertion(node.right)) { + // makes the rule skip checking of the right + return rules.ForOfStatement({ + ...node, + type: AST_NODE_TYPES.ForOfStatement, + right: { + ...node.right, + type: AST_NODE_TYPES.SequenceExpression as any, + }, + }); + } + + return rules.ForOfStatement(node); + }, // DoWhileStatement - // ForIn and ForOf are guarded by eslint version ForStatement(node) { // make the rule skip the piece by removing it entirely if (node.init && isTypeAssertion(node.init)) { @@ -279,51 +303,6 @@ export default createRule({ } }, }; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (rules.ForInStatement && rules.ForOfStatement) { - overrides.ForInStatement = function (node): void { - if (isTypeAssertion(node.right)) { - // as of 7.20.0 there's no way to skip checking the right of the ForIn - // so just don't validate it at all - return; - } - - return rules.ForInStatement(node); - }; - overrides.ForOfStatement = function (node): void { - if (isTypeAssertion(node.right)) { - // makes the rule skip checking of the right - return rules.ForOfStatement({ - ...node, - type: AST_NODE_TYPES.ForOfStatement, - right: { - ...node.right, - type: AST_NODE_TYPES.SequenceExpression as any, - }, - }); - } - - return rules.ForOfStatement(node); - }; - } else { - overrides['ForInStatement, ForOfStatement'] = function ( - node: TSESTree.ForInStatement | TSESTree.ForOfStatement, - ): void { - if (isTypeAssertion(node.right)) { - // makes the rule skip checking of the right - return rules['ForInStatement, ForOfStatement']({ - ...node, - type: AST_NODE_TYPES.ForOfStatement as any, - right: { - ...node.right, - type: AST_NODE_TYPES.SequenceExpression as any, - }, - }); - } - - return rules['ForInStatement, ForOfStatement'](node); - }; - } return Object.assign({}, rules, overrides); }, }); diff --git a/packages/eslint-plugin/src/rules/no-extra-semi.ts b/packages/eslint-plugin/src/rules/no-extra-semi.ts index f52e623cb9f..4d68f2d6db4 100644 --- a/packages/eslint-plugin/src/rules/no-extra-semi.ts +++ b/packages/eslint-plugin/src/rules/no-extra-semi.ts @@ -34,16 +34,7 @@ export default createRule({ 'TSAbstractMethodDefinition, TSAbstractPropertyDefinition'( node: never, ): void { - if (rules.MethodDefinition) { - // for ESLint <= v7 - rules.MethodDefinition(node); - } else if (rules['MethodDefinition, PropertyDefinition']) { - // for ESLint >= v8 < v8.3.0 - rules['MethodDefinition, PropertyDefinition'](node); - } else { - // for ESLint >= v8.3.0 - rules['MethodDefinition, PropertyDefinition, StaticBlock']?.(node); - } + rules['MethodDefinition, PropertyDefinition, StaticBlock'](node); }, }; }, diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index 8c6d9bc7433..de2e0574929 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -122,10 +121,13 @@ export default createRule({ } } - function isReferenceToGlobalFunction(calleeName: string): boolean { - const ref = getScope(context).references.find( - ref => ref.identifier.name === calleeName, - ); + function isReferenceToGlobalFunction( + calleeName: string, + node: TSESTree.Node, + ): boolean { + const ref = context.sourceCode + .getScope(node) + .references.find(ref => ref.identifier.name === calleeName); // ensure it's the "global" version return !ref?.resolved || ref.resolved.defs.length === 0; @@ -165,7 +167,7 @@ export default createRule({ if ( EVAL_LIKE_METHODS.has(calleeName) && !isFunction(handler) && - isReferenceToGlobalFunction(calleeName) + isReferenceToGlobalFunction(calleeName, node) ) { context.report({ node: handler, messageId: 'noImpliedEvalError' }); } diff --git a/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts index ec451f854cb..1658d471bc7 100644 --- a/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts +++ b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -30,7 +29,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); return { 'ImportDeclaration[importKind!="type"]'( node: TSESTree.ImportDeclaration, @@ -57,7 +55,7 @@ export default createRule({ const fixes: TSESLint.RuleFix[] = []; for (const specifier of specifiers) { const qualifier = nullThrows( - sourceCode.getFirstToken(specifier, isTypeKeyword), + context.sourceCode.getFirstToken(specifier, isTypeKeyword), NullThrowsReasons.MissingToken( 'type keyword', 'import specifier', @@ -72,7 +70,7 @@ export default createRule({ } const importKeyword = nullThrows( - sourceCode.getFirstToken(node, isImportKeyword), + context.sourceCode.getFirstToken(node, isImportKeyword), NullThrowsReasons.MissingToken('import keyword', 'import'), ); fixes.push(fixer.insertTextAfter(importKeyword, ' type')); diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 122ff346a86..f332642a339 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/internal/prefer-ast-types-enum */ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -49,8 +48,6 @@ export default createRule({ }, ], create(context, [{ ignoreParameters, ignoreProperties }]) { - const sourceCode = getSourceCode(context); - function isFunctionCall( init: TSESTree.Expression, callName: string, @@ -226,7 +223,7 @@ export default createRule({ node.left.optional) || (node.type === AST_NODE_TYPES.PropertyDefinition && node.definite) ) { - yield fixer.remove(sourceCode.getTokenBefore(typeNode)!); + yield fixer.remove(context.sourceCode.getTokenBefore(typeNode)!); } yield fixer.remove(typeNode); }, diff --git a/packages/eslint-plugin/src/rules/no-invalid-this.ts b/packages/eslint-plugin/src/rules/no-invalid-this.ts index c1acdb24fe7..fc87428ece3 100644 --- a/packages/eslint-plugin/src/rules/no-invalid-this.ts +++ b/packages/eslint-plugin/src/rules/no-invalid-this.ts @@ -61,13 +61,9 @@ export default createRule({ param.type === AST_NODE_TYPES.Identifier && param.name === 'this', ), ); - // baseRule's work - rules.FunctionDeclaration?.(node); }, - 'FunctionDeclaration:exit'(node: TSESTree.FunctionDeclaration): void { + 'FunctionDeclaration:exit'(): void { thisIsValidStack.pop(); - // baseRule's work - rules['FunctionDeclaration:exit']?.(node); }, FunctionExpression(node: TSESTree.FunctionExpression): void { thisIsValidStack.push( @@ -76,13 +72,9 @@ export default createRule({ param.type === AST_NODE_TYPES.Identifier && param.name === 'this', ), ); - // baseRule's work - rules.FunctionExpression?.(node); }, - 'FunctionExpression:exit'(node: TSESTree.FunctionExpression): void { + 'FunctionExpression:exit'(): void { thisIsValidStack.pop(); - // baseRule's work - rules['FunctionExpression:exit']?.(node); }, ThisExpression(node: TSESTree.ThisExpression): void { const thisIsValidHere = thisIsValidStack[thisIsValidStack.length - 1]; diff --git a/packages/eslint-plugin/src/rules/no-invalid-void-type.ts b/packages/eslint-plugin/src/rules/no-invalid-void-type.ts index d552dfb43ad..3d92174c95a 100644 --- a/packages/eslint-plugin/src/rules/no-invalid-void-type.ts +++ b/packages/eslint-plugin/src/rules/no-invalid-void-type.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -102,8 +101,7 @@ export default createRule<[Options], MessageIds>({ // check whitelist if (Array.isArray(allowInGenericTypeArguments)) { - const sourceCode = getSourceCode(context); - const fullyQualifiedName = sourceCode + const fullyQualifiedName = context.sourceCode .getText(node.parent.parent.typeName) .replace(/ /gu, ''); diff --git a/packages/eslint-plugin/src/rules/no-loop-func.ts b/packages/eslint-plugin/src/rules/no-loop-func.ts index c78e266da2a..a34217453b0 100644 --- a/packages/eslint-plugin/src/rules/no-loop-func.ts +++ b/packages/eslint-plugin/src/rules/no-loop-func.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -48,7 +47,7 @@ export default createRule({ return; } - const references = getScope(context).through; + const references = context.sourceCode.getScope(node).through; const unsafeRefs = references .filter(r => !isSafe(loopNode, r)) .map(r => r.identifier.name); diff --git a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts index ed3747884ab..06938f9e4dc 100644 --- a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts +++ b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts @@ -5,9 +5,9 @@ import type { InferOptionsTypeFromRule, } from '../util'; import { createRule } from '../util'; -import { maybeGetESLintCoreRule } from '../util/getESLintCoreRule'; +import { getESLintCoreRule } from '../util/getESLintCoreRule'; -const baseRule = maybeGetESLintCoreRule('no-loss-of-precision'); +const baseRule = getESLintCoreRule('no-loss-of-precision'); type Options = InferOptionsTypeFromRule>; type MessageIds = InferMessageIdsTypeFromRule>; @@ -21,20 +21,13 @@ export default createRule({ recommended: 'recommended', extendsBaseRule: true, }, - hasSuggestions: baseRule?.meta.hasSuggestions, + hasSuggestions: baseRule.meta.hasSuggestions, schema: [], - messages: baseRule?.meta.messages ?? { noLossOfPrecision: '' }, + messages: baseRule.meta.messages, }, defaultOptions: [], create(context) { - /* istanbul ignore if */ if (baseRule == null) { - throw new Error( - '@typescript-eslint/no-loss-of-precision requires at least ESLint v7.1.0', - ); - } - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion - const rules = baseRule!.create(context); + const rules = baseRule.create(context); function isSeparatedNumeric(node: TSESTree.Literal): boolean { return typeof node.value === 'number' && node.raw.includes('_'); diff --git a/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts b/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts index f91e48fb3c9..e8fdde8d1f3 100644 --- a/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts +++ b/packages/eslint-plugin/src/rules/no-meaningless-void-operator.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { ESLintUtils } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -47,14 +46,13 @@ export default createRule({ create(context, [{ checkNever }]) { const services = ESLintUtils.getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); return { 'UnaryExpression[operator="void"]'(node: TSESTree.UnaryExpression): void { const fix = (fixer: TSESLint.RuleFixer): TSESLint.RuleFix => { return fixer.removeRange([ - sourceCode.getTokens(node)[0].range[0], - sourceCode.getTokens(node)[1].range[0], + context.sourceCode.getTokens(node)[0].range[0], + context.sourceCode.getTokens(node)[1].range[0], ]); }; diff --git a/packages/eslint-plugin/src/rules/no-mixed-enums.ts b/packages/eslint-plugin/src/rules/no-mixed-enums.ts index 2b79f31a67e..c9bd94036f0 100644 --- a/packages/eslint-plugin/src/rules/no-mixed-enums.ts +++ b/packages/eslint-plugin/src/rules/no-mixed-enums.ts @@ -2,7 +2,6 @@ import type { Scope } from '@typescript-eslint/scope-manager'; import { DefinitionType } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -46,7 +45,7 @@ export default createRule({ imports: [], previousSibling: undefined, }; - let scope: Scope | null = getScope(context); + let scope: Scope | null = context.sourceCode.getScope(node); for (const definition of scope.upper?.set.get(name)?.defs ?? []) { if ( diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 4ff6ecfbd6e..c6b9213259b 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getFilename } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isDefinitionFile } from '../util'; @@ -50,8 +49,6 @@ export default createRule({ }, ], create(context, [{ allowDeclarations, allowDefinitionFiles }]) { - const filename = getFilename(context); - function isDeclaration(node: TSESTree.Node): boolean { if (node.type === AST_NODE_TYPES.TSModuleDeclaration && node.declare) { return true; @@ -66,7 +63,7 @@ export default createRule({ ): void { if ( node.parent.type === AST_NODE_TYPES.TSModuleDeclaration || - (allowDefinitionFiles && isDefinitionFile(filename)) || + (allowDefinitionFiles && isDefinitionFile(context.filename)) || (allowDeclarations && isDeclaration(node)) ) { return; diff --git a/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts index ad56985f723..1369254b16a 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts @@ -2,7 +2,6 @@ import type { Definition } from '@typescript-eslint/scope-manager'; import { DefinitionType } from '@typescript-eslint/scope-manager'; import type { TSESLint } from '@typescript-eslint/utils'; import { ASTUtils, TSESTree } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, nullThrows, NullThrowsReasons } from '../util'; @@ -54,7 +53,7 @@ export default createRule({ node: TSESTree.TSNonNullExpression, ): void { if (node.expression.type === TSESTree.AST_NODE_TYPES.Identifier) { - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); const identifier = node.expression; const variable = ASTUtils.findVariable(scope, identifier.name); if (variable && !hasAssignmentBeforeNode(variable, node)) { @@ -62,8 +61,6 @@ export default createRule({ } } - const sourceCode = getSourceCode(context); - context.report({ node, messageId: 'noNonNullAssertedNullishCoalescing', @@ -85,7 +82,7 @@ export default createRule({ messageId: 'suggestRemovingNonNull', fix(fixer): TSESLint.RuleFix { const exclamationMark = nullThrows( - sourceCode.getLastToken( + context.sourceCode.getLastToken( node, ASTUtils.isNonNullAssertionPunctuator, ), diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index f80d0ee0091..62bd5f1ab89 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -1,6 +1,5 @@ import type { TSESLint } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isNonNullAssertionPunctuator } from '../util'; @@ -25,13 +24,12 @@ export default createRule<[], MessageIds>({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); return { TSNonNullExpression(node): void { const suggest: TSESLint.ReportSuggestionArray = []; // it always exists in non-null assertion - const nonNullOperator = sourceCode.getTokenAfter( + const nonNullOperator = context.sourceCode.getTokenAfter( node.expression, isNonNullAssertionPunctuator, )!; @@ -62,7 +60,8 @@ export default createRule<[], MessageIds>({ fix(fixer) { // x!.y?.z // ^ punctuator - const punctuator = sourceCode.getTokenAfter(nonNullOperator)!; + const punctuator = + context.sourceCode.getTokenAfter(nonNullOperator)!; return [ fixer.remove(nonNullOperator), fixer.insertTextBefore(punctuator, '?'), diff --git a/packages/eslint-plugin/src/rules/no-redeclare.ts b/packages/eslint-plugin/src/rules/no-redeclare.ts index 35d8531798a..b084d90650b 100644 --- a/packages/eslint-plugin/src/rules/no-redeclare.ts +++ b/packages/eslint-plugin/src/rules/no-redeclare.ts @@ -1,7 +1,6 @@ import { ScopeType } from '@typescript-eslint/scope-manager'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getNameLocationInGlobalDirectiveComment } from '../util'; @@ -50,8 +49,6 @@ export default createRule({ }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); - const CLASS_DECLARATION_MERGE_NODES = new Set([ AST_NODE_TYPES.TSInterfaceDeclaration, AST_NODE_TYPES.TSModuleDeclaration, @@ -92,7 +89,7 @@ export default createRule({ type: 'comment', node: comment, loc: getNameLocationInGlobalDirectiveComment( - sourceCode, + context.sourceCode, comment, variable.name, ), @@ -237,7 +234,7 @@ export default createRule({ * Find variables in the current scope. */ function checkForBlock(node: TSESTree.Node): void { - const scope = getScope(context); + const scope = context.sourceCode.getScope(node); /* * In ES5, some node type such as `BlockStatement` doesn't have that scope. @@ -249,8 +246,8 @@ export default createRule({ } return { - Program(): void { - const scope = getScope(context); + Program(node): void { + const scope = context.sourceCode.getScope(node); findVariablesInScope(scope); diff --git a/packages/eslint-plugin/src/rules/no-require-imports.ts b/packages/eslint-plugin/src/rules/no-require-imports.ts index c4f20e6c68f..9b83ac66aec 100644 --- a/packages/eslint-plugin/src/rules/no-require-imports.ts +++ b/packages/eslint-plugin/src/rules/no-require-imports.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import * as util from '../util'; @@ -54,7 +53,10 @@ export default util.createRule({ ) { return; } - const variable = ASTUtils.findVariable(getScope(context), 'require'); + const variable = ASTUtils.findVariable( + context.sourceCode.getScope(node), + 'require', + ); // ignore non-global require usage as it's something user-land custom instead // of the commonjs standard diff --git a/packages/eslint-plugin/src/rules/no-shadow.ts b/packages/eslint-plugin/src/rules/no-shadow.ts index 2904d7dbb1f..628982acae0 100644 --- a/packages/eslint-plugin/src/rules/no-shadow.ts +++ b/packages/eslint-plugin/src/rules/no-shadow.ts @@ -5,7 +5,6 @@ import type { import { DefinitionType, ScopeType } from '@typescript-eslint/scope-manager'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -646,8 +645,8 @@ export default createRule({ } return { - 'Program:exit'(): void { - const globalScope = getScope(context); + 'Program:exit'(node): void { + const globalScope = context.sourceCode.getScope(node); const stack = globalScope.childScopes.slice(); while (stack.length) { diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts b/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts index da027bef8c6..b472f75e5a0 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -80,7 +79,6 @@ export default createRule({ ], create(context, [options]) { const services = getParserServices(context); - const sourceCode = getSourceCode(context); function getBooleanComparison( node: TSESTree.BinaryExpression, @@ -232,7 +230,7 @@ export default createRule({ yield fixer.replaceText( mutatedNode, - sourceCode.getText(comparison.expression), + context.sourceCode.getText(comparison.expression), ); // if `isUnaryNegation === literalBooleanInComparison === !negated` is true - negate the expression diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 34ebfc018d6..2f331dc78a6 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -154,7 +153,7 @@ export default createRule({ ) { const services = getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); + const compilerOptions = services.program.getCompilerOptions(); const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled( compilerOptions, @@ -672,7 +671,7 @@ export default createRule({ } const questionDotOperator = nullThrows( - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( beforeOperator, token => token.type === AST_TOKEN_TYPES.Punctuator && token.value === '?.', diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts index 90ae6a50694..34f973667c5 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -28,7 +27,6 @@ export default createRule({ const services = getParserServices(context); const esTreeNodeToTSNodeMap = services.esTreeNodeToTSNodeMap; const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); function tryGetAliasedSymbol( symbol: ts.Symbol, @@ -93,7 +91,7 @@ export default createRule({ const fromScope = getSymbolInScope( tsQualifier, accessedSymbol.flags, - sourceCode.getText(name), + context.sourceCode.getText(name), ); return ( fromScope === undefined || symbolsAreEqual(accessedSymbol, fromScope) @@ -115,7 +113,7 @@ export default createRule({ node: qualifier, messageId: 'unnecessaryQualifier', data: { - name: sourceCode.getText(name), + name: context.sourceCode.getText(name), }, fix(fixer) { return fixer.removeRange([qualifier.range[0], name.range[0]]); diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index ea17c721404..4d79c84368e 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -56,7 +55,6 @@ export default createRule({ }, defaultOptions: [{}], create(context, [options]) { - const sourceCode = getSourceCode(context); const services = getParserServices(context); const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); @@ -235,7 +233,7 @@ export default createRule({ ): void { if ( options.typesToIgnore?.includes( - sourceCode.getText(node.typeAnnotation), + context.sourceCode.getText(node.typeAnnotation), ) || isConstAssertion(node.typeAnnotation) ) { @@ -263,13 +261,13 @@ export default createRule({ messageId: 'unnecessaryAssertion', fix(fixer) { if (node.type === AST_NODE_TYPES.TSTypeAssertion) { - const openingAngleBracket = sourceCode.getTokenBefore( + const openingAngleBracket = context.sourceCode.getTokenBefore( node.typeAnnotation, token => token.type === AST_TOKEN_TYPES.Punctuator && token.value === '<', )!; - const closingAngleBracket = sourceCode.getTokenAfter( + const closingAngleBracket = context.sourceCode.getTokenAfter( node.typeAnnotation, token => token.type === AST_TOKEN_TYPES.Punctuator && @@ -283,13 +281,13 @@ export default createRule({ ]); } // `as` is always present in TSAsExpression - const asToken = sourceCode.getTokenAfter( + const asToken = context.sourceCode.getTokenAfter( node.expression, token => token.type === AST_TOKEN_TYPES.Identifier && token.value === 'as', )!; - const tokenBeforeAs = sourceCode.getTokenBefore(asToken, { + const tokenBeforeAs = context.sourceCode.getTokenBefore(asToken, { includeComments: true, })!; // ( 3 + 5 ) as number diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts index 42097bc5f59..77ea5c874e9 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts @@ -1,9 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { - getFilename, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { extname } from 'path'; import * as ts from 'typescript'; @@ -60,9 +56,7 @@ export default createRule({ } const requiresGenericDeclarationDisambiguation = - checkRequiresGenericDeclarationDisambiguation(getFilename(context)); - - const source = getSourceCode(context); + checkRequiresGenericDeclarationDisambiguation(context.filename); const checkNode = ( node: TypeParameterWithConstraint, @@ -77,7 +71,7 @@ export default createRule({ return ( (node.parent as TSESTree.TSTypeParameterDeclaration).params.length === 1 && - source.getTokensAfter(node)[0].value !== ',' && + context.sourceCode.getTokensAfter(node)[0].value !== ',' && !node.default ); } diff --git a/packages/eslint-plugin/src/rules/no-unsafe-declaration-merging.ts b/packages/eslint-plugin/src/rules/no-unsafe-declaration-merging.ts index ee053563a3a..2d8a797b116 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-declaration-merging.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-declaration-merging.ts @@ -1,7 +1,6 @@ import type { Scope } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -50,7 +49,7 @@ export default createRule({ if (node.id) { // by default eslint returns the inner class scope for the ClassDeclaration node // but we want the outer scope within which merged variables will sit - const currentScope = getScope(context).upper; + const currentScope = context.sourceCode.getScope(node).upper; if (currentScope == null) { return; } @@ -64,7 +63,7 @@ export default createRule({ }, TSInterfaceDeclaration(node): void { checkUnsafeDeclaration( - getScope(context), + context.sourceCode.getScope(node), node.id, AST_NODE_TYPES.ClassDeclaration, ); diff --git a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts index 6575b321bd1..f98e59b4cd6 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import { @@ -45,7 +44,6 @@ export default createRule({ compilerOptions, 'noImplicitThis', ); - const sourceCode = getSourceCode(context); const stateCache = new Map(); @@ -70,7 +68,7 @@ export default createRule({ stateCache.set(node, state); if (state === State.Unsafe) { - const propertyName = sourceCode.getText(node.property); + const propertyName = context.sourceCode.getText(node.property); let messageId: 'unsafeMemberExpression' | 'unsafeThisMemberExpression' = 'unsafeMemberExpression'; @@ -123,7 +121,7 @@ export default createRule({ const type = services.getTypeAtLocation(node); if (isTypeAnyType(type)) { - const propertyName = sourceCode.getText(node); + const propertyName = context.sourceCode.getText(node); context.report({ node, messageId: 'unsafeComputedMemberAccess', diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index a0094bee811..d9117605c40 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -1,12 +1,6 @@ import { PatternVisitor } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; -import { - getDeclaredVariables, - getFilename, - getScope, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { collectUnusedVariables as _collectUnusedVariables, @@ -103,8 +97,6 @@ export default createRule({ }, defaultOptions: [{}], create(context, [firstOption]) { - const filename = getFilename(context); - const sourceCode = getSourceCode(context); const MODULE_DECL_CACHE = new Map(); const options = ((): TranslatedOptions => { @@ -200,7 +192,7 @@ export default createRule({ */ function isAfterLastUsedArg(variable: TSESLint.Scope.Variable): boolean { const def = variable.defs[0]; - const params = getDeclaredVariables(context, def.node); + const params = context.sourceCode.getDeclaredVariables(def.node); const posteriorParams = params.slice(params.indexOf(variable) + 1); // If any used parameters occur after this parameter, do not report. @@ -306,7 +298,7 @@ export default createRule({ [ambientDeclarationSelector(AST_NODE_TYPES.Program, true)]( node: DeclarationSelectorNode, ): void { - if (!isDefinitionFile(filename)) { + if (!isDefinitionFile(context.filename)) { return; } markDeclarationChildAsUsed(node); @@ -447,7 +439,7 @@ export default createRule({ context.report({ node: programNode, loc: getNameLocationInGlobalDirectiveComment( - sourceCode, + context.sourceCode, directiveComment, unusedVar.name, ), @@ -533,7 +525,7 @@ export default createRule({ break; } - let scope = getScope(context); + let scope = context.sourceCode.getScope(node); const shouldUseUpperScope = [ AST_NODE_TYPES.TSModuleDeclaration, AST_NODE_TYPES.TSDeclareFunction, diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index f4e7d335eec..c08a21b4bac 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -1,7 +1,6 @@ import { DefinitionType } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -378,8 +377,8 @@ export default createRule({ } return { - Program(): void { - findVariablesInScope(getScope(context)); + Program(node): void { + findVariablesInScope(context.sourceCode.getScope(node)); }, }; }, diff --git a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts index 462b40304e7..a21f1cfa622 100644 --- a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts +++ b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getFilename } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isDefinitionFile } from '../util'; @@ -44,7 +43,7 @@ export default createRule({ // In a definition file, export {} is necessary to make the module properly // encapsulated, even when there are other exports // https://github.com/typescript-eslint/typescript-eslint/issues/4975 - if (isDefinitionFile(getFilename(context))) { + if (isDefinitionFile(context.filename)) { return {}; } function checkNode( diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index 3605904e655..30838ed7b99 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -70,7 +69,10 @@ export default createRule({ AST_NODE_TYPES.VariableDeclarator, ].includes(parent.type) ) { - const variable = ASTUtils.findVariable(getScope(context), 'require'); + const variable = ASTUtils.findVariable( + context.sourceCode.getScope(node), + 'require', + ); if (!variable?.identifiers.length) { context.report({ diff --git a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts index 8a9fa392bec..e4b237cccc8 100644 --- a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts +++ b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -31,7 +30,6 @@ export default createRule({ create(context) { const services = getParserServices(context); - const sourceCode = getSourceCode(context); const getTypesIfNotLoose = (node: TSESTree.Node): ts.Type[] | undefined => { const type = services.getTypeAtLocation(node); @@ -120,7 +118,9 @@ export default createRule({ } if (sameTypeWithoutNullish(assertedTypes, originalTypes)) { - const expressionSourceCode = sourceCode.getText(node.expression); + const expressionSourceCode = context.sourceCode.getText( + node.expression, + ); const higherPrecedenceThanUnary = getOperatorPrecedence( diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts index 0f89ef5b98b..e84677f01a1 100644 --- a/packages/eslint-plugin/src/rules/object-curly-spacing.ts +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -36,7 +35,6 @@ export default createRule({ // eslint-disable-next-line no-restricted-syntax -- Use raw options for extended rules. const [firstOption, secondOption] = context.options; const spaced = firstOption === 'always'; - const sourceCode = getSourceCode(context); /** * Determines whether an option is set, relative to the spacing option. @@ -70,7 +68,7 @@ export default createRule({ node: TSESTree.TSMappedType | TSESTree.TSTypeLiteral, token: TSESTree.Token, ): void { - const nextToken = getSourceCode(context).getTokenAfter(token, { + const nextToken = context.sourceCode.getTokenAfter(token, { includeComments: true, })!; @@ -96,7 +94,7 @@ export default createRule({ node: TSESTree.TSMappedType | TSESTree.TSTypeLiteral, token: TSESTree.Token, ): void { - const previousToken = getSourceCode(context).getTokenBefore(token, { + const previousToken = context.sourceCode.getTokenBefore(token, { includeComments: true, })!; @@ -173,8 +171,8 @@ export default createRule({ last: TSESTree.Token, ): void { if (isTokenOnSameLine(first, second)) { - const firstSpaced = sourceCode.isSpaceBetween!(first, second); - const secondType = sourceCode.getNodeByRangeIndex( + const firstSpaced = context.sourceCode.isSpaceBetween(first, second); + const secondType = context.sourceCode.getNodeByRangeIndex( second.range[0], )!.type; @@ -206,7 +204,7 @@ export default createRule({ (options.objectsInObjectsException && isClosingBraceToken(penultimate)); const penultimateType = shouldCheckPenultimate - ? sourceCode.getNodeByRangeIndex(penultimate.range[0])!.type + ? context.sourceCode.getNodeByRangeIndex(penultimate.range[0])!.type : undefined; const closingCurlyBraceMustBeSpaced = @@ -221,7 +219,7 @@ export default createRule({ ? !options.spaced : options.spaced; - const lastSpaced = sourceCode.isSpaceBetween!(penultimate, last); + const lastSpaced = context.sourceCode.isSpaceBetween(penultimate, last); if (closingCurlyBraceMustBeSpaced && !lastSpaced) { reportRequiredEndingSpace(node, last); @@ -248,7 +246,10 @@ export default createRule({ ): TSESTree.Token | null { const lastProperty = node.members[node.members.length - 1]; - return sourceCode.getTokenAfter(lastProperty, isClosingBraceToken); + return context.sourceCode.getTokenAfter( + lastProperty, + isClosingBraceToken, + ); } //-------------------------------------------------------------------------- @@ -259,12 +260,12 @@ export default createRule({ return { ...rules, TSMappedType(node: TSESTree.TSMappedType): void { - const first = sourceCode.getFirstToken(node)!; - const last = sourceCode.getLastToken(node)!; - const second = sourceCode.getTokenAfter(first, { + const first = context.sourceCode.getFirstToken(node)!; + const last = context.sourceCode.getLastToken(node)!; + const second = context.sourceCode.getTokenAfter(first, { includeComments: true, })!; - const penultimate = sourceCode.getTokenBefore(last, { + const penultimate = context.sourceCode.getTokenBefore(last, { includeComments: true, })!; @@ -275,12 +276,12 @@ export default createRule({ return; } - const first = sourceCode.getFirstToken(node)!; + const first = context.sourceCode.getFirstToken(node)!; const last = getClosingBraceOfObject(node)!; - const second = sourceCode.getTokenAfter(first, { + const second = context.sourceCode.getTokenAfter(first, { includeComments: true, })!; - const penultimate = sourceCode.getTokenBefore(last, { + const penultimate = context.sourceCode.getTokenBefore(last, { includeComments: true, })!; diff --git a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts index 563bc8e99ec..315d3e80d74 100644 --- a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts +++ b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -407,8 +406,8 @@ function verifyForNever( const nextToken = paddingLines[0][1]; const start = prevToken.range[1]; const end = nextToken.range[0]; - const text = getSourceCode(context) - .text.slice(start, end) + const text = context.sourceCode.text + .slice(start, end) .replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines); return fixer.replaceTextRange([start, end], text); @@ -443,10 +442,9 @@ function verifyForAlways( node: nextNode, messageId: 'expectedBlankLine', fix(fixer) { - const sourceCode = getSourceCode(context); - let prevToken = getActualLastToken(prevNode, sourceCode)!; + let prevToken = getActualLastToken(prevNode, context.sourceCode)!; const nextToken = - sourceCode.getFirstTokenBetween(prevToken, nextNode, { + context.sourceCode.getFirstTokenBetween(prevToken, nextNode, { includeComments: true, /** @@ -645,7 +643,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); // eslint-disable-next-line no-restricted-syntax -- We need all raw options. const configureList = context.options; @@ -698,7 +695,7 @@ export default createRule({ return type.some(match.bind(null, innerStatementNode)); } - return StatementTypes[type].test(innerStatementNode, sourceCode); + return StatementTypes[type].test(innerStatementNode, context.sourceCode); } /** @@ -737,13 +734,19 @@ export default createRule({ nextNode: TSESTree.Node, ): [TSESTree.Token, TSESTree.Token][] { const pairs: [TSESTree.Token, TSESTree.Token][] = []; - let prevToken: TSESTree.Token = getActualLastToken(prevNode, sourceCode)!; + let prevToken: TSESTree.Token = getActualLastToken( + prevNode, + context.sourceCode, + )!; if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) { do { - const token: TSESTree.Token = sourceCode.getTokenAfter(prevToken, { - includeComments: true, - })!; + const token: TSESTree.Token = context.sourceCode.getTokenAfter( + prevToken, + { + includeComments: true, + }, + )!; if (token.loc.start.line - prevToken.loc.end.line >= 2) { pairs.push([prevToken, token]); diff --git a/packages/eslint-plugin/src/rules/parameter-properties.ts b/packages/eslint-plugin/src/rules/parameter-properties.ts index 17fee949b01..d72a2591c41 100644 --- a/packages/eslint-plugin/src/rules/parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/parameter-properties.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -150,8 +149,6 @@ export default createRule({ return created; } - const sourceCode = getSourceCode(context); - function typeAnnotationsMatch( classProperty: TSESTree.PropertyDefinition, constructorParameter: TSESTree.Identifier, @@ -166,8 +163,8 @@ export default createRule({ } return ( - sourceCode.getText(classProperty.typeAnnotation) === - sourceCode.getText(constructorParameter.typeAnnotation) + context.sourceCode.getText(classProperty.typeAnnotation) === + context.sourceCode.getText(constructorParameter.typeAnnotation) ); } diff --git a/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts b/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts index 112caf8ae3c..27572b4f8f7 100644 --- a/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts +++ b/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts @@ -1,5 +1,4 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -24,14 +23,12 @@ export default createRule<[], MessageIds>({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); - function TSEnumDeclaration(node: TSESTree.TSEnumDeclaration): void { const { members } = node; members.forEach((member, index) => { if (member.initializer == null) { - const name = sourceCode.getText(member); + const name = context.sourceCode.getText(member); context.report({ node: member, messageId: 'defineInitializer', diff --git a/packages/eslint-plugin/src/rules/prefer-find.ts b/packages/eslint-plugin/src/rules/prefer-find.ts index e94f384ecd3..babee93bab8 100644 --- a/packages/eslint-plugin/src/rules/prefer-find.ts +++ b/packages/eslint-plugin/src/rules/prefer-find.ts @@ -1,11 +1,6 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; -import type { - RuleFix, - Scope, - SourceCode, -} from '@typescript-eslint/utils/ts-eslint'; +import type { RuleFix, Scope } from '@typescript-eslint/utils/ts-eslint'; import * as tsutils from 'ts-api-utils'; import type { Type } from 'typescript'; @@ -37,7 +32,7 @@ export default createRule({ defaultOptions: [], create(context) { - const globalScope = getScope(context); + const globalScope = context.sourceCode.getScope(context.sourceCode.ast); const services = getParserServices(context); const checker = services.program.getTypeChecker(); @@ -191,12 +186,11 @@ export default createRule({ fixer: TSESLint.RuleFixer, arrayNode: TSESTree.Expression, wholeExpressionBeingFlagged: TSESTree.Expression, - sourceCode: SourceCode, ): RuleFix { const tokenToStartDeletingFrom = nullThrows( // The next `.` or `[` is what we're looking for. // think of (...).at(0) or (...)[0] or even (...)["at"](0). - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( arrayNode, token => token.value === '.' || token.value === '[', ), @@ -232,7 +226,6 @@ export default createRule({ { messageId: 'preferFindSuggestion', fix: (fixer): TSESLint.RuleFix[] => { - const sourceCode = getSourceCode(context); return [ generateFixToReplaceFilterWithFind( fixer, @@ -243,7 +236,6 @@ export default createRule({ fixer, object, node, - sourceCode, ), ]; }, @@ -272,7 +264,6 @@ export default createRule({ { messageId: 'preferFindSuggestion', fix: (fixer): TSESLint.RuleFix[] => { - const sourceCode = context.sourceCode; return [ generateFixToReplaceFilterWithFind( fixer, @@ -283,7 +274,6 @@ export default createRule({ fixer, object, node, - sourceCode, ), ]; }, diff --git a/packages/eslint-plugin/src/rules/prefer-for-of.ts b/packages/eslint-plugin/src/rules/prefer-for-of.ts index 54fbd4fefc1..0f6bba8d543 100644 --- a/packages/eslint-plugin/src/rules/prefer-for-of.ts +++ b/packages/eslint-plugin/src/rules/prefer-for-of.ts @@ -1,9 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { - getDeclaredVariables, - getSourceCode, -} from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -165,8 +161,7 @@ export default createRule({ indexVar: TSESLint.Scope.Variable, arrayExpression: TSESTree.Expression, ): boolean { - const sourceCode = getSourceCode(context); - const arrayText = sourceCode.getText(arrayExpression); + const arrayText = context.sourceCode.getText(arrayExpression); return indexVar.references.every(reference => { const id = reference.identifier; const node = id.parent; @@ -175,7 +170,7 @@ export default createRule({ (node.type === AST_NODE_TYPES.MemberExpression && node.object.type !== AST_NODE_TYPES.ThisExpression && node.property === id && - sourceCode.getText(node.object) === arrayText && + context.sourceCode.getText(node.object) === arrayText && !isAssignee(node)) ); }); @@ -207,7 +202,7 @@ export default createRule({ return; } - const [indexVar] = getDeclaredVariables(context, node.init); + const [indexVar] = context.sourceCode.getDeclaredVariables(node.init); if ( isIncrement(node.update, indexName) && isIndexOnlyUsedWithArray(node.body, indexVar, arrayExpression) diff --git a/packages/eslint-plugin/src/rules/prefer-function-type.ts b/packages/eslint-plugin/src/rules/prefer-function-type.ts index c1d4bc8ec9c..e85ae87df8e 100644 --- a/packages/eslint-plugin/src/rules/prefer-function-type.ts +++ b/packages/eslint-plugin/src/rules/prefer-function-type.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -29,8 +28,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); - /** * Checks if there the interface has exactly one supertype that isn't named 'Function' * @param node The node being checked @@ -106,10 +103,12 @@ export default createRule({ const fixes: TSESLint.RuleFix[] = []; const start = member.range[0]; const colonPos = member.returnType!.range[0] - start; - const text = sourceCode.getText().slice(start, member.range[1]); - const comments = sourceCode + const text = context.sourceCode + .getText() + .slice(start, member.range[1]); + const comments = context.sourceCode .getCommentsBefore(member) - .concat(sourceCode.getCommentsAfter(member)); + .concat(context.sourceCode.getCommentsAfter(member)); let suggestion = `${text.slice(0, colonPos)} =>${text.slice( colonPos + 1, )}`; @@ -123,7 +122,7 @@ export default createRule({ if (node.type === AST_NODE_TYPES.TSInterfaceDeclaration) { if (node.typeParameters !== undefined) { - suggestion = `type ${sourceCode + suggestion = `type ${context.sourceCode .getText() .slice( node.id.range[0], diff --git a/packages/eslint-plugin/src/rules/prefer-includes.ts b/packages/eslint-plugin/src/rules/prefer-includes.ts index 4a63edfa5b2..ffd58daf8be 100644 --- a/packages/eslint-plugin/src/rules/prefer-includes.ts +++ b/packages/eslint-plugin/src/rules/prefer-includes.ts @@ -2,7 +2,6 @@ import type { AST as RegExpAST } from '@eslint-community/regexpp'; import { parseRegExpLiteral } from '@eslint-community/regexpp'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope } from '@typescript-eslint/utils/eslint-utils'; import * as ts from 'typescript'; import { @@ -33,7 +32,7 @@ export default createRule({ }, create(context) { - const globalScope = getScope(context); + const globalScope = context.sourceCode.getScope(context.sourceCode.ast); const services = getParserServices(context); const checker = services.program.getTypeChecker(); diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index d18079492b2..576d896c972 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -1,5 +1,4 @@ import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -21,8 +20,6 @@ export default createRule({ }, defaultOptions: [], create(context) { - const sourceCode = getSourceCode(context); - return { TSModuleDeclaration(node): void { // Do nothing if the name is a string. @@ -30,7 +27,7 @@ export default createRule({ return; } // Get tokens of the declaration header. - const moduleType = sourceCode.getTokenBefore(node.id); + const moduleType = context.sourceCode.getTokenBefore(node.id); if ( moduleType && diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index 144aa08641b..9faa2d52a3d 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -126,7 +125,7 @@ export default createRule({ ) { const parserServices = getParserServices(context); const compilerOptions = parserServices.program.getCompilerOptions(); - const sourceCode = getSourceCode(context); + const checker = parserServices.program.getTypeChecker(); const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled( compilerOptions, @@ -289,10 +288,10 @@ export default createRule({ : [node.consequent, node.alternate]; return fixer.replaceText( node, - `${sourceCode.text.slice( + `${context.sourceCode.text.slice( left.range[0], left.range[1], - )} ?? ${sourceCode.text.slice( + )} ?? ${context.sourceCode.text.slice( right.range[0], right.range[1], )}`, @@ -345,7 +344,7 @@ export default createRule({ } const barBarOperator = nullThrows( - sourceCode.getTokenAfter( + context.sourceCode.getTokenAfter( node.left, token => token.type === AST_TOKEN_TYPES.Punctuator && diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts index cc5d3e91f53..ec1a811ac3c 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts @@ -461,7 +461,6 @@ export function analyzeChain( PreferOptionalChainMessageIds, [PreferOptionalChainOptions] >, - sourceCode: SourceCode, parserServices: ParserServicesWithTypeInformation, options: PreferOptionalChainOptions, operator: TSESTree.LogicalExpression['operator'], @@ -497,7 +496,13 @@ export function analyzeChain( start: subChain[0].node.loc.start, end: subChain[subChain.length - 1].node.loc.end, }, - ...getFixer(sourceCode, parserServices, operator, options, subChain), + ...getFixer( + context.sourceCode, + parserServices, + operator, + options, + subChain, + ), }); } diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts index edb502c4a45..24791c5841e 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { RuleFix } from '@typescript-eslint/utils/ts-eslint'; import * as ts from 'typescript'; @@ -103,7 +102,6 @@ export default createRule< }, ], create(context, [options]) { - const sourceCode = getSourceCode(context); const parserServices = getParserServices(context); const seenLogicals = new Set(); @@ -150,12 +148,12 @@ export default createRule< { messageId: 'optionalChainSuggest', fix: (fixer): RuleFix => { - const leftNodeText = sourceCode.getText(leftNode); + const leftNodeText = context.sourceCode.getText(leftNode); // Any node that is made of an operator with higher or equal precedence, const maybeWrappedLeftNode = isLeftSideLowerPrecedence() ? `(${leftNodeText})` : leftNodeText; - const propertyToBeOptionalText = sourceCode.getText( + const propertyToBeOptionalText = context.sourceCode.getText( parentNode.property, ); const maybeWrappedProperty = parentNode.computed @@ -193,7 +191,6 @@ export default createRule< if (operand.type === OperandValidity.Invalid) { analyzeChain( context, - sourceCode, parserServices, options, node.operator, @@ -209,7 +206,6 @@ export default createRule< if (currentChain.length > 0) { analyzeChain( context, - sourceCode, parserServices, options, node.operator, diff --git a/packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts b/packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts index 69494823e02..1b7de382d47 100644 --- a/packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts +++ b/packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getDeclaredVariables } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -133,9 +132,9 @@ export default createRule({ } // reject param is always present in variables declared by executor - const rejectVariable = getDeclaredVariables(context, executor).find( - variable => variable.identifiers.includes(rejectParamNode), - )!; + const rejectVariable = context.sourceCode + .getDeclaredVariables(executor) + .find(variable => variable.identifiers.includes(rejectParamNode))!; rejectVariable.references.forEach(ref => { if ( diff --git a/packages/eslint-plugin/src/rules/prefer-readonly.ts b/packages/eslint-plugin/src/rules/prefer-readonly.ts index faf8db39a55..c1748195b39 100644 --- a/packages/eslint-plugin/src/rules/prefer-readonly.ts +++ b/packages/eslint-plugin/src/rules/prefer-readonly.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -185,14 +184,13 @@ export default createRule({ }, 'ClassDeclaration, ClassExpression:exit'(): void { const finalizedClassScope = classScopeStack.pop()!; - const sourceCode = getSourceCode(context); for (const violatingNode of finalizedClassScope.finalizeUnmodifiedPrivateNonReadonlys()) { const { esNode, nameNode } = getEsNodesFromViolatingNode(violatingNode); context.report({ data: { - name: sourceCode.getText(nameNode), + name: context.sourceCode.getText(nameNode), }, fix: fixer => fixer.insertTextBefore(nameNode, 'readonly '), messageId: 'preferReadonly', diff --git a/packages/eslint-plugin/src/rules/prefer-reduce-type-parameter.ts b/packages/eslint-plugin/src/rules/prefer-reduce-type-parameter.ts index 4ea5d7f5979..9a196e7be0d 100644 --- a/packages/eslint-plugin/src/rules/prefer-reduce-type-parameter.ts +++ b/packages/eslint-plugin/src/rules/prefer-reduce-type-parameter.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -93,9 +92,7 @@ export default createRule({ fixes.push( fixer.insertTextAfter( callee, - `<${getSourceCode(context).getText( - secondArg.typeAnnotation, - )}>`, + `<${context.sourceCode.getText(secondArg.typeAnnotation)}>`, ), ); } diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 4669cc2a97c..1b8109f87a5 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/prefer-literal-enum-member */ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import type * as ts from 'typescript'; @@ -39,10 +38,9 @@ export default createRule({ }, create(context) { - const globalScope = getScope(context); + const globalScope = context.sourceCode.getScope(context.sourceCode.ast); const services = getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); /** * Check if a given node type is a string. @@ -129,7 +127,7 @@ export default createRule({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: callNode, innerNode: [objectNode], wrap: objectCode => `${regExp.toString()}.exec(${objectCode})`, @@ -147,7 +145,7 @@ export default createRule({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: callNode, innerNode: [objectNode, argumentNode], wrap: (objectCode, argumentCode) => @@ -160,7 +158,7 @@ export default createRule({ node: memberNode.property, messageId: 'regExpExecOverStringMatch', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: callNode, innerNode: [objectNode, argumentNode], wrap: (objectCode, argumentCode) => diff --git a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts index d63e58d88f9..7cf6976e3e6 100644 --- a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts +++ b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts @@ -2,7 +2,6 @@ import type { AST as RegExpAST } from '@eslint-community/regexpp'; import { RegExpParser } from '@eslint-community/regexpp'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getScope, getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -39,8 +38,8 @@ export default createRule({ }, create(context) { - const globalScope = getScope(context); - const sourceCode = getSourceCode(context); + const globalScope = context.sourceCode.getScope(context.sourceCode.ast); + const services = getParserServices(context); const checker = services.program.getTypeChecker(); @@ -108,8 +107,8 @@ export default createRule({ * @param node2 Another node to compare. */ function isSameTokens(node1: TSESTree.Node, node2: TSESTree.Node): boolean { - const tokens1 = sourceCode.getTokens(node1); - const tokens2 = sourceCode.getTokens(node2); + const tokens1 = context.sourceCode.getTokens(node1); + const tokens2 = context.sourceCode.getTokens(node2); if (tokens1.length !== tokens2.length) { return false; @@ -212,7 +211,7 @@ export default createRule({ function getPropertyRange( node: TSESTree.MemberExpression, ): [number, number] { - const dotOrOpenBracket = sourceCode.getTokenAfter( + const dotOrOpenBracket = context.sourceCode.getTokenAfter( node.object, isNotClosingParenToken, )!; diff --git a/packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts b/packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts index 55507cf1e48..7dc15dc44b7 100644 --- a/packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts +++ b/packages/eslint-plugin/src/rules/prefer-ts-expect-error.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { RuleFix, RuleFixer } from '@typescript-eslint/utils/ts-eslint'; import { createRule } from '../util'; @@ -26,7 +25,6 @@ export default createRule<[], MessageIds>({ create(context) { const tsIgnoreRegExpSingleLine = /^\s*\/?\s*@ts-ignore/; const tsIgnoreRegExpMultiLine = /^\s*(?:\/|\*)*\s*@ts-ignore/; - const sourceCode = getSourceCode(context); function isLineComment(comment: TSESTree.Comment): boolean { return comment.type === AST_TOKEN_TYPES.Line; @@ -51,7 +49,7 @@ export default createRule<[], MessageIds>({ return { Program(): void { - const comments = sourceCode.getAllComments(); + const comments = context.sourceCode.getAllComments(); comments.forEach(comment => { if (isValidTsIgnorePresent(comment)) { const lineCommentRuleFixer = (fixer: RuleFixer): RuleFix => diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 2c286cb4550..e9dfabc3ca8 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as ts from 'typescript'; import { @@ -99,7 +98,6 @@ export default createRule({ ]); const services = getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); function validateNode( node: @@ -145,14 +143,14 @@ export default createRule({ return context.report({ messageId: 'missingAsync', node, - loc: getFunctionHeadLoc(node, sourceCode), + loc: getFunctionHeadLoc(node, context.sourceCode), }); } context.report({ messageId: 'missingAsync', node, - loc: getFunctionHeadLoc(node, sourceCode), + loc: getFunctionHeadLoc(node, context.sourceCode), fix: fixer => { if ( node.parent.type === AST_NODE_TYPES.MethodDefinition || @@ -162,7 +160,7 @@ export default createRule({ const method = node.parent; // the token to put `async` before - let keyToken = sourceCode.getFirstToken(method)!; + let keyToken = context.sourceCode.getFirstToken(method)!; // if there are decorators then skip past them if ( @@ -171,7 +169,7 @@ export default createRule({ ) { const lastDecorator = method.decorators[method.decorators.length - 1]; - keyToken = sourceCode.getTokenAfter(lastDecorator)!; + keyToken = context.sourceCode.getTokenAfter(lastDecorator)!; } // if current token is a keyword like `static` or `public` then skip it @@ -179,12 +177,12 @@ export default createRule({ keyToken.type === AST_TOKEN_TYPES.Keyword && keyToken.range[0] < method.key.range[0] ) { - keyToken = sourceCode.getTokenAfter(keyToken)!; + keyToken = context.sourceCode.getTokenAfter(keyToken)!; } // check if there is a space between key and previous token - const insertSpace = !sourceCode.isSpaceBetween!( - sourceCode.getTokenBefore(keyToken)!, + const insertSpace = !context.sourceCode.isSpaceBetween( + context.sourceCode.getTokenBefore(keyToken)!, keyToken, ); diff --git a/packages/eslint-plugin/src/rules/require-await.ts b/packages/eslint-plugin/src/rules/require-await.ts index dd033c7cbe2..989f4e356a2 100644 --- a/packages/eslint-plugin/src/rules/require-await.ts +++ b/packages/eslint-plugin/src/rules/require-await.ts @@ -1,17 +1,13 @@ -import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; +import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import type * as ts from 'typescript'; import { createRule, + getFunctionHeadLoc, getFunctionNameWithKind, getParserServices, - isArrowToken, - isOpeningParenToken, - nullThrows, - NullThrowsReasons, upperCaseFirst, } from '../util'; @@ -47,7 +43,6 @@ export default createRule({ const services = getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); let scopeInfo: ScopeInfo | null = null; /** @@ -81,7 +76,7 @@ export default createRule({ ) { context.report({ node, - loc: getFunctionHeadLoc(node, sourceCode), + loc: getFunctionHeadLoc(node, context.sourceCode), messageId: 'missingAwait', data: { name: upperCaseFirst(getFunctionNameWithKind(node)), @@ -198,59 +193,6 @@ function isEmptyFunction(node: FunctionNode): boolean { ); } -// https://github.com/eslint/eslint/blob/03a69dbe86d5b5768a310105416ae726822e3c1c/lib/rules/utils/ast-utils.js#L382-L392 -/** - * Gets the `(` token of the given function node. - */ -function getOpeningParenOfParams( - node: FunctionNode, - sourceCode: TSESLint.SourceCode, -): TSESTree.Token { - return nullThrows( - node.id - ? sourceCode.getTokenAfter(node.id, isOpeningParenToken) - : sourceCode.getFirstToken(node, isOpeningParenToken), - NullThrowsReasons.MissingToken('(', node.type), - ); -} - -// https://github.com/eslint/eslint/blob/03a69dbe86d5b5768a310105416ae726822e3c1c/lib/rules/utils/ast-utils.js#L1220-L1242 -/** - * Gets the location of the given function node for reporting. - */ -function getFunctionHeadLoc( - node: FunctionNode, - sourceCode: TSESLint.SourceCode, -): TSESTree.SourceLocation { - const parent = nullThrows(node.parent, NullThrowsReasons.MissingParent); - let start = null; - let end = null; - - if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) { - const arrowToken = nullThrows( - sourceCode.getTokenBefore(node.body, isArrowToken), - NullThrowsReasons.MissingToken('=>', node.type), - ); - - start = arrowToken.loc.start; - end = arrowToken.loc.end; - } else if ( - parent.type === AST_NODE_TYPES.Property || - parent.type === AST_NODE_TYPES.MethodDefinition - ) { - start = parent.loc.start; - end = getOpeningParenOfParams(node, sourceCode).loc.start; - } else { - start = node.loc.start; - end = getOpeningParenOfParams(node, sourceCode).loc.start; - } - - return { - start, - end, - }; -} - function expandUnionOrIntersectionType(type: ts.Type): ts.Type[] { if (type.isUnionOrIntersection()) { return type.types.flatMap(expandUnionOrIntersectionType); diff --git a/packages/eslint-plugin/src/rules/return-await.ts b/packages/eslint-plugin/src/rules/return-await.ts index fa3c6d5479e..d86b0874f8f 100644 --- a/packages/eslint-plugin/src/rules/return-await.ts +++ b/packages/eslint-plugin/src/rules/return-await.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -55,7 +54,6 @@ export default createRule({ create(context, [option]) { const services = getParserServices(context); const checker = services.program.getTypeChecker(); - const sourceCode = getSourceCode(context); const scopeInfoStack: ScopeInfo[] = []; @@ -138,7 +136,7 @@ export default createRule({ return null; } - const awaitToken = sourceCode.getFirstToken(node, isAwaitKeyword); + const awaitToken = context.sourceCode.getFirstToken(node, isAwaitKeyword); // Should always be the case; but let's be safe. /* istanbul ignore if */ if (!awaitToken) { return null; @@ -147,7 +145,7 @@ export default createRule({ const startAt = awaitToken.range[0]; let endAt = awaitToken.range[1]; // Also remove any extraneous whitespace after `await`, if there is any. - const nextToken = sourceCode.getTokenAfter(awaitToken, { + const nextToken = context.sourceCode.getTokenAfter(awaitToken, { includeComments: true, }); if (nextToken) { diff --git a/packages/eslint-plugin/src/rules/sort-type-constituents.ts b/packages/eslint-plugin/src/rules/sort-type-constituents.ts index 856ed206772..909af8c59bf 100644 --- a/packages/eslint-plugin/src/rules/sort-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/sort-type-constituents.ts @@ -1,6 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getEnumNames, typeNodeRequiresParentheses } from '../util'; @@ -166,8 +165,6 @@ export default createRule({ }, ], create(context, [{ checkIntersections, checkUnions, groupOrder }]) { - const sourceCode = getSourceCode(context); - const collator = new Intl.Collator('en', { sensitivity: 'base', numeric: true, @@ -181,7 +178,7 @@ export default createRule({ return { group: group === -1 ? Number.MAX_SAFE_INTEGER : group, node: type, - text: sourceCode.getText(type), + text: context.sourceCode.getText(type), }; }); const expectedOrder = [...sourceOrder].sort((a, b) => { @@ -197,8 +194,8 @@ export default createRule({ const hasComments = node.types.some(type => { const count = - sourceCode.getCommentsBefore(type).length + - sourceCode.getCommentsAfter(type).length; + context.sourceCode.getCommentsBefore(type).length + + context.sourceCode.getCommentsAfter(type).length; return count > 0; }); diff --git a/packages/eslint-plugin/src/rules/space-before-blocks.ts b/packages/eslint-plugin/src/rules/space-before-blocks.ts index 5a668cc20f8..cb50e5b57eb 100644 --- a/packages/eslint-plugin/src/rules/space-before-blocks.ts +++ b/packages/eslint-plugin/src/rules/space-before-blocks.ts @@ -1,5 +1,4 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -37,7 +36,6 @@ export default createRule({ defaultOptions: ['always'], create(context, [config]) { const rules = baseRule.create(context); - const sourceCode = getSourceCode(context); let requireSpace = true; @@ -50,10 +48,9 @@ export default createRule({ function checkPrecedingSpace( node: TSESTree.Token | TSESTree.TSInterfaceBody, ): void { - const precedingToken = sourceCode.getTokenBefore(node); + const precedingToken = context.sourceCode.getTokenBefore(node); if (precedingToken && isTokenOnSameLine(precedingToken, node)) { - // eslint-disable-next-line deprecation/deprecation -- TODO - switch once our min ESLint version is 6.7.0 - const hasSpace = sourceCode.isSpaceBetweenTokens( + const hasSpace = context.sourceCode.isSpaceBetween( precedingToken, node as TSESTree.Token, ); @@ -82,7 +79,7 @@ export default createRule({ } function checkSpaceAfterEnum(node: TSESTree.TSEnumDeclaration): void { - const punctuator = sourceCode.getTokenAfter(node.id); + const punctuator = context.sourceCode.getTokenAfter(node.id); if (punctuator) { checkPrecedingSpace(punctuator); } diff --git a/packages/eslint-plugin/src/rules/space-before-function-paren.ts b/packages/eslint-plugin/src/rules/space-before-function-paren.ts index d3966db5655..1bde80f3f77 100644 --- a/packages/eslint-plugin/src/rules/space-before-function-paren.ts +++ b/packages/eslint-plugin/src/rules/space-before-function-paren.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isOpeningParenToken } from '../util'; @@ -64,7 +63,6 @@ export default createRule({ defaultOptions: ['always'], create(context, [firstOption]) { - const sourceCode = getSourceCode(context); const baseConfig = typeof firstOption === 'string' ? firstOption : 'always'; const overrideConfig = typeof firstOption === 'object' ? firstOption : {}; @@ -111,7 +109,9 @@ export default createRule({ // Always ignore non-async functions and arrow functions without parens, e.g. async foo => bar if ( node.async && - isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 })!) + isOpeningParenToken( + context.sourceCode.getFirstToken(node, { skip: 1 })!, + ) ) { return overrideConfig.asyncArrow ?? baseConfig; } @@ -147,15 +147,20 @@ export default createRule({ let leftToken: TSESTree.Token; let rightToken: TSESTree.Token; if (node.typeParameters) { - leftToken = sourceCode.getLastToken(node.typeParameters)!; - rightToken = sourceCode.getTokenAfter(leftToken)!; + leftToken = context.sourceCode.getLastToken(node.typeParameters)!; + rightToken = context.sourceCode.getTokenAfter(leftToken)!; } else { - rightToken = sourceCode.getFirstToken(node, isOpeningParenToken)!; - leftToken = sourceCode.getTokenBefore(rightToken)!; + rightToken = context.sourceCode.getFirstToken( + node, + isOpeningParenToken, + )!; + leftToken = context.sourceCode.getTokenBefore(rightToken)!; } - // eslint-disable-next-line deprecation/deprecation -- TODO - switch once our min ESLint version is 6.7.0 - const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken); + const hasSpacing = context.sourceCode.isSpaceBetween( + leftToken, + rightToken, + ); if (hasSpacing && functionConfig === 'never') { context.report({ diff --git a/packages/eslint-plugin/src/rules/space-infix-ops.ts b/packages/eslint-plugin/src/rules/space-infix-ops.ts index 561d6b27e2c..b9094ad29b6 100644 --- a/packages/eslint-plugin/src/rules/space-infix-ops.ts +++ b/packages/eslint-plugin/src/rules/space-infix-ops.ts @@ -1,5 +1,4 @@ import { AST_TOKEN_TYPES, TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { InferMessageIdsTypeFromRule, @@ -41,7 +40,6 @@ export default createRule({ ], create(context) { const rules = baseRule.create(context); - const sourceCode = getSourceCode(context); function report(operator: TSESTree.Token): void { context.report({ @@ -51,8 +49,8 @@ export default createRule({ operator: operator.value, }, fix(fixer) { - const previousToken = sourceCode.getTokenBefore(operator); - const afterToken = sourceCode.getTokenAfter(operator); + const previousToken = context.sourceCode.getTokenBefore(operator); + const afterToken = context.sourceCode.getTokenAfter(operator); let fixString = ''; if (operator.range[0] - previousToken!.range[1] === 0) { @@ -84,18 +82,18 @@ export default createRule({ return; } - const operator = sourceCode.getFirstTokenBetween( + const operator = context.sourceCode.getFirstTokenBetween( leftNode, rightNode, isSpaceChar, )!; - const prev = sourceCode.getTokenBefore(operator)!; - const next = sourceCode.getTokenAfter(operator)!; + const prev = context.sourceCode.getTokenBefore(operator)!; + const next = context.sourceCode.getTokenAfter(operator)!; if ( - !sourceCode.isSpaceBetween!(prev, operator) || - !sourceCode.isSpaceBetween!(operator, next) + !context.sourceCode.isSpaceBetween(prev, operator) || + !context.sourceCode.isSpaceBetween(operator, next) ) { report(operator); } @@ -118,7 +116,7 @@ export default createRule({ ): void { const leftNode = node.optional && !node.typeAnnotation - ? sourceCode.getTokenAfter(node.key) + ? context.sourceCode.getTokenAfter(node.key) : node.typeAnnotation ?? node.key; checkAndReportAssignmentSpace(leftNode, node.value); @@ -138,18 +136,18 @@ export default createRule({ type.type === TSESTree.AST_NODE_TYPES.TSFunctionType ? isNotOpeningParenToken : 0; - const operator = sourceCode.getTokenBefore( + const operator = context.sourceCode.getTokenBefore( type, skipFunctionParenthesis, ); if (operator != null && UNIONS.includes(operator.value)) { - const prev = sourceCode.getTokenBefore(operator); - const next = sourceCode.getTokenAfter(operator); + const prev = context.sourceCode.getTokenBefore(operator); + const next = context.sourceCode.getTokenAfter(operator); if ( - !sourceCode.isSpaceBetween!(prev!, operator) || - !sourceCode.isSpaceBetween!(operator, next!) + !context.sourceCode.isSpaceBetween(prev!, operator) || + !context.sourceCode.isSpaceBetween(operator, next!) ) { report(operator); } diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 7ead3c9367a..c5fea6021ad 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -3,7 +3,6 @@ import type { TSESTree, } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -161,7 +160,7 @@ export default createRule({ const services = getParserServices(context); const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); - const sourceCode = getSourceCode(context); + const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled( compilerOptions, 'strictNullChecks', @@ -317,7 +316,7 @@ export default createRule({ { messageId: 'conditionFixDefaultFalse', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? false`, }), @@ -325,7 +324,7 @@ export default createRule({ { messageId: 'conditionFixCompareFalse', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} === false`, @@ -342,7 +341,7 @@ export default createRule({ { messageId: 'conditionFixDefaultFalse', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? false`, }), @@ -350,7 +349,7 @@ export default createRule({ { messageId: 'conditionFixCompareTrue', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} === true`, }), @@ -382,7 +381,7 @@ export default createRule({ { messageId: 'conditionFixCompareStringLength', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code}.length === 0`, @@ -391,7 +390,7 @@ export default createRule({ { messageId: 'conditionFixCompareEmptyString', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} === ""`, @@ -400,7 +399,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `!Boolean(${code})`, @@ -417,7 +416,7 @@ export default createRule({ { messageId: 'conditionFixCompareStringLength', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code}.length > 0`, }), @@ -425,7 +424,7 @@ export default createRule({ { messageId: 'conditionFixCompareEmptyString', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} !== ""`, }), @@ -433,7 +432,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `Boolean(${code})`, }), @@ -457,7 +456,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} == null`, @@ -466,7 +465,7 @@ export default createRule({ { messageId: 'conditionFixDefaultEmptyString', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? ""`, }), @@ -474,7 +473,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `!Boolean(${code})`, @@ -491,7 +490,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} != null`, }), @@ -499,7 +498,7 @@ export default createRule({ { messageId: 'conditionFixDefaultEmptyString', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? ""`, }), @@ -507,7 +506,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `Boolean(${code})`, }), @@ -529,7 +528,7 @@ export default createRule({ node, messageId: 'conditionErrorNumber', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} === 0`, @@ -541,7 +540,7 @@ export default createRule({ node, messageId: 'conditionErrorNumber', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} > 0`, }), @@ -556,7 +555,7 @@ export default createRule({ { messageId: 'conditionFixCompareZero', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, // TODO: we have to compare to 0n if the type is bigint @@ -567,7 +566,7 @@ export default createRule({ // TODO: don't suggest this for bigint because it can't be NaN messageId: 'conditionFixCompareNaN', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `Number.isNaN(${code})`, @@ -576,7 +575,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `!Boolean(${code})`, @@ -593,7 +592,7 @@ export default createRule({ { messageId: 'conditionFixCompareZero', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} !== 0`, }), @@ -601,7 +600,7 @@ export default createRule({ { messageId: 'conditionFixCompareNaN', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `!Number.isNaN(${code})`, }), @@ -609,7 +608,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `Boolean(${code})`, }), @@ -633,7 +632,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} == null`, @@ -642,7 +641,7 @@ export default createRule({ { messageId: 'conditionFixDefaultZero', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? 0`, }), @@ -650,7 +649,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `!Boolean(${code})`, @@ -667,7 +666,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} != null`, }), @@ -675,7 +674,7 @@ export default createRule({ { messageId: 'conditionFixDefaultZero', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} ?? 0`, }), @@ -683,7 +682,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `Boolean(${code})`, }), @@ -714,7 +713,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} == null`, @@ -731,7 +730,7 @@ export default createRule({ { messageId: 'conditionFixCompareNullish', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} != null`, }), @@ -761,7 +760,7 @@ export default createRule({ node, messageId: 'conditionErrorNullableEnum', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node: node.parent, innerNode: node, wrap: code => `${code} == null`, @@ -772,7 +771,7 @@ export default createRule({ node, messageId: 'conditionErrorNullableEnum', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `${code} != null`, }), @@ -792,7 +791,7 @@ export default createRule({ { messageId: 'conditionFixCastBoolean', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `Boolean(${code})`, }), diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 3247982dc2a..34b5d90be1c 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -1,5 +1,4 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -86,7 +85,6 @@ export default createRule({ context, [{ allowDefaultCaseForExhaustiveSwitch, requireDefaultForNonUnion }], ) { - const sourceCode = getSourceCode(context); const services = getParserServices(context); const checker = services.program.getTypeChecker(); const compilerOptions = services.program.getCompilerOptions(); @@ -247,11 +245,11 @@ export default createRule({ } // There were no existing cases. - const openingBrace = sourceCode.getTokenAfter( + const openingBrace = context.sourceCode.getTokenAfter( node.discriminant, isOpeningBraceToken, )!; - const closingBrace = sourceCode.getTokenAfter( + const closingBrace = context.sourceCode.getTokenAfter( node.discriminant, isClosingBraceToken, )!; diff --git a/packages/eslint-plugin/src/rules/triple-slash-reference.ts b/packages/eslint-plugin/src/rules/triple-slash-reference.ts index fe377123ee2..a45662c33d4 100644 --- a/packages/eslint-plugin/src/rules/triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/triple-slash-reference.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule } from '../util'; @@ -56,7 +55,7 @@ export default createRule({ ], create(context, [{ lib, path, types }]) { let programNode: TSESTree.Node | undefined; - const sourceCode = getSourceCode(context); + const references: { comment: TSESTree.Comment; importName: string; @@ -97,7 +96,8 @@ export default createRule({ programNode = node; const referenceRegExp = /^\/\s* { if (comment.type !== AST_TOKEN_TYPES.Line) { diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index bfc31993a50..62dcd7495cb 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -1,5 +1,4 @@ import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, @@ -157,7 +156,6 @@ export default createRule({ ], create(context, [options]) { const punctuators = [':', '=>']; - const sourceCode = getSourceCode(context); const ruleSet = createRules(options); @@ -169,9 +167,10 @@ export default createRule({ typeAnnotation: TSESTree.TypeNode, ): void { const nextToken = typeAnnotation; - const punctuatorTokenEnd = sourceCode.getTokenBefore(nextToken)!; + const punctuatorTokenEnd = context.sourceCode.getTokenBefore(nextToken)!; let punctuatorTokenStart = punctuatorTokenEnd; - let previousToken = sourceCode.getTokenBefore(punctuatorTokenEnd)!; + let previousToken = + context.sourceCode.getTokenBefore(punctuatorTokenEnd)!; let type = punctuatorTokenEnd.value; if (!punctuators.includes(type)) { @@ -182,8 +181,7 @@ export default createRule({ if (type === ':' && previousToken.value === '?') { if ( - // eslint-disable-next-line deprecation/deprecation -- TODO - switch once our min ESLint version is 6.7.0 - sourceCode.isSpaceBetweenTokens(previousToken, punctuatorTokenStart) + context.sourceCode.isSpaceBetween(previousToken, punctuatorTokenStart) ) { context.report({ node: punctuatorTokenStart, @@ -204,13 +202,13 @@ export default createRule({ // shift the start to the ? type = '?:'; punctuatorTokenStart = previousToken; - previousToken = sourceCode.getTokenBefore(previousToken)!; + previousToken = context.sourceCode.getTokenBefore(previousToken)!; // handle the +/- modifiers for optional modification operators if (previousToken.value === '+' || previousToken.value === '-') { type = `${previousToken.value}?:`; punctuatorTokenStart = previousToken; - previousToken = sourceCode.getTokenBefore(previousToken)!; + previousToken = context.sourceCode.getTokenBefore(previousToken)!; } } diff --git a/packages/eslint-plugin/src/rules/unbound-method.ts b/packages/eslint-plugin/src/rules/unbound-method.ts index de08e970d49..97a17c62095 100644 --- a/packages/eslint-plugin/src/rules/unbound-method.ts +++ b/packages/eslint-plugin/src/rules/unbound-method.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getFilename } from '@typescript-eslint/utils/eslint-utils'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; @@ -131,9 +130,7 @@ export default createRule({ ], create(context, [{ ignoreStatic }]) { const services = getParserServices(context); - const currentSourceFile = services.program.getSourceFile( - getFilename(context), - ); + const currentSourceFile = services.program.getSourceFile(context.filename); function checkMethodAndReport( node: TSESTree.Node, diff --git a/packages/eslint-plugin/src/rules/unified-signatures.ts b/packages/eslint-plugin/src/rules/unified-signatures.ts index 9b5edbe0afb..08ea21c5828 100644 --- a/packages/eslint-plugin/src/rules/unified-signatures.ts +++ b/packages/eslint-plugin/src/rules/unified-signatures.ts @@ -1,6 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import type { Equal } from '../util'; import { arraysAreEqual, createRule } from '../util'; @@ -100,8 +99,6 @@ export default createRule({ }, ], create(context, [{ ignoreDifferentlyNamedParameters }]) { - const sourceCode = getSourceCode(context); - //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- @@ -135,8 +132,12 @@ export default createRule({ messageId: 'singleParameterDifference', data: { failureStringStart: failureStringStart(lineOfOtherOverload), - type1: sourceCode.getText(typeAnnotation0?.typeAnnotation), - type2: sourceCode.getText(typeAnnotation1?.typeAnnotation), + type1: context.sourceCode.getText( + typeAnnotation0?.typeAnnotation, + ), + type2: context.sourceCode.getText( + typeAnnotation1?.typeAnnotation, + ), }, node: p1, }); @@ -443,8 +444,8 @@ export default createRule({ a === b || (a !== undefined && b !== undefined && - sourceCode.getText(a.typeAnnotation) === - sourceCode.getText(b.typeAnnotation)) + context.sourceCode.getText(a.typeAnnotation) === + context.sourceCode.getText(b.typeAnnotation)) ); } diff --git a/packages/eslint-plugin/src/util/collectUnusedVariables.ts b/packages/eslint-plugin/src/util/collectUnusedVariables.ts index 0b0b592bf60..80b05c7c43d 100644 --- a/packages/eslint-plugin/src/util/collectUnusedVariables.ts +++ b/packages/eslint-plugin/src/util/collectUnusedVariables.ts @@ -10,7 +10,6 @@ import { ESLintUtils, TSESLint, } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; class UnusedVarsVisitor< TMessageIds extends string, @@ -30,7 +29,7 @@ class UnusedVarsVisitor< }); this.#scopeManager = ESLintUtils.nullThrows( - getSourceCode(context).scopeManager, + context.sourceCode.scopeManager, 'Missing required scope manager', ); } @@ -41,7 +40,7 @@ class UnusedVarsVisitor< >( context: TSESLint.RuleContext, ): ReadonlySet { - const program = getSourceCode(context).ast; + const program = context.sourceCode.ast; const cached = this.RESULTS_CACHE.get(program); if (cached) { return cached; diff --git a/packages/eslint-plugin/src/util/getESLintCoreRule.ts b/packages/eslint-plugin/src/util/getESLintCoreRule.ts index ef9f4c12503..c3349011de5 100644 --- a/packages/eslint-plugin/src/util/getESLintCoreRule.ts +++ b/packages/eslint-plugin/src/util/getESLintCoreRule.ts @@ -1,8 +1,5 @@ import { ESLintUtils } from '@typescript-eslint/utils'; -import { version } from 'eslint/package.json'; -import * as semver from 'semver'; - -const isESLintV8 = semver.major(version) >= 8; +import { builtinRules } from 'eslint/use-at-your-own-risk'; interface RuleMap { /* eslint-disable @typescript-eslint/consistent-type-imports -- more concise to use inline imports */ @@ -46,18 +43,11 @@ interface RuleMap { type RuleId = keyof RuleMap; -export const getESLintCoreRule: (ruleId: R) => RuleMap[R] = - isESLintV8 - ? (ruleId: R): RuleMap[R] => - ESLintUtils.nullThrows( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - require('eslint/use-at-your-own-risk').builtinRules.get( - ruleId, - ) as RuleMap[R], - `ESLint's core rule '${ruleId}' not found.`, - ) - : (ruleId: R): RuleMap[R] => - require(`eslint/lib/rules/${ruleId}`) as RuleMap[R]; +export const getESLintCoreRule = (ruleId: R): RuleMap[R] => + ESLintUtils.nullThrows( + builtinRules.get(ruleId), + `ESLint's core rule '${ruleId}' not found.`, + ); export function maybeGetESLintCoreRule( ruleId: R, diff --git a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts index 2b8cdf15bb2..4d4bb3b5ae1 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts @@ -256,9 +256,6 @@ export { type T, T }; type T = 1; export type { T, T }; `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'typeOverValue', @@ -276,9 +273,6 @@ export { type/* */T, type /* */T, T }; type T = 1; export type { /* */T, /* */T, T }; `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'typeOverValue', @@ -299,9 +293,6 @@ const x = 1; export type { T, T }; export { x }; `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'singleExportIsType', @@ -321,9 +312,6 @@ type T = 1; const x = 1; export { type T, x }; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ fixMixedExportsWithInlineTypeSpecifier: true }], errors: [ { @@ -342,9 +330,6 @@ export { type T, T }; type T = 1; export type { T, T }; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ fixMixedExportsWithInlineTypeSpecifier: true }], errors: [ { @@ -367,9 +352,6 @@ export { export type { Type1, Type2 as Foo, value1 as BScope } from './consistent-type-exports'; export { value2 as CScope } from './consistent-type-exports'; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ fixMixedExportsWithInlineTypeSpecifier: false }], errors: [ { @@ -396,9 +378,6 @@ export { value2 as CScope, } from './consistent-type-exports'; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ fixMixedExportsWithInlineTypeSpecifier: true }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts index a9956f09fc4..117a7a374d3 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts @@ -9,10 +9,6 @@ const ruleTester = new RuleTester({ ecmaVersion: 2020, sourceType: 'module', }, - // type-only imports were first added in TS3.8 - dependencyConstraints: { - typescript: '3.8', - }, }); const withMetaParserOptions = { @@ -131,9 +127,6 @@ ruleTester.run('consistent-type-imports', rule, { const a: typeof Type = Type; `, options: [{ prefer: 'no-type-imports' }], - dependencyConstraints: { - typescript: '4.5', - }, }, ` import { type A } from 'foo'; @@ -208,9 +201,6 @@ ruleTester.run('consistent-type-imports', rule, { const b = B; `, options: [{ prefer: 'no-type-imports', fixStyle: 'inline-type-imports' }], - dependencyConstraints: { - typescript: '4.5', - }, }, // exports ` @@ -1939,9 +1929,6 @@ import { A, B } from 'foo'; type T = A; const b = B; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ prefer: 'no-type-imports' }], errors: [ { @@ -1962,9 +1949,6 @@ import { B, type C } from 'foo'; type T = A | C; const b = B; `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ prefer: 'type-imports' }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index 6ebcb82e3aa..1ffe8d86b5f 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -30,9 +30,6 @@ interface Foo { } `, { - dependencyConstraints: { - typescript: '4.5', - }, code: ` // no accessibility === public interface Foo { @@ -1313,9 +1310,6 @@ class Foo { f = 1; } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['static-initialization', 'method', 'field'] }], }, { @@ -1326,9 +1320,6 @@ class Foo { static {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['method', 'field', 'static-initialization'] }], }, { @@ -1339,9 +1330,6 @@ class Foo { m() {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['field', 'static-initialization', 'method'] }], }, ` @@ -4675,9 +4663,6 @@ class Foo { f = 1; } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['method', 'field', 'static-initialization'] }], errors: [ { @@ -4708,9 +4693,6 @@ class Foo { static {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['static-initialization', 'method', 'field'] }], errors: [ { @@ -4732,9 +4714,6 @@ class Foo { m() {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['static-initialization', 'field', 'method'] }], errors: [ { @@ -4756,9 +4735,6 @@ class Foo { m() {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [{ default: ['field', 'static-initialization', 'method'] }], errors: [ { @@ -4782,9 +4758,6 @@ class Foo { md() {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [ { default: ['decorated-method', 'static-initialization', 'method'] }, ], diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts index 46531f75267..3b0df609377 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts @@ -500,9 +500,6 @@ class Foo { static {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [ { default: { diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts index 4b76427cfe8..b038e010f65 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts @@ -1695,9 +1695,6 @@ class Foo { static {} } `, - dependencyConstraints: { - typescript: '4.4', - }, options: [ { default: { diff --git a/packages/eslint-plugin/tests/rules/method-signature-style.test.ts b/packages/eslint-plugin/tests/rules/method-signature-style.test.ts index 91053830e86..5d352f99ba7 100644 --- a/packages/eslint-plugin/tests/rules/method-signature-style.test.ts +++ b/packages/eslint-plugin/tests/rules/method-signature-style.test.ts @@ -33,42 +33,22 @@ interface Test { 'f!': (/* b */ x: any /* c */) => void; } `, - { - code: ` + ` interface Test { get f(): number; } - `, - dependencyConstraints: { - typescript: '4.3', - }, - }, - { - code: ` + `, + ` interface Test { set f(value: number): void; } - `, - dependencyConstraints: { - typescript: '4.3', - }, - }, + `, 'type Test = { readonly f: (a: string) => number };', "type Test = { ['f']?: (a: boolean) => void };", 'type Test = { readonly f?: (a?: T) => T };', "type Test = { readonly ['f']?: (a: T, b: T) => T };", - { - code: 'type Test = { get f(): number };', - dependencyConstraints: { - typescript: '4.3', - }, - }, - { - code: 'type Test = { set f(value: number): void };', - dependencyConstraints: { - typescript: '4.3', - }, - }, + 'type Test = { get f(): number };', + 'type Test = { set f(value: number): void };', { options: ['method'], code: ` @@ -133,45 +113,27 @@ interface Test { type Test = { ['f']?(a: T, b: T): T }; `, }, - { - options: ['method'], - code: ` - interface Test { - get f(): number; - } - `, - dependencyConstraints: { - typescript: '4.3', - }, - }, - { - options: ['method'], - code: ` - interface Test { - set f(value: number): void; - } - `, - dependencyConstraints: { - typescript: '4.3', - }, - }, + ` + interface Test { + get f(): number; + } + `, + ` + interface Test { + set f(value: number): void; + } + `, { options: ['method'], code: ` type Test = { get f(): number }; `, - dependencyConstraints: { - typescript: '4.3', - }, }, { options: ['method'], code: ` type Test = { set f(value: number): void }; `, - dependencyConstraints: { - typescript: '4.3', - }, }, ], invalid: [ diff --git a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts index d24ad789e59..1f335765c67 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts @@ -79,9 +79,6 @@ class Foo extends Base { override foo() {} } `, - dependencyConstraints: { - typescript: '4.3', - }, options: [{ allow: ['overrideMethods'] }], }, ], @@ -194,9 +191,6 @@ class Foo extends Base { override foo() {} } `, - dependencyConstraints: { - typescript: '4.3', - }, errors: [ { messageId: 'unexpected', diff --git a/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts b/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts index 10a4c04b42f..ccf55f9eaf5 100644 --- a/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts +++ b/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts @@ -537,9 +537,6 @@ type Foo = { [K in keyof Other]: \`\${K & number}\`; }; `, - dependencyConstraints: { - typescript: '4.1', - }, options: [{ ignoreTypeIndexes: true }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts index 04ee15735c4..94d26e6f197 100644 --- a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts @@ -156,21 +156,11 @@ ruleTester.run('no-redundant-type-constituents', rule, { type B = string; type T = B & null; `, - { - code: 'type T = `${string}` & null;', - dependencyConstraints: { - typescript: '4.1', - }, - }, - { - code: ` - type B = \`\${string}\`; - type T = B & null; - `, - dependencyConstraints: { - typescript: '4.1', - }, - }, + 'type T = `${string}` & null;', + ` + type B = \`\${string}\`; + type T = B & null; + `, ], invalid: [ @@ -454,9 +444,6 @@ ruleTester.run('no-redundant-type-constituents', rule, { }, { code: 'type T = `a${number}c` | string;', - dependencyConstraints: { - typescript: '4.1', - }, errors: [ { column: 10, @@ -473,9 +460,6 @@ ruleTester.run('no-redundant-type-constituents', rule, { type B = \`a\${number}c\`; type T = B | string; `, - dependencyConstraints: { - typescript: '4.1', - }, errors: [ { column: 18, @@ -489,9 +473,6 @@ ruleTester.run('no-redundant-type-constituents', rule, { }, { code: 'type T = `${number}` | string;', - dependencyConstraints: { - typescript: '4.1', - }, errors: [ { column: 10, diff --git a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts index d368bbe61fd..2cbacdffb34 100644 --- a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts +++ b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts @@ -252,9 +252,6 @@ import { type foo } from './foo'; // 'foo' is already declared in the upper scope function doThing(foo: number) {} `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ ignoreTypeValueShadow: true }], }, { @@ -622,9 +619,6 @@ function doThing(foo: number) {} import { type foo } from './foo'; function doThing(foo: number) {} `, - dependencyConstraints: { - typescript: '4.5', - }, options: [{ ignoreTypeValueShadow: false }], errors: [ { @@ -752,9 +746,6 @@ declare module 'baz' { } } `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'noShadow', @@ -775,9 +766,6 @@ declare module 'bar' { export type Foo = string; } `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'noShadow', @@ -800,9 +788,6 @@ declare module 'bar' { } } `, - dependencyConstraints: { - typescript: '4.5', - }, errors: [ { messageId: 'noShadow', diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts index 12acba6dd3f..7222cb8b907 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -134,107 +134,62 @@ ruleTester.run('no-type-alias', rule, { }, { code: 'type Foo = `a-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` | `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` | `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions-and-intersections' }], }, { code: 'type Foo = `a-${number}` | `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions' }], }, { code: 'type Foo = `a-${number}` | `b-${number}` | `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` | `b-${number}` | `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions-and-intersections' }], }, { code: 'type Foo = `a-${number}` | `b-${number}` | `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions' }], }, { code: 'type Foo = `a-${number}` & `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` & `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions-and-intersections' }], }, { code: 'type Foo = `a-${number}` & `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-intersections' }], }, { code: 'type Foo = `a-${number}` & `b-${number}` & `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` & `b-${number}` & `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions-and-intersections' }], }, { code: 'type Foo = `a-${number}` & `b-${number}` & `c-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-intersections' }], }, { code: 'type Foo = `a-${number}` | (`b-${number}` & `c-${number}`);', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'always' }], }, { code: 'type Foo = `a-${number}` | (`b-${number}` & `c-${number}`);', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'in-unions-and-intersections' }], }, { @@ -3448,9 +3403,6 @@ type Foo = { }, { code: 'type Foo = `foo-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, errors: [ { messageId: 'noTypeAlias', @@ -3464,9 +3416,6 @@ type Foo = { }, { code: 'type Foo = `a-${number}` | `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'never' }], errors: [ { @@ -3491,9 +3440,6 @@ type Foo = { }, { code: 'type Foo = `a-${number}` & `b-${number}`;', - dependencyConstraints: { - typescript: '4.1', - }, options: [{ allowAliases: 'never' }], errors: [ { diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index b4f6356efef..3ae10b5b142 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -582,9 +582,6 @@ foo?.[key]?.trim(); tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: ` @@ -600,9 +597,6 @@ foo?.[key].trim(); tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: ` @@ -621,9 +615,6 @@ function Foo(outer: Outer, key: BrandedKey): number | undefined { tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: ` @@ -643,9 +634,6 @@ function Foo(outer: Outer, key: Foo): number | undefined { tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: ` @@ -661,9 +649,6 @@ foo?.[key]?.trim(); tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, ` let latencies: number[][] = []; @@ -830,9 +815,6 @@ function getElem(dict: Record, key: string) { tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.noUncheckedIndexedAccess.json', }, - dependencyConstraints: { - typescript: '4.1', - }, }, ` type Foo = { bar: () => number | undefined } | null; diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts index 162877446c6..2845cb0f3c4 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts @@ -129,17 +129,11 @@ class Foo extends Bar {} interface Bar {} class Foo implements Bar {} `, - { - code: ` + ` import { F } from './missing'; function bar() {} bar>(); - `, - dependencyConstraints: { - // TS 4.5 improved type resolution for unresolved generics - typescript: '4.5', - }, - }, + `, ` type A = T; type B = A; diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts index a7cd216a4f4..1ca02bd7add 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts @@ -3,7 +3,7 @@ // License : https://github.com/eslint/eslint/blob/0cb81a9b90dd6b92bac383022f886e501bd2cb31/LICENSE import { RuleTester } from '@typescript-eslint/rule-tester'; -import type { TSESLint } from '@typescript-eslint/utils'; +import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import type { MessageIds } from '../../../src/rules/no-unused-vars'; @@ -21,9 +21,8 @@ ruleTester.defineRule('use-every-a', context => { /** * Mark a variable as used */ - function useA(): void { - // eslint-disable-next-line deprecation/deprecation - context.markVariableAsUsed('a'); + function useA(node: TSESTree.Node): void { + context.sourceCode.markVariableAsUsed('a', node); } return { VariableDeclaration: useA, diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts index 5d39c2a2610..2bbdfd86aa0 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts @@ -405,8 +405,7 @@ export const map: { [name in Foo]: Bar } = { }; `, // 4.1 remapped mapped type - { - code: noFormat` + ` type Foo = 'a' | 'b' | 'c'; type Bar = number; @@ -415,11 +414,7 @@ export const map: { [name in Foo as string]: Bar } = { b: 2, c: 3, }; - `, - dependencyConstraints: { - typescript: '4.1', - }, - }, + `, ` import { Nullable } from 'nullable'; class A { @@ -758,17 +753,12 @@ export function foo() { } `, // https://github.com/typescript-eslint/typescript-eslint/issues/5152 - { - code: noFormat` + ` function foo(value: T): T { return { value }; } export type Foo = typeof foo; - `, - dependencyConstraints: { - typescript: '4.7', - }, - }, + `, // https://github.com/typescript-eslint/typescript-eslint/issues/2331 { code: ` @@ -945,20 +935,15 @@ export declare namespace Foo { } } `, - { - code: noFormat` + ` class Foo { - value: T; + value: T; } class Bar { - foo = Foo; + foo = Foo; } new Bar(); - `, - dependencyConstraints: { - typescript: '4.7', - }, - }, + `, { code: ` declare namespace A { @@ -980,9 +965,6 @@ type Color = 'red' | 'blue'; type Quantity = 'one' | 'two'; export type SeussFish = \`\${Quantity | Color} fish\`; `, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: noFormat` @@ -991,18 +973,12 @@ type HorizontalAlignment = "left" | "center" | "right"; export declare function setAlignment(value: \`\${VerticalAlignment}-\${HorizontalAlignment}\`): void; `, - dependencyConstraints: { - typescript: '4.1', - }, }, { code: noFormat` type EnthusiasticGreeting = \`\${Uppercase} - \${Lowercase} - \${Capitalize} - \${Uncapitalize}\`; export type HELLO = EnthusiasticGreeting<"heLLo">; `, - dependencyConstraints: { - typescript: '4.1', - }, }, // https://github.com/typescript-eslint/typescript-eslint/issues/2714 { @@ -1083,9 +1059,6 @@ export class Foo { } } `, - dependencyConstraints: { - typescript: '4.4', - }, }, ` interface Foo { diff --git a/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts b/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts index a5dd34cb94a..f7aa671cfbc 100644 --- a/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts +++ b/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts @@ -252,9 +252,6 @@ const ruleTesterWithNoUncheckedIndexAccess = new RuleTester({ project: './tsconfig.noUncheckedIndexedAccess.json', }, parser: '@typescript-eslint/parser', - dependencyConstraints: { - typescript: '4.1', - }, }); ruleTesterWithNoUncheckedIndexAccess.run( diff --git a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts index 48b700584ef..1701f9a4496 100644 --- a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts @@ -424,11 +424,6 @@ ruleTester.run('restrict-template-expressions', rule, { return \`arg = \${arg}\`; } `, - dependencyConstraints: { - // TS 4.5 improved type printing to print the type T as `T` - // before that it was printed as `any` - typescript: '4.5', - }, errors: [ { messageId: 'invalidType', diff --git a/packages/eslint-plugin/tests/schemas.test.ts b/packages/eslint-plugin/tests/schemas.test.ts index 5524203d181..b1670bc6b9f 100644 --- a/packages/eslint-plugin/tests/schemas.test.ts +++ b/packages/eslint-plugin/tests/schemas.test.ts @@ -3,8 +3,8 @@ import 'jest-specific-snapshot'; import fs from 'node:fs'; import path from 'node:path'; -import prettier from '@prettier/sync'; import { compile } from '@typescript-eslint/rule-schema-to-typescript-types'; +import prettier from 'prettier'; import rules from '../src/rules/index'; import { areOptionsValid } from './areOptionsValid'; @@ -16,9 +16,32 @@ try { // ignore failure as it means it already exists probably } -const prettierConfigJson = { - ...(prettier.resolveConfig(__filename) ?? {}), - filepath: path.join(__dirname, 'schema.json'), +const PRETTIER_CONFIG_PATH = path.resolve( + __dirname, + '..', + '..', + '..', + '.prettierrc.json', +); +const SCHEMA_FILEPATH = path.join(__dirname, 'schema.json'); +const TS_TYPE_FILEPATH = path.join(__dirname, 'schema.ts'); +const getPrettierConfig = async ( + filepath: string, +): Promise => { + const config = await prettier.resolveConfig(filepath, { + config: PRETTIER_CONFIG_PATH, + }); + if (config == null) { + throw new Error('Unable to resolve prettier config'); + } + return { + ...config, + filepath, + }; +}; +const PRETTIER_CONFIG = { + schema: getPrettierConfig(SCHEMA_FILEPATH), + tsType: getPrettierConfig(TS_TYPE_FILEPATH), }; const SKIPPED_RULES_FOR_TYPE_GENERATION = new Set(['indent']); @@ -33,8 +56,8 @@ describe('Rule schemas should be convertible to TS types for documentation purpo continue; } - (ruleName === ONLY ? it.only : it)(ruleName, () => { - const schemaString = prettier.format( + (ruleName === ONLY ? it.only : it)(ruleName, async () => { + const schemaString = await prettier.format( JSON.stringify( ruleDef.meta.schema, (k, v: unknown) => { @@ -60,9 +83,12 @@ describe('Rule schemas should be convertible to TS types for documentation purpo // changes per line, or adding a prop can restructure an object 2, ), - prettierConfigJson, + await PRETTIER_CONFIG.schema, + ); + const compilationResult = await compile( + ruleDef.meta.schema, + PRETTIER_CONFIG.tsType, ); - const compilationResult = compile(ruleDef.meta.schema); expect( [ diff --git a/packages/eslint-plugin/tests/util/getWrappedCode.test.ts b/packages/eslint-plugin/tests/util/getWrappedCode.test.ts index a3edc6db68e..69e337694b0 100644 --- a/packages/eslint-plugin/tests/util/getWrappedCode.test.ts +++ b/packages/eslint-plugin/tests/util/getWrappedCode.test.ts @@ -1,6 +1,5 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import * as ts from 'typescript'; import { @@ -37,7 +36,6 @@ const removeFunctionRule = createRule({ }, create(context) { - const sourceCode = getSourceCode(context); const parserServices = getParserServices(context, true); const report = (node: TSESTree.CallExpression): void => { @@ -61,7 +59,7 @@ const removeFunctionRule = createRule({ : ts.SyntaxKind.Unknown, ); - const text = sourceCode.getText(node.arguments[0]); + const text = context.sourceCode.getText(node.arguments[0]); return fixer.replaceText( node, getWrappedCode(text, nodePrecedence, parentPrecedence), diff --git a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts index b9a07bf8181..2e8cc730113 100644 --- a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts +++ b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts @@ -1,6 +1,5 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, getWrappingFixer } from '../../src/util'; import { getFixturesRootDir } from '../RuleTester'; @@ -30,14 +29,12 @@ const voidEverythingRule = createRule({ }, create(context) { - const sourceCode = getSourceCode(context); - const report = (node: TSESTree.Node): void => { context.report({ node, messageId: 'addVoid', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, wrap: code => `void ${code}`, }), @@ -307,14 +304,12 @@ const removeFunctionRule = createRule({ }, create(context) { - const sourceCode = getSourceCode(context); - const report = (node: TSESTree.CallExpression): void => { context.report({ node, messageId: 'removeFunction', fix: getWrappingFixer({ - sourceCode, + sourceCode: context.sourceCode, node, innerNode: [node.arguments[0]], wrap: code => code, diff --git a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts index 1f5568e3d6a..2e42192090c 100644 --- a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts +++ b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts @@ -1,6 +1,5 @@ import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { getSourceCode } from '@typescript-eslint/utils/eslint-utils'; import { createRule, isNodeEqual } from '../../src/util'; import { getFixturesRootDir } from '../RuleTester'; @@ -21,8 +20,6 @@ const rule = createRule({ }, create(context) { - const sourceCode = getSourceCode(context); - return { LogicalExpression: (node: TSESTree.LogicalExpression): void => { if (isNodeEqual(node.left, node.right)) { @@ -32,7 +29,10 @@ const rule = createRule({ fix(fixer: TSESLint.RuleFixer): TSESLint.RuleFix { return fixer.replaceText( node, - sourceCode.text.slice(node.left.range[0], node.left.range[1]), + context.sourceCode.text.slice( + node.left.range[0], + node.left.range[1], + ), ); }, }); diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 5d301e04f2b..68e8f106781 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -4,6 +4,52 @@ // export = rule; // } +declare module 'eslint/use-at-your-own-risk' { + export interface RuleMap { + /* eslint-disable @typescript-eslint/consistent-type-imports -- more concise to use inline imports */ + 'arrow-parens': typeof import('eslint/lib/rules/arrow-parens'); + 'block-spacing': typeof import('eslint/lib/rules/block-spacing'); + 'brace-style': typeof import('eslint/lib/rules/brace-style'); + 'comma-dangle': typeof import('eslint/lib/rules/comma-dangle'); + 'dot-notation': typeof import('eslint/lib/rules/dot-notation'); + indent: typeof import('eslint/lib/rules/indent'); + 'init-declarations': typeof import('eslint/lib/rules/init-declarations'); + 'key-spacing': typeof import('eslint/lib/rules/key-spacing'); + 'keyword-spacing': typeof import('eslint/lib/rules/keyword-spacing'); + 'lines-around-comment': typeof import('eslint/lib/rules/lines-around-comment'); + 'lines-between-class-members': typeof import('eslint/lib/rules/lines-between-class-members'); + 'max-params': typeof import('eslint/lib/rules/max-params'); + 'no-dupe-args': typeof import('eslint/lib/rules/no-dupe-args'); + 'no-dupe-class-members': typeof import('eslint/lib/rules/no-dupe-class-members'); + 'no-empty-function': typeof import('eslint/lib/rules/no-empty-function'); + 'no-extra-parens': typeof import('eslint/lib/rules/no-extra-parens'); + 'no-extra-semi': typeof import('eslint/lib/rules/no-extra-semi'); + 'no-implicit-globals': typeof import('eslint/lib/rules/no-implicit-globals'); + 'no-invalid-this': typeof import('eslint/lib/rules/no-invalid-this'); + 'no-loop-func': typeof import('eslint/lib/rules/no-loop-func'); + 'no-loss-of-precision': typeof import('eslint/lib/rules/no-loss-of-precision'); + 'no-magic-numbers': typeof import('eslint/lib/rules/no-magic-numbers'); + 'no-restricted-imports': typeof import('eslint/lib/rules/no-restricted-imports'); + 'no-undef': typeof import('eslint/lib/rules/no-undef'); + 'no-unused-expressions': typeof import('eslint/lib/rules/no-unused-expressions'); + 'no-useless-constructor': typeof import('eslint/lib/rules/no-useless-constructor'); + 'no-restricted-globals': typeof import('eslint/lib/rules/no-restricted-globals'); + 'object-curly-spacing': typeof import('eslint/lib/rules/object-curly-spacing'); + 'prefer-const': typeof import('eslint/lib/rules/prefer-const'); + 'prefer-destructuring': typeof import('eslint/lib/rules/prefer-destructuring'); + quotes: typeof import('eslint/lib/rules/quotes'); + semi: typeof import('eslint/lib/rules/semi'); + 'space-before-blocks': typeof import('eslint/lib/rules/space-before-blocks'); + 'space-infix-ops': typeof import('eslint/lib/rules/space-infix-ops'); + strict: typeof import('eslint/lib/rules/strict'); + /* eslint-enable @typescript-eslint/consistent-type-imports */ + } + + export const builtinRules: { + get(key: K): RuleMap[K] | undefined; + }; +} + declare module 'eslint/lib/rules/arrow-parens' { import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; @@ -300,12 +346,9 @@ declare module 'eslint/lib/rules/no-dupe-class-members' { Program(): void; ClassBody(): void; 'ClassBody:exit'(): void; - // for ESLint <= v7 - MethodDefinition?: (node: TSESTree.MethodDefinition) => void; - // for ESLint v8 - 'MethodDefinition, PropertyDefinition'?: ( + 'MethodDefinition, PropertyDefinition'( node: TSESTree.MethodDefinition | TSESTree.PropertyDefinition, - ) => void; + ): void; } >; export = rule; @@ -598,11 +641,6 @@ declare module 'eslint/lib/rules/no-extra-parens' { ClassExpression(node: TSESTree.ClassExpression): void; ConditionalExpression(node: TSESTree.ConditionalExpression): void; DoWhileStatement(node: TSESTree.DoWhileStatement): void; - // -- eslint < 7.19.0 - 'ForInStatement, ForOfStatement'( - node: TSESTree.ForInStatement | TSESTree.ForOfStatement, - ): void; - // -- eslint >= 7.19.0 ForInStatement(node: TSESTree.ForInStatement): void; ForOfStatement(node: TSESTree.ForOfStatement): void; ForStatement(node: TSESTree.ForStatement): void; @@ -730,19 +768,12 @@ declare module 'eslint/lib/rules/no-extra-semi' { { EmptyStatement(node: TSESTree.EmptyStatement): void; ClassBody(node: TSESTree.ClassBody): void; - // for ESLint <= v7 - MethodDefinition?: (node: TSESTree.MethodDefinition) => void; - // for ESLint >= v8 < v8.3.0 - 'MethodDefinition, PropertyDefinition'?: ( - node: TSESTree.MethodDefinition | TSESTree.PropertyDefinition, - ) => void; - // for ESLint >= v8.3.0 - 'MethodDefinition, PropertyDefinition, StaticBlock'?: ( + 'MethodDefinition, PropertyDefinition, StaticBlock'( node: | TSESTree.MethodDefinition | TSESTree.PropertyDefinition | TSESTree.StaticBlock, - ) => void; + ): void; } >; export = rule; @@ -834,17 +865,6 @@ declare module 'eslint/lib/rules/no-invalid-this' { }?, ], { - // for ESLint < v8.7.0 - - Program?: (node: TSESTree.Program) => void; - 'Program:exit'?: (node: TSESTree.Program) => void; - - FunctionDeclaration?: (node: TSESTree.FunctionDeclaration) => void; - 'FunctionDeclaration:exit'?: (node: TSESTree.FunctionDeclaration) => void; - - FunctionExpression?: (node: TSESTree.FunctionExpression) => void; - 'FunctionExpression:exit'?: (node: TSESTree.FunctionExpression) => void; - // Common ThisExpression(node: TSESTree.ThisExpression): void; } diff --git a/packages/integration-tests/fixtures/eslint-v7/.eslintrc.js b/packages/integration-tests/fixtures/eslint-v8/.eslintrc.js similarity index 100% rename from packages/integration-tests/fixtures/eslint-v7/.eslintrc.js rename to packages/integration-tests/fixtures/eslint-v8/.eslintrc.js diff --git a/packages/integration-tests/fixtures/eslint-v7/index.ts b/packages/integration-tests/fixtures/eslint-v8/index.ts similarity index 100% rename from packages/integration-tests/fixtures/eslint-v7/index.ts rename to packages/integration-tests/fixtures/eslint-v8/index.ts diff --git a/packages/integration-tests/fixtures/eslint-v7/package.json b/packages/integration-tests/fixtures/eslint-v8/package.json similarity index 57% rename from packages/integration-tests/fixtures/eslint-v7/package.json rename to packages/integration-tests/fixtures/eslint-v8/package.json index d939ab3f81c..0065741800d 100644 --- a/packages/integration-tests/fixtures/eslint-v7/package.json +++ b/packages/integration-tests/fixtures/eslint-v8/package.json @@ -1,5 +1,5 @@ { "devDependencies": { - "eslint": "7.0.0" + "eslint": "8.56.0" } } diff --git a/packages/integration-tests/fixtures/eslint-v7/tsconfig.json b/packages/integration-tests/fixtures/eslint-v8/tsconfig.json similarity index 100% rename from packages/integration-tests/fixtures/eslint-v7/tsconfig.json rename to packages/integration-tests/fixtures/eslint-v8/tsconfig.json diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index abf752dd55f..ae22b9f0f5d 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -9,6 +9,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "devDependencies": { + "jest": "29.7.0", "ncp": "*", "tmp": "*" } diff --git a/packages/integration-tests/tests/__snapshots__/eslint-v7.test.ts.snap b/packages/integration-tests/tests/__snapshots__/eslint-v8.test.ts.snap similarity index 92% rename from packages/integration-tests/tests/__snapshots__/eslint-v7.test.ts.snap rename to packages/integration-tests/tests/__snapshots__/eslint-v8.test.ts.snap index eb23a06011e..1a77699f990 100644 --- a/packages/integration-tests/tests/__snapshots__/eslint-v7.test.ts.snap +++ b/packages/integration-tests/tests/__snapshots__/eslint-v8.test.ts.snap @@ -1,9 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`eslint-v7 should lint successfully 1`] = ` +exports[`eslint-v8 should lint successfully 1`] = ` [ { "errorCount": 1, + "fatalErrorCount": 0, "filePath": "/index.ts", "fixableErrorCount": 0, "fixableWarningCount": 0, @@ -46,6 +47,7 @@ exports[`eslint-v7 should lint successfully 1`] = ` ], "source": "const noSemi: any = true; ", + "suppressedMessages": [], "usedDeprecatedRules": [], "warningCount": 0, }, diff --git a/packages/integration-tests/tests/eslint-v7.test.ts b/packages/integration-tests/tests/eslint-v8.test.ts similarity index 100% rename from packages/integration-tests/tests/eslint-v7.test.ts rename to packages/integration-tests/tests/eslint-v8.test.ts diff --git a/packages/parser/package.json b/packages/parser/package.json index 4bcdf33503c..29ef557e422 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -48,7 +48,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 6cde9616577..bbdfe9dff9e 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -17,7 +17,6 @@ }, "devDependencies": { "@nx/devkit": "*", - "@prettier/sync": "*", "cross-fetch": "*", "execa": "*", "prettier": "^3.0.3", diff --git a/packages/repo-tools/src/generate-lib.mts b/packages/repo-tools/src/generate-lib.mts index b732dfc62c1..bb169f8a138 100644 --- a/packages/repo-tools/src/generate-lib.mts +++ b/packages/repo-tools/src/generate-lib.mts @@ -1,7 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; -import prettier from '@prettier/sync'; import type { AnalyzeOptions, ScopeManager, @@ -13,6 +12,7 @@ import { AST_TOKEN_TYPES } from '@typescript-eslint/types'; import type { TSESTreeOptions } from '@typescript-eslint/typescript-estree'; import { parse } from '@typescript-eslint/typescript-estree'; import { ESLint } from '@typescript-eslint/utils/ts-eslint'; +import prettier from 'prettier'; import { rimraf } from 'rimraf'; import ts from 'typescript'; @@ -74,10 +74,10 @@ enum BASE_CONFIG_EXPORT_NAMES { TYPE_AND_VALUE = 'TYPE_VALUE', } -function formatCode(code: string[]): string { - return prettier.format(addAutoGeneratedComment(code), { +async function formatCode(code: string[]): Promise { + return await prettier.format(addAutoGeneratedComment(code), { parser: 'typescript', - ...PRETTIER_CONFIG, + ...(await PRETTIER_CONFIG), }); } @@ -140,7 +140,7 @@ async function main(): Promise { // the shared fs.writeFileSync( SHARED_CONFIG_MODULE, - formatCode([ + await formatCode([ `export const ${ BASE_CONFIG_EXPORT_NAMES.TYPE } = Object.freeze(${JSON.stringify({ @@ -236,7 +236,7 @@ async function main(): Promise { code.unshift(...imports, ''); } - const formattedCode = formatCode(code); + const formattedCode = await formatCode(code); const writePath = path.join(OUTPUT_FOLDER, `${libName}.ts`); fs.writeFileSync(writePath, formattedCode); filesWritten.push(writePath); @@ -269,7 +269,7 @@ async function main(): Promise { barrelCode.push('', 'export { lib };'); - const formattedBarrelCode = formatCode(barrelCode); + const formattedBarrelCode = await formatCode(barrelCode); fs.writeFileSync(BARREL_PATH, formattedBarrelCode); console.log('Wrote barrel file'); @@ -283,7 +283,7 @@ async function main(): Promise { '', 'export { Lib };', ]; - const formattedLibUnionCode = formatCode(libUnionCode); + const formattedLibUnionCode = await formatCode(libUnionCode); fs.writeFileSync(TYPES_FILE, formattedLibUnionCode); console.log('Wrote Lib union type file'); diff --git a/packages/rule-schema-to-typescript-types/package.json b/packages/rule-schema-to-typescript-types/package.json index d18618ace25..86630e6264f 100644 --- a/packages/rule-schema-to-typescript-types/package.json +++ b/packages/rule-schema-to-typescript-types/package.json @@ -33,7 +33,6 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@prettier/sync": "*", "@typescript-eslint/type-utils": "6.21.0", "@typescript-eslint/utils": "6.21.0", "natural-compare": "^1.4.0", diff --git a/packages/rule-schema-to-typescript-types/src/index.ts b/packages/rule-schema-to-typescript-types/src/index.ts index 90a553e2fd7..32da7e7efd2 100644 --- a/packages/rule-schema-to-typescript-types/src/index.ts +++ b/packages/rule-schema-to-typescript-types/src/index.ts @@ -1,21 +1,16 @@ -import prettier from '@prettier/sync'; import { TSUtils } from '@typescript-eslint/utils'; import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema'; -import path from 'path'; +import prettier from 'prettier'; import { generateType } from './generateType'; import { optimizeAST } from './optimizeAST'; import { printTypeAlias } from './printAST'; import type { AST } from './types'; -const prettierConfig = { - ...(prettier.resolveConfig(__filename) ?? {}), - filepath: path.join(__dirname, 'schema.ts'), -}; - -export function compile( +export async function compile( schemaIn: JSONSchema4 | readonly JSONSchema4[], -): string { + prettierConfig: Promise, +): Promise { const { schema, isArraySchema } = (() => { if (TSUtils.isArray(schemaIn)) { return { @@ -52,7 +47,7 @@ export function compile( const unformattedCode = [...refTypes, optionsType].join('\n\n'); try { - return prettier.format(unformattedCode, prettierConfig); + return await prettier.format(unformattedCode, await prettierConfig); } catch (e) { if (e instanceof Error) { e.message = e.message + `\n\nUnformatted Code:\n${unformattedCode}`; diff --git a/packages/rule-tester/package.json b/packages/rule-tester/package.json index 1d2f4119989..290f038ddd5 100644 --- a/packages/rule-tester/package.json +++ b/packages/rule-tester/package.json @@ -55,7 +55,7 @@ }, "peerDependencies": { "@eslint/eslintrc": ">=2", - "eslint": ">=8" + "eslint": "^8.56.0" }, "devDependencies": { "@types/lodash.merge": "4.6.9", diff --git a/packages/rule-tester/tests/eslint-base/eslint-base.test.js b/packages/rule-tester/tests/eslint-base/eslint-base.test.js index 03d5f1d8f8c..b1dabac0bb4 100644 --- a/packages/rule-tester/tests/eslint-base/eslint-base.test.js +++ b/packages/rule-tester/tests/eslint-base/eslint-base.test.js @@ -1508,9 +1508,6 @@ describe("RuleTester", () => { it("should throw an error if rule uses start and end properties on nodes, tokens or comments", () => { const usesStartEndRule = { create(context) { - - const sourceCode = context.getSourceCode(); - return { CallExpression(node) { noop(node.arguments[1].start); @@ -1519,16 +1516,16 @@ describe("RuleTester", () => { noop(node.end); }, "UnaryExpression[operator='-']"(node) { - noop(sourceCode.getFirstToken(node).start); + noop(context.sourceCode.getFirstToken(node).start); }, ConditionalExpression(node) { - noop(sourceCode.getFirstToken(node).end); + noop(context.sourceCode.getFirstToken(node).end); }, BlockStatement(node) { - noop(sourceCode.getCommentsInside(node)[0].start); + noop(context.sourceCode.getCommentsInside(node)[0].start); }, ObjectExpression(node) { - noop(sourceCode.getCommentsInside(node)[0].end); + noop(context.sourceCode.getCommentsInside(node)[0].end); }, Decorator(node) { noop(node.start); diff --git a/packages/rule-tester/tests/eslint-base/fixtures/no-var.js b/packages/rule-tester/tests/eslint-base/fixtures/no-var.js index 26f0382536d..58530de4e1d 100644 --- a/packages/rule-tester/tests/eslint-base/fixtures/no-var.js +++ b/packages/rule-tester/tests/eslint-base/fixtures/no-var.js @@ -8,8 +8,6 @@ module.exports = { schema: [] }, create(context) { - var sourceCode = context.getSourceCode(); - return { "VariableDeclaration": function(node) { if (node.kind === "var") { @@ -18,7 +16,7 @@ module.exports = { loc: sourceCode.getFirstToken(node).loc, message: "Bad var.", fix: function(fixer) { - return fixer.remove(sourceCode.getFirstToken(node)); + return fixer.remove(context.sourceCode.getFirstToken(node)); } }) } diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 2fc21ed3c56..097414cf834 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -48,7 +48,6 @@ "@typescript-eslint/visitor-keys": "6.21.0" }, "devDependencies": { - "@prettier/sync": "*", "@types/glob": "*", "@typescript-eslint/typescript-estree": "6.21.0", "glob": "*", diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index c8017c32436..63e21873f98 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -60,7 +60,7 @@ "typescript": "*" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { diff --git a/packages/typescript-eslint/package.json b/packages/typescript-eslint/package.json index 8599bdb135d..39431a7e3f5 100644 --- a/packages/typescript-eslint/package.json +++ b/packages/typescript-eslint/package.json @@ -51,7 +51,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "dependencies": { "@typescript-eslint/eslint-plugin": "6.21.0", diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 3eb898abc8f..13882d67c9c 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -3120,15 +3120,7 @@ export class Converter { // Tuple case SyntaxKind.TupleType: { - // In TS 4.0, the `elementTypes` property was changed to `elements`. - // To support both at compile time, we cast to access the newer version - // if the former does not exist. - const elementTypes = - 'elementTypes' in node - ? (node as any).elementTypes.map((el: ts.Node) => - this.convertChild(el), - ) - : node.elements.map(el => this.convertChild(el)); + const elementTypes = node.elements.map(el => this.convertChild(el)); return this.createNode(node, { type: AST_NODE_TYPES.TSTupleType, diff --git a/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts b/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts index 42249968343..50261e294bb 100644 --- a/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts +++ b/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts @@ -2,11 +2,11 @@ import semver from 'semver'; import * as ts from 'typescript'; import type { ParseSettings } from './index'; + /** - * This needs to be kept in sync with /docs/users/Versioning.mdx - * in the typescript-eslint monorepo + * This needs to be kept in sync with package.json in the typescript-eslint monorepo */ -const SUPPORTED_TYPESCRIPT_VERSIONS = '>=4.3.5 <5.4.0'; +const SUPPORTED_TYPESCRIPT_VERSIONS = '>=4.7.4 <5.4.0'; /* * The semver package will ignore prerelease ranges, and we don't want to explicitly document every one diff --git a/packages/typescript-estree/src/version-check.ts b/packages/typescript-estree/src/version-check.ts index 03b664401a9..15c6ad10f54 100644 --- a/packages/typescript-estree/src/version-check.ts +++ b/packages/typescript-estree/src/version-check.ts @@ -12,16 +12,14 @@ function semverCheck(version: string): boolean { } const versions = [ - '4.3', - '4.4', - '4.5', - '4.6', '4.7', '4.8', '4.9', '5.0', '5.1', '5.2', + '5.3', + '5.4', ] as const; type Versions = typeof versions extends ArrayLike ? U : never; diff --git a/packages/utils/package.json b/packages/utils/package.json index 266d07eef56..8b7db097ec1 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -74,7 +74,7 @@ "semver": "^7.5.4" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "devDependencies": { "@typescript-eslint/parser": "6.21.0", diff --git a/packages/utils/src/eslint-utils/context.ts b/packages/utils/src/eslint-utils/context.ts deleted file mode 100644 index 28ddb3cc154..00000000000 --- a/packages/utils/src/eslint-utils/context.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Wrappers around ESLint's deprecation of existing methods -// We'll be able to drop them once we no longer support ESLint <8.40.0. -/* eslint-disable @typescript-eslint/no-unnecessary-condition, deprecation/deprecation */ -import type { Scope, SourceCode } from '../ts-eslint'; -import type { RuleContext } from '../ts-eslint/Rule'; -import type { TSESTree } from '../ts-estree'; - -export function getAncestors( - context: Readonly>, -): TSESTree.Node[] { - // TODO: Use `SourceCode#getAncestors` (we'll be forced to soon) - return context.getAncestors(); -} - -export function getCwd( - context: Readonly>, -): string { - return context.cwd ?? context.getCwd(); -} - -export function getDeclaredVariables( - context: Readonly>, - node: TSESTree.Node, -): readonly Scope.Variable[] { - const sourceCode = getSourceCode(context); - return ( - sourceCode.getDeclaredVariables?.(node) ?? - context.getDeclaredVariables(node) - ); -} - -export function getFilename( - context: Readonly>, -): string { - return context.filename ?? context.getFilename(); -} - -export function getScope( - context: Readonly>, -): Scope.Scope { - // TODO: Use `SourceCode#getScope` (we'll be forced to soon) - return context.getScope(); -} - -export function getSourceCode( - context: Readonly>, -): Readonly { - return context.sourceCode ?? context.getSourceCode(); -} diff --git a/packages/utils/src/eslint-utils/getParserServices.ts b/packages/utils/src/eslint-utils/getParserServices.ts index 30f16a8613d..c834c230091 100644 --- a/packages/utils/src/eslint-utils/getParserServices.ts +++ b/packages/utils/src/eslint-utils/getParserServices.ts @@ -71,10 +71,8 @@ function getParserServices( // This check allows us to handle bad user setups whilst providing a nice user-facing // error message explaining the problem. if ( - // eslint-disable-next-line deprecation/deprecation -- TODO - support for ESLint v9 with backwards-compatible support for ESLint v8 - context.parserServices?.esTreeNodeToTSNodeMap == null || - // eslint-disable-next-line deprecation/deprecation, @typescript-eslint/no-unnecessary-condition -- TODO - support for ESLint v9 with backwards-compatible support for ESLint v8 - context.parserServices.tsNodeToESTreeNodeMap == null + context.sourceCode.parserServices?.esTreeNodeToTSNodeMap == null || + context.sourceCode.parserServices.tsNodeToESTreeNodeMap == null ) { throwError(context.parserPath); } @@ -82,15 +80,13 @@ function getParserServices( // if a rule requires full type information, then hard fail if it doesn't exist // this forces the user to supply parserOptions.project if ( - // eslint-disable-next-line deprecation/deprecation -- TODO - support for ESLint v9 with backwards-compatible support for ESLint v8 - context.parserServices.program == null && + context.sourceCode.parserServices.program == null && !allowWithoutFullTypeInformation ) { throwError(context.parserPath); } - // eslint-disable-next-line deprecation/deprecation -- TODO - support for ESLint v9 with backwards-compatible support for ESLint v8 - return context.parserServices; + return context.sourceCode.parserServices as ParserServices; } /* eslint-enable @typescript-eslint/unified-signatures */ diff --git a/packages/utils/src/eslint-utils/index.ts b/packages/utils/src/eslint-utils/index.ts index 29062e4e708..baf3e82bc65 100644 --- a/packages/utils/src/eslint-utils/index.ts +++ b/packages/utils/src/eslint-utils/index.ts @@ -1,5 +1,4 @@ export * from './applyDefault'; -export * from './context'; export * from './getParserServices'; export * from './InferTypesFromRule'; export * from './RuleCreator'; diff --git a/packages/utils/src/ts-eslint/CLIEngine.ts b/packages/utils/src/ts-eslint/CLIEngine.ts deleted file mode 100644 index 2e668b49bfc..00000000000 --- a/packages/utils/src/ts-eslint/CLIEngine.ts +++ /dev/null @@ -1,178 +0,0 @@ -/* eslint-disable @typescript-eslint/no-namespace */ -/* eslint-disable deprecation/deprecation -- "uses" deprecated API to define the deprecated API */ - -import { CLIEngine as ESLintCLIEngine } from 'eslint'; - -import type { Linter } from './Linter'; -import type { RuleMetaData, RuleModule } from './Rule'; - -declare class CLIEngineBase { - /** - * Creates a new instance of the core CLI engine. - * @param providedOptions The options for this instance. - */ - constructor(options: CLIEngine.Options); - - /** - * Add a plugin by passing its configuration - * @param name Name of the plugin. - * @param pluginObject Plugin configuration object. - */ - addPlugin(name: string, pluginObject: Linter.Plugin): void; - - /** - * Executes the current configuration on an array of file and directory names. - * @param patterns An array of file and directory names. - * @returns The results for all files that were linted. - */ - executeOnFiles(patterns: string[]): CLIEngine.LintReport; - - /** - * Executes the current configuration on text. - * @param text A string of JavaScript code to lint. - * @param filename An optional string representing the texts filename. - * @param warnIgnored Always warn when a file is ignored - * @returns The results for the linting. - */ - executeOnText( - text: string, - filename?: string, - warnIgnored?: boolean, - ): CLIEngine.LintReport; - - /** - * Returns a configuration object for the given file based on the CLI options. - * This is the same logic used by the ESLint CLI executable to determine configuration for each file it processes. - * @param filePath The path of the file to retrieve a config object for. - * @returns A configuration object for the file. - */ - getConfigForFile(filePath: string): Linter.Config; - - /** - * Returns the formatter representing the given format. - * @param format The name of the format to load or the path to a custom formatter. - * @returns The formatter function. - */ - getFormatter(format?: string): CLIEngine.Formatter; - - /** - * Checks if a given path is ignored by ESLint. - * @param filePath The path of the file to check. - * @returns Whether or not the given path is ignored. - */ - isPathIgnored(filePath: string): boolean; - - /** - * Resolves the patterns passed into `executeOnFiles()` into glob-based patterns for easier handling. - * @param patterns The file patterns passed on the command line. - * @returns The equivalent glob patterns. - */ - resolveFileGlobPatterns(patterns: string[]): string[]; - - getRules< - TMessageIds extends string = string, - TOptions extends readonly unknown[] = unknown[], - >(): Map>; - - //////////////////// - // static members // - //////////////////// - - /** - * Returns results that only contains errors. - * @param results The results to filter. - * @returns The filtered results. - */ - static getErrorResults( - results: CLIEngine.LintResult[], - ): CLIEngine.LintResult[]; - - /** - * Returns the formatter representing the given format or null if the `format` is not a string. - * @param format The name of the format to load or the path to a custom formatter. - * @returns The formatter function. - */ - static getFormatter(format?: string): CLIEngine.Formatter; - - /** - * Outputs fixes from the given results to files. - * @param report The report object created by CLIEngine. - */ - static outputFixes(report: CLIEngine.LintReport): void; - - static version: string; -} - -namespace CLIEngine { - export interface Options { - allowInlineConfig?: boolean; - baseConfig?: false | Record; - cache?: boolean; - cacheFile?: string; - cacheLocation?: string; - configFile?: string; - cwd?: string; - envs?: string[]; - errorOnUnmatchedPattern?: boolean; - extensions?: string[]; - fix?: boolean; - globals?: string[]; - ignore?: boolean; - ignorePath?: string; - ignorePattern?: string[] | string; - useEslintrc?: boolean; - parser?: string; - parserOptions?: Linter.ParserOptions; - plugins?: string[]; - resolvePluginsRelativeTo?: string; - rules?: Record; - rulePaths?: string[]; - reportUnusedDisableDirectives?: boolean; - } - - export interface LintResult { - filePath: string; - messages: Linter.LintMessage[]; - errorCount: number; - warningCount: number; - fixableErrorCount: number; - fixableWarningCount: number; - output?: string; - source?: string; - } - - export interface LintReport { - results: LintResult[]; - errorCount: number; - warningCount: number; - fixableErrorCount: number; - fixableWarningCount: number; - usedDeprecatedRules: DeprecatedRuleUse[]; - } - - export interface DeprecatedRuleUse { - ruleId: string; - replacedBy: string[]; - } - - export interface LintResultData { - rulesMeta: Record>; - } - - export type Formatter = ( - results: LintResult[], - data?: LintResultData, - ) => string; -} - -/** - * The underlying utility that runs the ESLint command line interface. This object will read the filesystem for - * configuration and file information but will not output any results. Instead, it allows you direct access to the - * important information so you can deal with the output yourself. - * @deprecated use the ESLint class instead - */ -const CLIEngine = ESLintCLIEngine - ? class CLIEngine extends (ESLintCLIEngine as typeof CLIEngineBase) {} - : undefined; - -export { CLIEngine }; diff --git a/packages/utils/src/ts-eslint/Config.ts b/packages/utils/src/ts-eslint/Config.ts index 1c040d2bfef..7d65599bc06 100644 --- a/packages/utils/src/ts-eslint/Config.ts +++ b/packages/utils/src/ts-eslint/Config.ts @@ -189,8 +189,6 @@ export namespace FlatConfig { * directives should be tracked and reported. For legacy compatibility, `true` * is equivalent to `"warn"` and `false` is equivalent to `"off"`. * @default "off" - * - * non-boolean values @since 8.56.0 */ reportUnusedDisableDirectives?: | SharedConfig.Severity diff --git a/packages/utils/src/ts-eslint/ESLint.ts b/packages/utils/src/ts-eslint/ESLint.ts index 104d8f83765..4eb31dd6e87 100644 --- a/packages/utils/src/ts-eslint/ESLint.ts +++ b/packages/utils/src/ts-eslint/ESLint.ts @@ -220,9 +220,8 @@ namespace ESLint { errorCount: number; /** * The number of fatal errors. - * @since 7.32.0 */ - fatalErrorCount?: number; + fatalErrorCount: number; /** * The absolute path to the file of this result. This is the string "" if the file path is unknown (when you * didn't pass the options.filePath option to the eslint.lintText() method). @@ -251,10 +250,8 @@ namespace ESLint { source?: string; /** * The array of SuppressedLintMessage objects. - * - * @since 8.8.0 */ - suppressedMessages?: SuppressedLintMessage[]; + suppressedMessages: SuppressedLintMessage[]; /** * The information about the deprecated rules that were used to check this file. */ @@ -297,7 +294,6 @@ namespace ESLint { endLine: number | undefined; /** * `true` if this is a fatal error unrelated to a rule, like a parsing error. - * @since 7.24.0 */ fatal?: boolean | undefined; /** @@ -384,24 +380,12 @@ namespace ESLint { } } -// We want to export this class always so it's easy for end users to consume. -// However on ESLint v6, this class will not exist, so we provide a fallback to make it clear -// The only users of this should be users scripting ESLint locally, so _they_ should have the correct version installed. -const _ESLint = (ESLintESLint ?? - function (): void { - throw new Error( - 'Attempted to construct an ESLint instance on less than ESLint v7.0.0', - ); - }) as typeof ESLintBase; - /** * The ESLint class is the primary class to use in Node.js applications. * This class depends on the Node.js fs module and the file system, so you cannot use it in browsers. * * If you want to lint code on browsers, use the Linter class instead. - * - * @since 7.0.0 */ -class ESLint extends _ESLint {} +class ESLint extends (ESLintESLint as typeof ESLintBase) {} export { ESLint }; diff --git a/packages/utils/src/ts-eslint/Rule.ts b/packages/utils/src/ts-eslint/Rule.ts index 5d23b07afb0..01cfd91a1e8 100644 --- a/packages/utils/src/ts-eslint/Rule.ts +++ b/packages/utils/src/ts-eslint/Rule.ts @@ -192,9 +192,8 @@ interface RuleContext< parserPath: string; /** * The language options configured for this run - * @since 8.4.0 */ - languageOptions?: FlatConfig.LanguageOptions; + languageOptions: FlatConfig.LanguageOptions; /** * The parser options configured for this run */ @@ -231,7 +230,6 @@ interface RuleContext< /** * Returns the current working directory passed to Linter. * It is a path to a directory that should be considered as the current working directory. - * @since 6.6.0 * @deprecated in favor of `RuleContext#cwd` */ getCwd(): string; @@ -239,7 +237,6 @@ interface RuleContext< /** * The current working directory passed to Linter. * It is a path to a directory that should be considered as the current working directory. - * @since 8.40.0 */ cwd: string; @@ -252,22 +249,19 @@ interface RuleContext< /** * The filename associated with the source. - * @since 8.40.0 */ filename: string; /** * Returns the full path of the file on disk without any code block information (unlike `getFilename()`). - * @since 7.28.0 * @deprecated in favor of `RuleContext#physicalFilename` */ - getPhysicalFilename?(): string; + getPhysicalFilename(): string; /** * The full path of the file on disk without any code block information (unlike `filename`). - * @since 8.40.0 */ - physicalFilename?: string; + physicalFilename: string; /** * Returns the scope of the currently-traversed node. @@ -288,7 +282,6 @@ interface RuleContext< /** * A SourceCode object that you can use to work with the source that * was passed to ESLint. - * @since 8.40.0 */ sourceCode: Readonly; diff --git a/packages/utils/src/ts-eslint/RuleTester.ts b/packages/utils/src/ts-eslint/RuleTester.ts index 51b54fb7b5f..9e3e0166b0e 100644 --- a/packages/utils/src/ts-eslint/RuleTester.ts +++ b/packages/utils/src/ts-eslint/RuleTester.ts @@ -14,7 +14,6 @@ import type { interface ValidTestCase> { /** * Name for the test case. - * @since 8.1.0 */ readonly name?: string; /** @@ -51,7 +50,6 @@ interface ValidTestCase> { readonly settings?: Readonly; /** * Run this case exclusively for debugging in supported test frameworks. - * @since 7.29.0 */ readonly only?: boolean; } diff --git a/packages/utils/src/ts-eslint/SourceCode.ts b/packages/utils/src/ts-eslint/SourceCode.ts index 50ffd9000a7..3216efb26e6 100644 --- a/packages/utils/src/ts-eslint/SourceCode.ts +++ b/packages/utils/src/ts-eslint/SourceCode.ts @@ -278,12 +278,11 @@ declare class SourceCodeBase extends TokenStore { * Determines if two nodes or tokens have at least one whitespace character * between them. Order does not matter. Returns false if the given nodes or * tokens overlap. - * @since 6.7.0 * @param first The first node or token to check between. * @param second The second node or token to check between. * @returns True if there is a whitespace character between any of the tokens found between the two given nodes or tokens. */ - isSpaceBetween?( + isSpaceBetween( first: TSESTree.Node | TSESTree.Token, second: TSESTree.Node | TSESTree.Token, ): boolean; @@ -303,28 +302,24 @@ declare class SourceCodeBase extends TokenStore { /** * Returns the scope of the given node. * This information can be used track references to variables. - * @since 8.37.0 */ - getScope?(node: TSESTree.Node): Scope.Scope; + getScope(node: TSESTree.Node): Scope.Scope; /** * Returns an array of the ancestors of the given node, starting at * the root of the AST and continuing through the direct parent of the current node. * This array does not include the currently-traversed node itself. - * @since 8.38.0 */ - getAncestors?(node: TSESTree.Node): TSESTree.Node[]; + getAncestors(node: TSESTree.Node): TSESTree.Node[]; /** * Returns a list of variables declared by the given node. * This information can be used to track references to variables. - * @since 8.38.0 */ - getDeclaredVariables?(node: TSESTree.Node): readonly Scope.Variable[]; + getDeclaredVariables(node: TSESTree.Node): readonly Scope.Variable[]; /** * Marks a variable with the given name in the current scope as used. * This affects the no-unused-vars rule. - * @since 8.39.0 */ - markVariableAsUsed?(name: string, node: TSESTree.Node): boolean; + markVariableAsUsed(name: string, node: TSESTree.Node): boolean; /** * The source code split into lines according to ECMA-262 specification. * This is done to avoid each rule needing to do so separately. @@ -337,7 +332,7 @@ declare class SourceCodeBase extends TokenStore { /** * The parser services of this source code. */ - parserServices: ParserServices; + parserServices?: Partial; /** * The scope of this source code. */ diff --git a/packages/utils/src/ts-eslint/index.ts b/packages/utils/src/ts-eslint/index.ts index 5f6a1e1b71d..217b46dcbf7 100644 --- a/packages/utils/src/ts-eslint/index.ts +++ b/packages/utils/src/ts-eslint/index.ts @@ -1,5 +1,4 @@ export * from './AST'; -export * from './CLIEngine'; export * from './Config'; export * from './ESLint'; export * from './Linter'; diff --git a/packages/utils/tests/eslint-utils/getParserServices.test.ts b/packages/utils/tests/eslint-utils/getParserServices.test.ts index 4fd4ed3cbff..103acb91044 100644 --- a/packages/utils/tests/eslint-utils/getParserServices.test.ts +++ b/packages/utils/tests/eslint-utils/getParserServices.test.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any, deprecation/deprecation -- wild and wacky testing */ +/* eslint-disable @typescript-eslint/no-explicit-any -- wild and wacky testing */ import type * as ts from 'typescript'; import type { ParserServices, TSESLint, TSESTree } from '../../src'; @@ -8,12 +8,14 @@ type UnknownRuleContext = Readonly>; const defaults = { parserPath: '@typescript-eslint/parser/dist/index.js', - parserServices: { - esTreeNodeToTSNodeMap: new Map(), - program: {}, - tsNodeToESTreeNodeMap: new Map(), - } as unknown as ParserServices, -}; + sourceCode: { + parserServices: { + esTreeNodeToTSNodeMap: new Map(), + program: {}, + tsNodeToESTreeNodeMap: new Map(), + } as unknown as ParserServices, + }, +} as unknown as UnknownRuleContext; const createMockRuleContext = ( overrides: Partial = {}, @@ -26,9 +28,12 @@ const createMockRuleContext = ( describe('getParserServices', () => { it('throws a standard error when parserOptions.esTreeNodeToTSNodeMap is missing and the parser is known', () => { const context = createMockRuleContext({ - parserServices: { - ...defaults.parserServices, - esTreeNodeToTSNodeMap: undefined as any, + sourceCode: { + ...defaults.sourceCode, + parserServices: { + ...defaults.sourceCode.parserServices, + esTreeNodeToTSNodeMap: undefined as any, + }, }, }); @@ -42,9 +47,12 @@ describe('getParserServices', () => { it('throws an augment error when parserOptions.esTreeNodeToTSNodeMap is missing and the parser is unknown', () => { const context = createMockRuleContext({ parserPath: '@babel/parser.js', - parserServices: { - ...defaults.parserServices, - esTreeNodeToTSNodeMap: undefined as any, + sourceCode: { + ...defaults.sourceCode, + parserServices: { + ...defaults.sourceCode.parserServices, + esTreeNodeToTSNodeMap: undefined as any, + }, }, }); @@ -58,9 +66,12 @@ describe('getParserServices', () => { it('throws an error when parserOptions.tsNodeToESTreeNodeMap is missing', () => { const context = createMockRuleContext({ - parserServices: { - ...defaults.parserServices, - tsNodeToESTreeNodeMap: undefined as any, + sourceCode: { + ...defaults.sourceCode, + parserServices: { + ...defaults.sourceCode.parserServices, + tsNodeToESTreeNodeMap: undefined as any, + }, }, }); @@ -73,9 +84,12 @@ describe('getParserServices', () => { it('throws an error when parserServices.program is missing and allowWithoutFullTypeInformation is false', () => { const context = createMockRuleContext({ - parserServices: { - ...defaults.parserServices, - program: undefined as any, + sourceCode: { + ...defaults.sourceCode, + parserServices: { + ...defaults.sourceCode.parserServices, + program: undefined as any, + }, }, }); @@ -88,20 +102,25 @@ describe('getParserServices', () => { it('returns when parserServices.program is missing and allowWithoutFullTypeInformation is true', () => { const context = createMockRuleContext({ - parserServices: { - ...defaults.parserServices, - program: undefined as any, + sourceCode: { + ...defaults.sourceCode, + parserServices: { + ...defaults.sourceCode.parserServices, + program: undefined as any, + }, }, }); expect(ESLintUtils.getParserServices(context, true)).toBe( - context.parserServices, + context.sourceCode.parserServices, ); }); it('returns when parserServices is filled out', () => { const context = createMockRuleContext(); - expect(ESLintUtils.getParserServices(context)).toBe(context.parserServices); + expect(ESLintUtils.getParserServices(context)).toBe( + context.sourceCode.parserServices, + ); }); }); diff --git a/packages/website/package.json b/packages/website/package.json index 6fdfafe630c..4da66f5bd27 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -23,7 +23,6 @@ "@docusaurus/remark-plugin-npm2yarn": "~2.4.1", "@docusaurus/theme-common": "~2.4.1", "@mdx-js/react": "1.6.22", - "@prettier/sync": "*", "@typescript-eslint/parser": "6.21.0", "@typescript-eslint/website-eslint": "6.21.0", "clsx": "^2.0.0", diff --git a/packages/website/plugins/generated-rule-docs/index.ts b/packages/website/plugins/generated-rule-docs/index.ts index 22fae4d8252..d8da7d9eb15 100644 --- a/packages/website/plugins/generated-rule-docs/index.ts +++ b/packages/website/plugins/generated-rule-docs/index.ts @@ -18,7 +18,7 @@ import { } from './utils'; export const generatedRuleDocs: Plugin = () => { - return (root, file) => { + return async (root, file) => { if (!nodeIsParent(root) || !isVFileWithStem(file)) { return; } @@ -36,7 +36,7 @@ export const generatedRuleDocs: Plugin = () => { const eslintrc = rule.meta.docs.extendsBaseRule ? insertBaseRuleReferences(page) - : insertNewRuleReferences(page); + : await insertNewRuleReferences(page); insertSpecialCaseOptions(page); insertWhenNotToUseIt(page); diff --git a/packages/website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts b/packages/website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts index d3c72292c49..0924b7270e0 100644 --- a/packages/website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts +++ b/packages/website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts @@ -1,8 +1,8 @@ -import prettier from '@prettier/sync'; import { compile } from '@typescript-eslint/rule-schema-to-typescript-types'; import type * as mdast from 'mdast'; import { EOL } from 'os'; import * as path from 'path'; +import prettier from 'prettier'; import type * as unist from 'unist'; import type { RuleDocsPage } from '../RuleDocsPage'; @@ -27,12 +27,32 @@ const SPECIAL_CASE_DEFAULTS = new Map([ ['ban-types', '[{ /* See below for default options */ }]'], ]); -const prettierConfig = { - ...(prettier.resolveConfig(__filename) ?? {}), - filepath: path.join(__dirname, '../defaults.ts'), -}; +const PRETTIER_CONFIG_PATH = path.resolve( + __dirname, + '..', + '..', + '..', + '..', + '..', + '.prettierrc.json', +); +const prettierConfig = (async () => { + const filepath = path.join(__dirname, 'file.ts'); + const config = await prettier.resolveConfig(filepath, { + config: PRETTIER_CONFIG_PATH, + }); + if (config == null) { + throw new Error('Unable to resolve prettier config'); + } + return { + ...config, + filepath, + }; +})(); -export function insertNewRuleReferences(page: RuleDocsPage): string { +export async function insertNewRuleReferences( + page: RuleDocsPage, +): Promise { // For non-extended rules, the code snippet is placed before the first h2 // (i.e. at the end of the initial explanation) const firstH2Index = page.children.findIndex( @@ -97,10 +117,10 @@ export function insertNewRuleReferences(page: RuleDocsPage): string { lang: 'ts', type: 'code', value: [ - compile(page.rule.meta.schema), - prettier.format( + await compile(page.rule.meta.schema, prettierConfig), + await prettier.format( `const defaultOptions: Options = ${defaults};`, - prettierConfig, + await prettierConfig, ), ] .join(EOL) diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index b881319e58a..aa31f79ad70 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -5,7 +5,8 @@ import { import CopyIcon from '@theme/Icon/Copy'; import IconExternalLink from '@theme/Icon/ExternalLink'; import SuccessIcon from '@theme/Icon/Success'; -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; +import semverSatisfies from 'semver/functions/satisfies'; import { useClipboard } from '../hooks/useClipboard'; import Checkbox from './inputs/Checkbox'; @@ -24,6 +25,8 @@ export interface OptionsSelectorParams { readonly tsVersions: readonly string[]; } +const MIN_TS_VERSION_SEMVER = '>=4.7.4'; + function OptionsSelectorContent({ state, setState, @@ -47,6 +50,14 @@ function OptionsSelectorContent({ ?.focus(); }, [state]); + const tsVersionsFiltered = useMemo( + () => + tsVersions.filter(version => + semverSatisfies(version, MIN_TS_VERSION_SEMVER), + ), + [tsVersions], + ); + return ( <> @@ -55,9 +66,11 @@ function OptionsSelectorContent({ name="ts" className="text--right" value={state.ts} - disabled={!tsVersions.length} + disabled={!tsVersionsFiltered.length} onChange={(ts): void => setState({ ts })} - options={tsVersions.length ? tsVersions : [state.ts]} + options={ + tsVersionsFiltered.length ? tsVersionsFiltered : [state.ts] + } /> {process.env.ESLINT_VERSION} diff --git a/packages/website/src/components/editor/useSandboxServices.ts b/packages/website/src/components/editor/useSandboxServices.ts index bc8d1ac0582..2e231c60491 100644 --- a/packages/website/src/components/editor/useSandboxServices.ts +++ b/packages/website/src/components/editor/useSandboxServices.ts @@ -72,9 +72,7 @@ export const useSandboxServices = ( colorMode === 'dark' ? 'vs-dark' : 'vs-light', ); - // registerInlayHintsProvider was added in TS 4.4 and isn't in TS <= 4.3. - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - sandboxInstance.monaco.languages.registerInlayHintsProvider?.( + sandboxInstance.monaco.languages.registerInlayHintsProvider( sandboxInstance.language, createTwoslashInlayProvider(sandboxInstance), ); diff --git a/yarn.lock b/yarn.lock index b1fdfa3f6a8..fe0f6687026 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4213,7 +4213,7 @@ __metadata: languageName: node linkType: hard -"@prettier/sync@npm:*, @prettier/sync@npm:^0.5.0": +"@prettier/sync@npm:^0.5.0": version: 0.5.0 resolution: "@prettier/sync@npm:0.5.0" dependencies: @@ -5376,7 +5376,7 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/eslint-plugin-internal@workspace:packages/eslint-plugin-internal" dependencies: - "@prettier/sync": "*" + "@prettier/sync": ^0.5.0 "@typescript-eslint/rule-tester": 6.21.0 "@typescript-eslint/scope-manager": 6.21.0 "@typescript-eslint/type-utils": 6.21.0 @@ -5398,7 +5398,7 @@ __metadata: prettier: ^3.0.3 rimraf: "*" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 tslint: ^5.0.0 || ^6.0.0 typescript: "*" languageName: unknown @@ -5409,7 +5409,6 @@ __metadata: resolution: "@typescript-eslint/eslint-plugin@workspace:packages/eslint-plugin" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@prettier/sync": "*" "@types/debug": "*" "@types/marked": "*" "@types/natural-compare": "*" @@ -5421,8 +5420,10 @@ __metadata: "@typescript-eslint/visitor-keys": 6.21.0 ajv: ^6.12.6 chalk: ^5.3.0 + cross-env: ^7.0.3 cross-fetch: "*" debug: ^4.3.4 + eslint: "*" grapheme-splitter: ^1.0.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -5441,7 +5442,7 @@ __metadata: typescript: "*" peerDependencies: "@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true @@ -5452,6 +5453,7 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/integration-tests@workspace:packages/integration-tests" dependencies: + jest: 29.7.0 ncp: "*" tmp: "*" languageName: unknown @@ -5474,7 +5476,7 @@ __metadata: rimraf: "*" typescript: "*" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true @@ -5486,7 +5488,6 @@ __metadata: resolution: "@typescript-eslint/repo-tools@workspace:packages/repo-tools" dependencies: "@nx/devkit": "*" - "@prettier/sync": "*" cross-fetch: "*" execa: "*" prettier: ^3.0.3 @@ -5501,7 +5502,6 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/rule-schema-to-typescript-types@workspace:packages/rule-schema-to-typescript-types" dependencies: - "@prettier/sync": "*" "@typescript-eslint/type-utils": 6.21.0 "@typescript-eslint/utils": 6.21.0 natural-compare: ^1.4.0 @@ -5526,7 +5526,7 @@ __metadata: source-map-support: ^0.5.21 peerDependencies: "@eslint/eslintrc": ">=2" - eslint: ">=8" + eslint: ^8.56.0 languageName: unknown linkType: soft @@ -5534,7 +5534,6 @@ __metadata: version: 0.0.0-use.local resolution: "@typescript-eslint/scope-manager@workspace:packages/scope-manager" dependencies: - "@prettier/sync": "*" "@types/glob": "*" "@typescript-eslint/types": 6.21.0 "@typescript-eslint/typescript-estree": 6.21.0 @@ -5573,7 +5572,7 @@ __metadata: ts-api-utils: ^1.0.1 typescript: "*" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true @@ -5613,7 +5612,6 @@ __metadata: "@nx/eslint": 17.2.8 "@nx/jest": 17.2.8 "@nx/workspace": 17.2.8 - "@prettier/sync": ^0.5.0 "@swc/core": ^1.3.68 "@swc/jest": ^0.2.26 "@types/babel__code-frame": ^7.0.3 @@ -5634,7 +5632,7 @@ __metadata: cross-fetch: ^4.0.0 cspell: ^7.0.0 downlevel-dts: ">=0.11.0" - eslint: ^8.56.0 + eslint: 8.56.0 eslint-plugin-deprecation: ^2.0.0 eslint-plugin-eslint-comments: ^3.2.0 eslint-plugin-eslint-plugin: ^5.2.1 @@ -5667,7 +5665,7 @@ __metadata: ts-node: 10.7.0 tslint: ^6.1.3 tsx: ^4.6.2 - typescript: ">=4.3.5 <5.4.0" + typescript: ">=4.7.4 <5.4.0" typescript-eslint: "workspace:^" yargs: 17.7.2 languageName: unknown @@ -5737,7 +5735,7 @@ __metadata: semver: ^7.5.4 typescript: "*" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 languageName: unknown linkType: soft @@ -7955,6 +7953,18 @@ __metadata: languageName: node linkType: hard +"cross-env@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-env@npm:7.0.3" + dependencies: + cross-spawn: ^7.0.1 + bin: + cross-env: src/bin/cross-env.js + cross-env-shell: src/bin/cross-env-shell.js + checksum: 26f2f3ea2ab32617f57effb70d329c2070d2f5630adc800985d8b30b56e8bf7f5f439dd3a0358b79cee6f930afc23cf8e23515f17ccfb30092c6b62c6b630a79 + languageName: node + linkType: hard + "cross-fetch@npm:*, cross-fetch@npm:^4.0.0": version: 4.0.0 resolution: "cross-fetch@npm:4.0.0" @@ -7973,7 +7983,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -9596,7 +9606,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:*, eslint@npm:^8.56.0": +"eslint@npm:8.56.0": version: 8.56.0 resolution: "eslint@npm:8.56.0" dependencies: @@ -18427,7 +18437,7 @@ __metadata: rimraf: "*" typescript: "*" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true @@ -19205,7 +19215,6 @@ __metadata: "@docusaurus/remark-plugin-npm2yarn": ~2.4.1 "@docusaurus/theme-common": ~2.4.1 "@mdx-js/react": 1.6.22 - "@prettier/sync": "*" "@types/react": "*" "@types/react-helmet": ^6.1.6 "@types/react-router-dom": ^5.3.3