diff --git a/.github/actions/prepare-build/action.yml b/.github/actions/prepare-build/action.yml index 227b60733b3e..e88bd2cfb93b 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 4f701841d79e..2334ef0b406f 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 f5095651e30b..15111ea9c4d3 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 9951a2cc4bcd..225405e2f4de 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 73d4e4fbed2d..6f14a129f17a 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 1954306a646a..386cb3a3d68d 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 23da68e6698e..2baa28a19e7a 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 89505dd00858..8e31ab2be3f2 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 4c13b42b9cc5..19cb2d33fb1c 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 ab3e3c3cfd83..2b0924bb7839 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 c9170531b501..89abe0507f55 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 66e90db95e59..8c19df75b90f 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 b55e7202f555..52a40e2519cf 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 1474e330c030..fc8d5f32f80a 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 e2c3767e9130..084ea2447e89 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 5c70c7b9179b..b0f964f58d1b 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 32189a2e3f1f..4c84981a9fa3 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 574c16937e98..da2d79716a35 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 ac71dbb1d2b7..e127bb1a6a02 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 6ab52b48ab29..ed76480e75f7 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 d2212e8e751a..483ad9a40807 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 d6240415b066..6236a46ddb7b 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 45d94c4a491c..60b48ecd0b2c 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 09abc747b5a2..e22bbaa73f45 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 1913cdfc4e52..5ef447ede85b 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 601c47c4621d..f0f91cc32b8e 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 ed3b0bf487a4..418cfa48f928 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 7a10fd392fe8..1b0f405f73ed 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 78efc59bb853..236659d13adb 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 b6d2a0fdce81..b4d0dbd52acc 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 e6201df8e9e6..d135f4c1a0d3 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 18919815cd19..52453371540c 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 092179f8187d..f04a71de8b63 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 510730fca997..4e87b7c6d076 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 c2d61583405a..1f25bd794515 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 bb882d1e8b48..28ba361e7a76 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 b36900062988..ff3878ec6340 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 9c25d24351a6..1e731bbdf761 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 08e44c52abe2..428f31f3667e 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 34fed637e6c8..949758785b2b 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 6ab9c1c2ec8c..0a17da9c0913 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 2ffbf7b665bf..4af3fd2502c8 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 694fafe14d63..b164e5713e6d 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 141332e06382..d9900a1df10f 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 8cca081f4122..131579e8457e 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 76e60100422c..9caf777aabad 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 3eae588d0079..95764e92bb9c 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 09c734a75585..08dd0b35d3b8 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 7c99a1d92b7d..58bd5ad6db24 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 5d99e32a149c..35c9b65937af 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 44f8eb977009..674b86d44bf9 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 8360df8e3ee4..0ed0f4c6b4de 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 f52e623cb9f0..4d68f2d6db46 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 8c6d9bc74338..de2e0574929d 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 ec451f854cb7..1658d471bc7b 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 122ff346a865..f332642a339c 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 c1acdb24fe7a..fc87428ece3d 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 d552dfb43add..3d92174c95af 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 c78e266da2a3..a34217453b0d 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 ed3747884abd..06938f9e4dcf 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 f91e48fb3c91..e8fdde8d1f33 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 2b79f31a67e6..c9bd94036f09 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 4ff6ecfbd6e6..c6b9213259be 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 ad56985f723e..1369254b16ae 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 f80d0ee00914..62bd5f1ab890 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 35d8531798ad..b084d90650b0 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 c4f20e6c68f7..9b83ac66aeca 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 2904d7dbb1f6..628982acae0b 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 da027bef8c6f..b472f75e5a0a 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 34ebfc018d6a..2f331dc78a6b 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 90ae6a50694f..34f973667c51 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 ea17c721404b..4d79c84368e0 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 42097bc5f59a..77ea5c874e91 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 ee053563a3a1..2d8a797b116f 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 6575b321bd18..f98e59b4cd65 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 a0094bee811d..d9117605c404 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 f4e7d335eec5..c08a21b4bac5 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 462b40304e70..a21f1cfa6224 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 3605904e655b..30838ed7b99d 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 8a9fa392becd..e4b237cccc85 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 0f89ef5b98b2..e84677f01a1f 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 563bc8e99ec9..315d3e80d74d 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 17fee949b01e..d72a2591c415 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 112caf8ae3c1..27572b4f8f7f 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 e94f384ecd33..babee93bab87 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 54fbd4fefc14..0f6bba8d5430 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 c1d4bc8ec9c1..e85ae87df8e3 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 4a63edfa5b27..ffd58daf8be0 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 d18079492b29..576d896c972d 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 144aa08641b5..9faa2d52a3db 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 cc5d3e91f53e..ec1a811ac3c1 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 edb502c4a451..24791c5841ed 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 69494823e023..1b7de382d47d 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 faf8db39a55c..c1748195b392 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 4ea5d7f59794..9a196e7be0d0 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 4669cc2a97c6..1b8109f87a5b 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 d63e58d88f93..7cf6976e3e67 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 55507cf1e486..7dc15dc44b7e 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 2c286cb45506..e9dfabc3ca80 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 dd033c7cbe2d..989f4e356a27 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 fa3c6d5479e0..d86b0874f8f3 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 856ed2067727..909af8c59bf0 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 5a668cc20f89..cb50e5b57eb0 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 d3966db56558..1bde80f3f776 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 561d6b27e2c2..b9094ad29b64 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 7ead3c9367ad..c5fea6021ad2 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 3247982dc2ad..34b5d90be1c6 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 fe377123ee26..a45662c33d4c 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 bfc31993a501..62dcd7495cb2 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 de08e970d491..97a17c620957 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 9b5edbe0afba..08ea21c58282 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 0b0b592bf60d..80b05c7c43d4 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 ef9f4c12503a..c3349011de52 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 2b8cdf15bb28..4d4bb3b5ae1d 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 a9956f09fc4f..117a7a374d33 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 6ebcb82e3aaa..1ffe8d86b5fb 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 46531f75267a..3b0df609377f 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 4b76427cfe8f..b038e010f65e 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 91053830e863..5d352f99ba70 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 d24ad789e596..1f335765c675 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 10a4c04b42f5..ccf55f9eaf58 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 04ee15735c4d..94d26e6f197f 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 d368bbe61fd8..2cbacdffb341 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 12acba6dd3fc..7222cb8b907b 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 b4f6356efef4..3ae10b5b1423 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 162877446c69..2845cb0f3c4b 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 a7cd216a4f4d..1ca02bd7add2 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 5d39c2a2610e..2bbdfd86aa08 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 a5dd34cb94aa..f7aa671cfbc7 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 48b700584efa..1701f9a44960 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 5524203d1815..b1670bc6b9f1 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 a3edc6db68ea..69e337694b06 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 b9a07bf8181d..2e8cc730113b 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 1f5568e3d6ac..2e42192090ca 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 5d301e04f2b6..68e8f106781d 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 d939ab3f81c3..0065741800d5 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 abf752dd55f6..ae22b9f0f5d9 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 eb23a06011ea..1a77699f990f 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 4bcdf33503c7..29ef557e4225 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 6cde96165773..bbdfe9dff9e9 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 b732dfc62c1a..bb169f8a138a 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 d18618ace255..86630e6264f0 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 90a553e2fd7d..32da7e7efd2e 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 1d2f41199897..290f038ddd50 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 03d5f1d8f8c6..b1dabac0bb4c 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 26f0382536d9..58530de4e1d0 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 2fc21ed3c565..097414cf8345 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 c8017c324365..63e21873f983 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 8599bdb135d8..39431a7e3f5e 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 3eb898abc8f7..13882d67c9ce 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 422499683435..50261e294bb2 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 03b664401a92..15c6ad10f542 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 266d07eef566..8b7db097ec1b 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 28ddb3cc154e..000000000000 --- 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 30f16a8613d7..c834c230091d 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 29062e4e7083..baf3e82bc653 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 2e668b49bfcd..000000000000 --- 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 1c040d2bfef9..7d65599bc06e 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 104d8f83765f..4eb31dd6e879 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 5d23b07afb0c..01cfd91a1e81 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 51b54fb7b5f3..9e3e0166b0ee 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 50ffd9000a7e..3216efb26e65 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 5f6a1e1b71d5..217b46dcbf7d 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 4fd4ed3cbff2..103acb91044b 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 6fdfafe630ca..4da66f5bd278 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 22fae4d82526..d8da7d9eb154 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 d3c72292c49f..0924b7270e05 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 b881319e58ab..aa31f79ad702 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 bc8d1ac0582d..2e231c60491e 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 b1fdfa3f6a8c..fe0f66870266 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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy