diff --git a/.changeset/slimy-jokes-reflect.md b/.changeset/slimy-jokes-reflect.md new file mode 100644 index 000000000..6059a1c90 --- /dev/null +++ b/.changeset/slimy-jokes-reflect.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat: use eslint-compat-utils diff --git a/.eslintrc.js b/.eslintrc.js index 40e8a3a6c..a81c80236 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -133,6 +133,19 @@ module.exports = { } ] } + ], + 'no-restricted-properties': [ + 'error', + { object: 'context', property: 'getSourceCode', message: 'Use src/utils/compat.ts' }, + { object: 'context', property: 'getFilename', message: 'Use src/utils/compat.ts' }, + { + object: 'context', + property: 'getPhysicalFilename', + message: 'Use src/utils/compat.ts' + }, + { object: 'context', property: 'getCwd', message: 'Use src/utils/compat.ts' }, + { object: 'context', property: 'getScope', message: 'Use src/utils/compat.ts' }, + { object: 'context', property: 'parserServices', message: 'Use src/utils/compat.ts' } ] } }, diff --git a/package.json b/package.json index b7a08c8e3..031e89143 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "@eslint-community/eslint-utils": "^4.2.0", "@jridgewell/sourcemap-codec": "^1.4.14", "debug": "^4.3.1", + "eslint-compat-utils": "^0.1.2", "esutils": "^2.0.3", "known-css-properties": "^0.29.0", "postcss": "^8.4.5", diff --git a/src/rules/@typescript-eslint/no-unnecessary-condition.ts b/src/rules/@typescript-eslint/no-unnecessary-condition.ts index 0824dcba6..eb3123b2c 100644 --- a/src/rules/@typescript-eslint/no-unnecessary-condition.ts +++ b/src/rules/@typescript-eslint/no-unnecessary-condition.ts @@ -22,6 +22,7 @@ import { isTupleType } from '../../utils/ts-utils'; import type { TS, TSTools } from '../../utils/ts-utils'; +import { getSourceCode } from '../../utils/compat'; /** * Returns all types of a union type or an array containing `type` itself if it's no union type. @@ -156,7 +157,7 @@ export default createRule('@typescript-eslint/no-unnecessary-condition', { const { service, ts } = tools; const checker = service.program.getTypeChecker(); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const compilerOptions = service.program.getCompilerOptions(); const isStrictNullChecks = compilerOptions.strict ? compilerOptions.strictNullChecks !== false diff --git a/src/rules/block-lang.ts b/src/rules/block-lang.ts index 41a1c9b87..1beb94e80 100644 --- a/src/rules/block-lang.ts +++ b/src/rules/block-lang.ts @@ -1,6 +1,7 @@ import { createRule } from '../utils'; import { getLangValue } from '../utils/ast-utils'; import type { SvelteScriptElement, SvelteStyleElement } from 'svelte-eslint-parser/lib/ast'; +import { getSourceCode } from '../utils/compat'; export default createRule('block-lang', { meta: { @@ -56,7 +57,7 @@ export default createRule('block-lang', { type: 'suggestion' }, create(context) { - if (!context.parserServices.isSvelte) { + if (!getSourceCode(context).parserServices.isSvelte) { return {}; } const enforceScriptPresent: boolean = context.options[0]?.enforceScriptPresent ?? false; diff --git a/src/rules/comment-directive.ts b/src/rules/comment-directive.ts index c905677e6..116b23a4b 100644 --- a/src/rules/comment-directive.ts +++ b/src/rules/comment-directive.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import { getShared } from '../shared'; import type { CommentDirectives } from '../shared/comment-directives'; import { createRule } from '../utils'; +import { getFilename, getSourceCode } from '../utils/compat'; type RuleAndLocation = { ruleId: string; @@ -53,7 +54,7 @@ export default createRule('comment-directive', { type: 'problem' }, create(context) { - const shared = getShared(context.getFilename()); + const shared = getShared(getFilename(context)); if (!shared) return {}; const options = context.options[0] || {}; const reportUnusedDisableDirectives = Boolean(options.reportUnusedDisableDirectives); @@ -62,7 +63,7 @@ export default createRule('comment-directive', { reportUnusedDisableDirectives }); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Parse a given comment. diff --git a/src/rules/first-attribute-linebreak.ts b/src/rules/first-attribute-linebreak.ts index 3c87e1261..34a953d33 100644 --- a/src/rules/first-attribute-linebreak.ts +++ b/src/rules/first-attribute-linebreak.ts @@ -1,5 +1,6 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('first-attribute-linebreak', { meta: { @@ -29,7 +30,7 @@ export default createRule('first-attribute-linebreak', { create(context) { const multiline: 'below' | 'beside' = context.options[0]?.multiline || 'below'; const singleline: 'below' | 'beside' = context.options[0]?.singleline || 'beside'; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Report attribute diff --git a/src/rules/html-quotes.ts b/src/rules/html-quotes.ts index 0ff192151..8935e3da5 100644 --- a/src/rules/html-quotes.ts +++ b/src/rules/html-quotes.ts @@ -3,6 +3,7 @@ import { createRule } from '../utils'; import type { QuoteAndRange } from '../utils/ast-utils'; import { getMustacheTokens } from '../utils/ast-utils'; import { getAttributeValueQuoteAndRange } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; const QUOTE_CHARS = { double: '"', @@ -48,7 +49,7 @@ export default createRule('html-quotes', { type: 'layout' // "problem", }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const preferQuote: 'double' | 'single' = context.options[0]?.prefer ?? 'double'; const dynamicQuote = context.options[0]?.dynamic?.quoted ? preferQuote : 'unquoted'; const avoidInvalidUnquotedInHTML = Boolean( diff --git a/src/rules/html-self-closing.ts b/src/rules/html-self-closing.ts index 17df3870e..d4bf01b40 100644 --- a/src/rules/html-self-closing.ts +++ b/src/rules/html-self-closing.ts @@ -1,6 +1,7 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; import { getNodeName, isVoidHtmlElement } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; const TYPE_MESSAGES = { normal: 'HTML elements', @@ -126,9 +127,9 @@ export default createRule('html-self-closing', { context.report({ node, loc: { - start: context - .getSourceCode() - .getLocFromIndex(node.startTag.range[1] - (node.startTag.selfClosing ? 2 : 1)), + start: getSourceCode(context).getLocFromIndex( + node.startTag.range[1] - (node.startTag.selfClosing ? 2 : 1) + ), end: node.loc.end }, messageId: shouldBeClosed ? 'requireClosing' : 'disallowClosing', diff --git a/src/rules/indent-helpers/index.ts b/src/rules/indent-helpers/index.ts index 5150c926b..6ef6172db 100644 --- a/src/rules/indent-helpers/index.ts +++ b/src/rules/indent-helpers/index.ts @@ -9,6 +9,7 @@ import { isCommentToken } from '@eslint-community/eslint-utils'; import type { AnyToken, IndentOptions } from './commons'; import type { OffsetCalculator } from './offset-context'; import { OffsetContext } from './offset-context'; +import { getFilename, getSourceCode } from '../../utils/compat'; type IndentUserOptions = { indent?: number | 'tab'; @@ -78,10 +79,10 @@ export function defineVisitor( context: RuleContext, defaultOptions: Partial ): RuleListener { - if (!context.getFilename().endsWith('.svelte')) return {}; + if (!getFilename(context).endsWith('.svelte')) return {}; const options = parseOptions(context.options[0] || {}, defaultOptions); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const offsets = new OffsetContext({ sourceCode, options }); /** diff --git a/src/rules/infinite-reactive-loop.ts b/src/rules/infinite-reactive-loop.ts index 157481e55..910709b42 100644 --- a/src/rules/infinite-reactive-loop.ts +++ b/src/rules/infinite-reactive-loop.ts @@ -5,6 +5,7 @@ import { createRule } from '../utils'; import type { RuleContext } from '../types'; import { findVariable } from '../utils/ast-utils'; import { traverseNodes } from 'svelte-eslint-parser'; +import { getSourceCode } from '../utils/compat'; /** * Get usage of `tick` @@ -12,7 +13,7 @@ import { traverseNodes } from 'svelte-eslint-parser'; function extractTickReferences( context: RuleContext ): { node: TSESTree.CallExpression; name: string }[] { - const referenceTracker = new ReferenceTracker(context.getSourceCode().scopeManager.globalScope!); + const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope!); const a = referenceTracker.iterateEsmReferences({ svelte: { [ReferenceTracker.ESM]: true, @@ -35,7 +36,7 @@ function extractTickReferences( function extractTaskReferences( context: RuleContext ): { node: TSESTree.CallExpression; name: string }[] { - const referenceTracker = new ReferenceTracker(context.getSourceCode().scopeManager.globalScope!); + const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope!); const a = referenceTracker.iterateGlobalReferences({ setTimeout: { [ReferenceTracker.CALL]: true }, setInterval: { [ReferenceTracker.CALL]: true }, @@ -122,7 +123,7 @@ function isPromiseThenOrCatchBody(node: TSESTree.Node): boolean { * Get all reactive variable reference. */ function getReactiveVariableReferences(context: RuleContext) { - const scopeManager = context.getSourceCode().scopeManager; + const scopeManager = getSourceCode(context).scopeManager; // Find the top-level (module or global) scope. // Any variable defined at the top-level (module scope or global scope) can be made reactive. const toplevelScope = diff --git a/src/rules/max-attributes-per-line.ts b/src/rules/max-attributes-per-line.ts index ad09e8784..63001ac53 100644 --- a/src/rules/max-attributes-per-line.ts +++ b/src/rules/max-attributes-per-line.ts @@ -1,5 +1,6 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; /** * Check whether the component is declared in a single line or not. @@ -57,7 +58,7 @@ export default createRule('max-attributes-per-line', { create(context) { const multilineMaximum = context.options[0]?.multiline ?? 1; const singlelineMaximum = context.options[0]?.singleline ?? 1; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Report attributes diff --git a/src/rules/mustache-spacing.ts b/src/rules/mustache-spacing.ts index 76892f54a..1b1c971e5 100644 --- a/src/rules/mustache-spacing.ts +++ b/src/rules/mustache-spacing.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import { isClosingBraceToken, isOpeningBraceToken } from '@eslint-community/eslint-utils'; import { createRule } from '../utils'; import { getMustacheTokens } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; type DeepPartial = { [P in keyof T]?: DeepPartial; }; @@ -73,7 +74,7 @@ export default createRule('mustache-spacing', { }, create(context) { const options = parseOptions(context.options[0]); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); function verifyBraces( openingBrace: AST.Token | AST.Comment, diff --git a/src/rules/no-dupe-else-if-blocks.ts b/src/rules/no-dupe-else-if-blocks.ts index 3919f2720..9ec431492 100644 --- a/src/rules/no-dupe-else-if-blocks.ts +++ b/src/rules/no-dupe-else-if-blocks.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; import { equalTokens } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; // ------------------------------------------------------------------------------ // Helpers @@ -81,7 +82,7 @@ export default createRule('no-dupe-else-if-blocks', { type: 'problem' // "problem", }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Determines whether the two given nodes are considered to be equal. In particular, given that the nodes diff --git a/src/rules/no-dupe-on-directives.ts b/src/rules/no-dupe-on-directives.ts index 7b2b625b6..a90451273 100644 --- a/src/rules/no-dupe-on-directives.ts +++ b/src/rules/no-dupe-on-directives.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; import { equalTokens } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-dupe-on-directives', { meta: { @@ -18,7 +19,7 @@ export default createRule('no-dupe-on-directives', { type: 'problem' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const directiveDataMap = new Map< string, // event type diff --git a/src/rules/no-dupe-use-directives.ts b/src/rules/no-dupe-use-directives.ts index f8c9ae0c4..e7830e685 100644 --- a/src/rules/no-dupe-use-directives.ts +++ b/src/rules/no-dupe-use-directives.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; import { equalTokens, getAttributeKeyText } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-dupe-use-directives', { meta: { @@ -18,7 +19,7 @@ export default createRule('no-dupe-use-directives', { type: 'problem' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const directiveDataMap = new Map< string, // key text diff --git a/src/rules/no-dynamic-slot-name.ts b/src/rules/no-dynamic-slot-name.ts index 8aca712e8..6b6c6ada3 100644 --- a/src/rules/no-dynamic-slot-name.ts +++ b/src/rules/no-dynamic-slot-name.ts @@ -6,6 +6,7 @@ import { getAttributeValueQuoteAndRange, getStringIfConstant } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-dynamic-slot-name', { meta: { @@ -23,7 +24,7 @@ export default createRule('no-dynamic-slot-name', { type: 'problem' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); return { "SvelteElement[name.name='slot'] > SvelteStartTag.startTag > SvelteAttribute[key.name='name']"( node: AST.SvelteAttribute diff --git a/src/rules/no-extra-reactive-curlies.ts b/src/rules/no-extra-reactive-curlies.ts index 98e796de2..489cd2483 100644 --- a/src/rules/no-extra-reactive-curlies.ts +++ b/src/rules/no-extra-reactive-curlies.ts @@ -1,5 +1,6 @@ import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-extra-reactive-curlies', { meta: { @@ -23,7 +24,7 @@ export default createRule('no-extra-reactive-curlies', { [`SvelteReactiveStatement > BlockStatement[body.length=1]`]: ( node: TSESTree.BlockStatement ) => { - const source = context.getSourceCode(); + const source = getSourceCode(context); return context.report({ node, diff --git a/src/rules/no-immutable-reactive-statements.ts b/src/rules/no-immutable-reactive-statements.ts index 0d978114e..a36a20c6f 100644 --- a/src/rules/no-immutable-reactive-statements.ts +++ b/src/rules/no-immutable-reactive-statements.ts @@ -3,6 +3,7 @@ import { createRule } from '../utils'; import type { Scope, Variable, Reference, Definition } from '@typescript-eslint/scope-manager'; import type { TSESTree } from '@typescript-eslint/types'; import { findVariable, iterateIdentifiers } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-immutable-reactive-statements', { meta: { @@ -20,7 +21,7 @@ export default createRule('no-immutable-reactive-statements', { type: 'suggestion' }, create(context) { - const scopeManager = context.getSourceCode().scopeManager; + const scopeManager = getSourceCode(context).scopeManager; const globalScope = scopeManager.globalScope; const toplevelScope = globalScope?.childScopes.find((scope) => scope.type === 'module') || globalScope; diff --git a/src/rules/no-reactive-functions.ts b/src/rules/no-reactive-functions.ts index 434da1d4f..c6ebe9e9a 100644 --- a/src/rules/no-reactive-functions.ts +++ b/src/rules/no-reactive-functions.ts @@ -1,6 +1,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-reactive-functions', { meta: { @@ -30,7 +31,7 @@ export default createRule('no-reactive-functions', { return false; } - const source = context.getSourceCode(); + const source = getSourceCode(context); return context.report({ node: parent, diff --git a/src/rules/no-reactive-literals.ts b/src/rules/no-reactive-literals.ts index a35ad15fe..e27f09596 100644 --- a/src/rules/no-reactive-literals.ts +++ b/src/rules/no-reactive-literals.ts @@ -1,5 +1,6 @@ import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-reactive-literals', { meta: { @@ -36,7 +37,7 @@ export default createRule('no-reactive-literals', { return false; } - const source = context.getSourceCode(); + const source = getSourceCode(context); return context.report({ node: parent, diff --git a/src/rules/no-reactive-reassign.ts b/src/rules/no-reactive-reassign.ts index 61f1a686b..0e41f2069 100644 --- a/src/rules/no-reactive-reassign.ts +++ b/src/rules/no-reactive-reassign.ts @@ -2,6 +2,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; import { getPropertyName } from '@eslint-community/eslint-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-reactive-reassign', { meta: { @@ -30,7 +31,7 @@ export default createRule('no-reactive-reassign', { }, create(context) { const props = context.options[0]?.props !== false; // default true - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const scopeManager = sourceCode.scopeManager; const globalScope = scopeManager.globalScope; const toplevelScope = diff --git a/src/rules/no-trailing-spaces.ts b/src/rules/no-trailing-spaces.ts index bdb982c54..1eee75c24 100644 --- a/src/rules/no-trailing-spaces.ts +++ b/src/rules/no-trailing-spaces.ts @@ -1,5 +1,6 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-trailing-spaces', { meta: { @@ -32,7 +33,7 @@ export default createRule('no-trailing-spaces', { const skipBlankLines = options?.skipBlankLines || false; const ignoreComments = options?.ignoreComments || false; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const ignoreLineNumbers = new Set(); if (ignoreComments) { diff --git a/src/rules/no-unused-class-name.ts b/src/rules/no-unused-class-name.ts index a797b5cad..40a23b6e7 100644 --- a/src/rules/no-unused-class-name.ts +++ b/src/rules/no-unused-class-name.ts @@ -10,6 +10,7 @@ import type { } from 'svelte-eslint-parser/lib/ast'; import type { AnyNode } from 'postcss'; import { default as selectorParser, type Node as SelectorNode } from 'postcss-selector-parser'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-unused-class-name', { meta: { @@ -36,7 +37,8 @@ export default createRule('no-unused-class-name', { type: 'suggestion' }, create(context) { - if (!context.parserServices.isSvelte) { + const sourceCode = getSourceCode(context); + if (!sourceCode.parserServices.isSvelte) { return {}; } const allowedClassNames = context.options[0]?.allowedClassNames ?? []; @@ -53,7 +55,7 @@ export default createRule('no-unused-class-name', { } }, 'Program:exit'() { - const styleContext = context.parserServices.getStyleContext(); + const styleContext = sourceCode.parserServices.getStyleContext(); if (['parse-error', 'unknown-lang'].includes(styleContext.status)) { return; } diff --git a/src/rules/no-unused-svelte-ignore.ts b/src/rules/no-unused-svelte-ignore.ts index 359bab5c3..434021935 100644 --- a/src/rules/no-unused-svelte-ignore.ts +++ b/src/rules/no-unused-svelte-ignore.ts @@ -2,6 +2,7 @@ import { getSvelteCompileWarnings } from '../shared/svelte-compile-warns'; import { createRule } from '../utils'; import type { IgnoreItem } from '../shared/svelte-compile-warns/ignore-comment'; import { getSvelteIgnoreItems } from '../shared/svelte-compile-warns/ignore-comment'; +import { getSourceCode } from '../utils/compat'; export default createRule('no-unused-svelte-ignore', { meta: { @@ -19,10 +20,10 @@ export default createRule('no-unused-svelte-ignore', { }, create(context) { - if (!context.parserServices.isSvelte) { + const sourceCode = getSourceCode(context); + if (!sourceCode.parserServices.isSvelte) { return {}; } - const sourceCode = context.getSourceCode(); const ignoreComments: IgnoreItem[] = []; for (const item of getSvelteIgnoreItems(context)) { diff --git a/src/rules/no-useless-mustaches.ts b/src/rules/no-useless-mustaches.ts index 9d11f9c32..0eab8ad27 100644 --- a/src/rules/no-useless-mustaches.ts +++ b/src/rules/no-useless-mustaches.ts @@ -1,5 +1,6 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; +import { getSourceCode } from '../utils/compat'; /** * Strip quotes string @@ -45,7 +46,7 @@ export default createRule('no-useless-mustaches', { const opts = context.options[0] || {}; const ignoreIncludesComment = Boolean(opts.ignoreIncludesComment); const ignoreStringEscape = Boolean(opts.ignoreStringEscape); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Report if the value expression is string literals diff --git a/src/rules/prefer-class-directive.ts b/src/rules/prefer-class-directive.ts index 017a4096f..acd877265 100644 --- a/src/rules/prefer-class-directive.ts +++ b/src/rules/prefer-class-directive.ts @@ -3,6 +3,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import { createRule } from '../utils'; import { getStringIfConstant, isHTMLElementLike, needParentheses } from '../utils/ast-utils'; import type { Rule } from 'eslint'; +import { getSourceCode } from '../utils/compat'; export default createRule('prefer-class-directive', { meta: { @@ -20,7 +21,7 @@ export default createRule('prefer-class-directive', { type: 'suggestion' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); type Expr = { not?: true; diff --git a/src/rules/prefer-destructured-store-props.ts b/src/rules/prefer-destructured-store-props.ts index 1e3ca4303..c57ae59c4 100644 --- a/src/rules/prefer-destructured-store-props.ts +++ b/src/rules/prefer-destructured-store-props.ts @@ -5,6 +5,7 @@ import { keyword } from 'esutils'; import type { SuggestionReportDescriptor } from '../types'; import { createRule } from '../utils'; import { findAttribute, isExpressionIdentifier, findVariable } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; type StoreMemberExpression = TSESTree.MemberExpression & { object: TSESTree.Identifier & { name: string }; @@ -114,7 +115,7 @@ export default createRule('prefer-destructured-store-props', { /** Checks whether the given name is already defined as a variable. */ function hasTopLevelVariable(name: string) { - const scopeManager = context.getSourceCode().scopeManager; + const scopeManager = getSourceCode(context).scopeManager; if (scopeManager.globalScope?.set.has(name)) { return true; } @@ -251,7 +252,7 @@ export default createRule('prefer-destructured-store-props', { store, property: !node.computed ? node.property.name - : context.getSourceCode().getText(node.property).replace(/\s+/g, ' ') + : getSourceCode(context).getText(node.property).replace(/\s+/g, ' ') }, suggest diff --git a/src/rules/prefer-style-directive.ts b/src/rules/prefer-style-directive.ts index 90acdc525..a706d1185 100644 --- a/src/rules/prefer-style-directive.ts +++ b/src/rules/prefer-style-directive.ts @@ -9,6 +9,7 @@ import type { import { parseStyleAttributeValue } from '../utils/css-utils'; import type { RuleFixer } from '../types'; import { isHTMLElementLike } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; /** Checks wether the given node is string literal or not */ function isStringLiteral(node: TSESTree.Expression): node is TSESTree.StringLiteral { @@ -31,7 +32,7 @@ export default createRule('prefer-style-directive', { type: 'suggestion' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Process for `style=" ... "` diff --git a/src/rules/reference-helpers/svelte-store.ts b/src/rules/reference-helpers/svelte-store.ts index ba8451678..50bff723d 100644 --- a/src/rules/reference-helpers/svelte-store.ts +++ b/src/rules/reference-helpers/svelte-store.ts @@ -5,6 +5,7 @@ import type { RuleContext } from '../../types'; import type { TS, TSTools } from '../../utils/ts-utils'; import { getTypeScriptTools } from '../../utils/ts-utils'; import { findVariable, getParent } from '../../utils/ast-utils'; +import { getSourceCode } from '../../utils/compat'; type StoreName = 'writable' | 'readable' | 'derived'; @@ -13,7 +14,7 @@ export function* extractStoreReferences( context: RuleContext, storeNames: StoreName[] = ['writable', 'readable', 'derived'] ): Generator<{ node: TSESTree.CallExpression; name: string }, void> { - const referenceTracker = new ReferenceTracker(context.getSourceCode().scopeManager.globalScope!); + const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope!); for (const { node, path } of referenceTracker.iterateEsmReferences({ 'svelte/store': { [ReferenceTracker.ESM]: true, diff --git a/src/rules/require-event-dispatcher-types.ts b/src/rules/require-event-dispatcher-types.ts index 59261e48c..092c2f068 100644 --- a/src/rules/require-event-dispatcher-types.ts +++ b/src/rules/require-event-dispatcher-types.ts @@ -2,6 +2,7 @@ import { ReferenceTracker } from '@eslint-community/eslint-utils'; import { createRule } from '../utils'; import { getLangValue } from '../utils/ast-utils'; import type { TSESTree } from '@typescript-eslint/types'; +import { getSourceCode } from '../utils/compat'; export default createRule('require-event-dispatcher-types', { meta: { @@ -30,7 +31,7 @@ export default createRule('require-event-dispatcher-types', { return; } const referenceTracker = new ReferenceTracker( - context.getSourceCode().scopeManager.globalScope! + getSourceCode(context).scopeManager.globalScope! ); for (const { node: n } of referenceTracker.iterateEsmReferences({ svelte: { diff --git a/src/rules/require-store-reactive-access.ts b/src/rules/require-store-reactive-access.ts index 90b646697..95c11582f 100644 --- a/src/rules/require-store-reactive-access.ts +++ b/src/rules/require-store-reactive-access.ts @@ -2,6 +2,7 @@ import type { TSESTree } from '@typescript-eslint/types'; import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; import { createStoreChecker } from './reference-helpers/svelte-store'; +import { getSourceCode } from '../utils/compat'; export default createRule('require-store-reactive-access', { meta: { @@ -22,7 +23,7 @@ export default createRule('require-store-reactive-access', { type: 'problem' }, create(context) { - if (!context.parserServices.isSvelte) { + if (!getSourceCode(context).parserServices.isSvelte) { return {}; } const isStore = createStoreChecker(context); diff --git a/src/rules/shorthand-attribute.ts b/src/rules/shorthand-attribute.ts index aefe6643c..702486fed 100644 --- a/src/rules/shorthand-attribute.ts +++ b/src/rules/shorthand-attribute.ts @@ -1,5 +1,6 @@ import { createRule } from '../utils'; import { getAttributeValueQuoteAndRange } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('shorthand-attribute', { meta: { @@ -26,7 +27,7 @@ export default createRule('shorthand-attribute', { type: 'layout' // "problem", or "layout", }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const always: boolean = context.options[0]?.prefer !== 'never'; return always diff --git a/src/rules/shorthand-directive.ts b/src/rules/shorthand-directive.ts index 705d3b54c..a4e314169 100644 --- a/src/rules/shorthand-directive.ts +++ b/src/rules/shorthand-directive.ts @@ -1,6 +1,7 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; import { getAttributeValueQuoteAndRange } from '../utils/ast-utils'; +import { getSourceCode } from '../utils/compat'; export default createRule('shorthand-directive', { meta: { @@ -27,7 +28,7 @@ export default createRule('shorthand-directive', { type: 'layout' }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const always: boolean = context.options[0]?.prefer !== 'never'; /** Report for always */ diff --git a/src/rules/sort-attributes.ts b/src/rules/sort-attributes.ts index 2de0bdc53..dae17d14a 100644 --- a/src/rules/sort-attributes.ts +++ b/src/rules/sort-attributes.ts @@ -2,6 +2,7 @@ import type { AST } from 'svelte-eslint-parser'; import { createRule } from '../utils'; import { getAttributeKeyText } from '../utils/ast-utils'; import { toRegExp } from '../utils/regexp'; +import { getSourceCode } from '../utils/compat'; type UserOrderObjectOption = { match: string | string[]; @@ -253,7 +254,7 @@ export default createRule('sort-attributes', { attributes.indexOf(node) ); const moveNodes = [node, ...previousNodes]; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); return moveNodes.map((moveNode, index) => { const text = sourceCode.getText(moveNode); return fixer.replaceText(previousNodes[index] || node, text); diff --git a/src/rules/system.ts b/src/rules/system.ts index 1746877f5..e44365368 100644 --- a/src/rules/system.ts +++ b/src/rules/system.ts @@ -1,5 +1,6 @@ import { getShared } from '../shared'; import { createRule } from '../utils'; +import { getFilename } from '../utils/compat'; import { isRegExp, toRegExp } from '../utils/regexp'; export default createRule('system', { @@ -14,7 +15,7 @@ export default createRule('system', { type: 'problem' }, create(context) { - const shared = getShared(context.getFilename()); + const shared = getShared(getFilename(context)); if (!shared) return {}; const directives = shared.newCommentDirectives({ diff --git a/src/rules/valid-compile.ts b/src/rules/valid-compile.ts index 45082322a..0701d52ef 100644 --- a/src/rules/valid-compile.ts +++ b/src/rules/valid-compile.ts @@ -1,6 +1,7 @@ import { createRule } from '../utils'; import type { Warning } from '../shared/svelte-compile-warns'; import { getSvelteCompileWarnings } from '../shared/svelte-compile-warns'; +import { getSourceCode } from '../utils/compat'; export default createRule('valid-compile', { meta: { @@ -22,7 +23,7 @@ export default createRule('valid-compile', { type: 'problem' }, create(context) { - if (!context.parserServices.isSvelte) { + if (!getSourceCode(context).parserServices.isSvelte) { return {}; } const ignoreWarnings = Boolean(context.options[0]?.ignoreWarnings); diff --git a/src/shared/svelte-compile-warns/extract-leading-comments.ts b/src/shared/svelte-compile-warns/extract-leading-comments.ts index 584609806..b34ae2b64 100644 --- a/src/shared/svelte-compile-warns/extract-leading-comments.ts +++ b/src/shared/svelte-compile-warns/extract-leading-comments.ts @@ -2,13 +2,14 @@ import { isOpeningParenToken } from '@eslint-community/eslint-utils'; import type { AST } from 'svelte-eslint-parser'; import type { RuleContext } from '../../types'; import type { ASTNodeWithParent } from '../../types-for-node'; +import { getSourceCode } from '../../utils/compat'; /** Extract comments */ export function extractLeadingComments( context: RuleContext, node: ASTNodeWithParent ): (AST.Token | AST.Comment)[] { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const beforeToken = sourceCode.getTokenBefore(node, { includeComments: false, filter(token) { diff --git a/src/shared/svelte-compile-warns/ignore-comment.ts b/src/shared/svelte-compile-warns/ignore-comment.ts index bbb6d5c74..4d3fada04 100644 --- a/src/shared/svelte-compile-warns/ignore-comment.ts +++ b/src/shared/svelte-compile-warns/ignore-comment.ts @@ -1,5 +1,6 @@ import type { AST } from 'svelte-eslint-parser'; import type { RuleContext } from '../../types'; +import { getSourceCode } from '../../utils/compat'; const SVELTE_IGNORE_PATTERN = /^\s*svelte-ignore/m; @@ -16,7 +17,7 @@ export type IgnoreItem = { /** Extract all svelte-ignore comment items */ export function getSvelteIgnoreItems(context: RuleContext): (IgnoreItem | IgnoreItemWithoutCode)[] { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const ignoreComments: (IgnoreItem | IgnoreItemWithoutCode)[] = []; for (const comment of sourceCode.getAllComments()) { diff --git a/src/shared/svelte-compile-warns/index.ts b/src/shared/svelte-compile-warns/index.ts index 5ec8bd0b8..f41434364 100644 --- a/src/shared/svelte-compile-warns/index.ts +++ b/src/shared/svelte-compile-warns/index.ts @@ -19,6 +19,7 @@ import { findAttribute, getLangValue } from '../../utils/ast-utils'; import path from 'path'; import fs from 'fs'; import semver from 'semver'; +import { getSourceCode } from '../../utils/compat'; type WarningTargetNode = | (AST.SvelteProgram & ASTNodeWithParent) @@ -73,7 +74,7 @@ export type Warning = { * Get svelte compile warnings */ export function getSvelteCompileWarnings(context: RuleContext): SvelteCompileWarnings { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const cache = cacheAll.get(sourceCode.ast); if (cache) { return cache; @@ -87,7 +88,7 @@ export function getSvelteCompileWarnings(context: RuleContext): SvelteCompileWar * Get svelte compile warnings */ function getSvelteCompileWarningsWithoutCache(context: RuleContext): SvelteCompileWarnings { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); // Process for styles const styleElementsWithNotCSS = [...extractStyleElementsWithLangOtherThanCSS(context)]; @@ -96,7 +97,7 @@ function getSvelteCompileWarningsWithoutCache(context: RuleContext): SvelteCompi for (const style of styleElementsWithNotCSS) { const transform = STYLE_TRANSFORMS[style.lang]; if (transform) { - const result = transform(style.node, context.getSourceCode().text, context); + const result = transform(style.node, getSourceCode(context).text, context); if (result) { transformResults.push(result); continue; @@ -337,7 +338,7 @@ function* extractStyleElementsWithLangOtherThanCSS(context: RuleContext): Iterab node: AST.SvelteStyleElement; readonly lang: string; }> { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const root = sourceCode.ast; for (const node of root.body) { if (node.type === 'SvelteStyleElement') { @@ -357,7 +358,7 @@ function buildStrippedText( ignoreComments: IgnoreItem[], stripStyleTokens: AST.SvelteText[] ) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const baseText = sourceCode.text; const stripTokens = new Set([...ignoreComments.map((item) => item.token), ...stripStyleTokens]); @@ -387,7 +388,7 @@ function* transformScripts(context: RuleContext, text: string) { ? transformWithBabel : null; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); if (transform) { const root = sourceCode.ast; for (const node of root.body) { @@ -429,7 +430,7 @@ function getWarningsFromCode( generate: false, ...(semver.satisfies(compiler.VERSION, '>=4.0.0-0') ? { customElement: true } - : hasTagOption(context.getSourceCode().ast) + : hasTagOption(getSourceCode(context).ast) ? { customElement: true } : {}) }); @@ -468,7 +469,7 @@ function processIgnore( unusedIgnores: ignoreComments }; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const unusedIgnores = new Set(ignoreComments); const remainingWarning = new Set(warnings); @@ -599,8 +600,8 @@ function processIgnore( * Check if using TypeScript. */ function isUseTypeScript(context: RuleContext) { - if (context.parserServices.esTreeNodeToTSNodeMap) return true; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); + if (sourceCode.parserServices.esTreeNodeToTSNodeMap) return true; const root = sourceCode.ast; for (const node of root.body) { @@ -622,7 +623,7 @@ function isUseBabel(context: RuleContext) { if (!parser) { return false; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const root = sourceCode.ast; let scriptLang = 'js'; diff --git a/src/shared/svelte-compile-warns/transform/babel.ts b/src/shared/svelte-compile-warns/transform/babel.ts index 7eb594af4..3cc4c9310 100644 --- a/src/shared/svelte-compile-warns/transform/babel.ts +++ b/src/shared/svelte-compile-warns/transform/babel.ts @@ -3,6 +3,7 @@ import type babelCore from '@babel/core'; import type { RuleContext } from '../../../types'; import type { TransformResult } from './types'; import { loadModule } from '../../../utils/load-module'; +import { getCwd } from '../../../utils/compat'; type BabelCore = typeof babelCore; /** @@ -32,7 +33,7 @@ export function transform( minified: false, ast: false, code: true, - cwd: context.getCwd?.() ?? process.cwd() + cwd: getCwd(context) }); if (!output) { return null; diff --git a/src/shared/svelte-compile-warns/transform/less.ts b/src/shared/svelte-compile-warns/transform/less.ts index a5dfa6408..b489dfdd1 100644 --- a/src/shared/svelte-compile-warns/transform/less.ts +++ b/src/shared/svelte-compile-warns/transform/less.ts @@ -3,6 +3,7 @@ import type less from 'less'; import type { RuleContext } from '../../../types'; import type { TransformResult } from './types'; import { loadModule } from '../../../utils/load-module'; +import { getFilename } from '../../../utils/compat'; type Less = typeof less; /** @@ -25,7 +26,7 @@ export function transform( } const code = text.slice(...inputRange); - const filename = `${context.getFilename()}.less`; + const filename = `${getFilename(context)}.less`; try { let output: Awaited> | undefined; diff --git a/src/shared/svelte-compile-warns/transform/postcss.ts b/src/shared/svelte-compile-warns/transform/postcss.ts index 15830a398..4c3d699ab 100644 --- a/src/shared/svelte-compile-warns/transform/postcss.ts +++ b/src/shared/svelte-compile-warns/transform/postcss.ts @@ -3,6 +3,7 @@ import postcss from 'postcss'; import postcssLoadConfig from 'postcss-load-config'; import type { RuleContext } from '../../../types'; import type { TransformResult } from './types'; +import { getCwd, getFilename } from '../../../utils/compat'; /** * Transform with postcss @@ -24,13 +25,13 @@ export function transform( } const code = text.slice(...inputRange); - const filename = `${context.getFilename()}.css`; + const filename = `${getFilename(context)}.css`; try { const configFilePath = postcssConfig?.configFilePath; const config = postcssLoadConfig.sync( { - cwd: context.getCwd?.() ?? process.cwd(), + cwd: getCwd(context), from: filename }, typeof configFilePath === 'string' ? configFilePath : undefined diff --git a/src/shared/svelte-compile-warns/transform/stylus.ts b/src/shared/svelte-compile-warns/transform/stylus.ts index 6d13b7660..14a8a0240 100644 --- a/src/shared/svelte-compile-warns/transform/stylus.ts +++ b/src/shared/svelte-compile-warns/transform/stylus.ts @@ -4,6 +4,7 @@ import type { RawSourceMap } from 'source-map-js'; import type { RuleContext } from '../../../types'; import type { TransformResult } from './types'; import { loadModule } from '../../../utils/load-module'; +import { getFilename } from '../../../utils/compat'; type Stylus = typeof stylus; /** @@ -26,7 +27,7 @@ export function transform( } const code = text.slice(...inputRange); - const filename = `${context.getFilename()}.stylus`; + const filename = `${getFilename(context)}.stylus`; try { let output: string | undefined; diff --git a/src/shared/svelte-compile-warns/transform/typescript.ts b/src/shared/svelte-compile-warns/transform/typescript.ts index aeac371b6..90f755913 100644 --- a/src/shared/svelte-compile-warns/transform/typescript.ts +++ b/src/shared/svelte-compile-warns/transform/typescript.ts @@ -3,6 +3,7 @@ import type typescript from 'typescript'; import type { RuleContext } from '../../../types'; import type { TransformResult } from './types'; import { loadModule } from '../../../utils/load-module'; +import { getSourceCode } from '../../../utils/compat'; type TS = typeof typescript; /** @@ -30,7 +31,8 @@ export function transform( reportDiagnostics: false, compilerOptions: { target: - context.parserServices.program?.getCompilerOptions()?.target || ts.ScriptTarget.ESNext, + getSourceCode(context).parserServices.program?.getCompilerOptions()?.target || + ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve, sourceMap: true diff --git a/src/utils/ast-utils.ts b/src/utils/ast-utils.ts index 7d6c9d154..d05395908 100644 --- a/src/utils/ast-utils.ts +++ b/src/utils/ast-utils.ts @@ -4,6 +4,7 @@ import type { Scope, Variable } from '@typescript-eslint/scope-manager'; import type { AST as SvAST } from 'svelte-eslint-parser'; import * as eslintUtils from '@eslint-community/eslint-utils'; import voidElements from './void-elements'; +import { getSourceCode } from './compat'; /** * Checks whether or not the tokens of two given nodes are same. @@ -269,7 +270,7 @@ export function* iterateIdentifiers( * Gets the scope for the current node */ export function getScope(context: RuleContext, currentNode: TSESTree.Node): Scope { - const scopeManager = context.getSourceCode().scopeManager; + const scopeManager = getSourceCode(context).scopeManager; let node: TSESTree.Node | null = currentNode; for (; node; node = node.parent || null) { @@ -623,5 +624,5 @@ function getSimpleNameFromNode( throw new Error('Rule context is required'); } - return context.getSourceCode().getText(node); + return getSourceCode(context).getText(node); } diff --git a/src/utils/compat.ts b/src/utils/compat.ts new file mode 100644 index 000000000..701b1da39 --- /dev/null +++ b/src/utils/compat.ts @@ -0,0 +1,41 @@ +import { + getSourceCode as getSourceCodeBase, + getFilename as getFilenameBase, + getPhysicalFilename as getPhysicalFilenameBase, + getCwd as getCwdBase +} from 'eslint-compat-utils'; +import type { RuleContext, SourceCode } from '../types'; + +// export function getSourceCode(context: RuleContext): SourceCode; +// export function getSourceCode(context: Rule.RuleContext): ESLintSourceCode; +/** + * Returns an extended instance of `context.sourceCode` or the result of `context.getSourceCode()`. + * Extended instances can use new APIs such as `getScope(node)` even with old ESLint. + */ +export function getSourceCode(context: RuleContext): SourceCode { + return getSourceCodeBase(context as never) as never; +} + +/** + * Gets the value of `context.filename`, but for older ESLint it returns the result of `context.getFilename()`. + */ +export function getFilename(context: RuleContext): string { + return getFilenameBase(context as never); +} +/** + * Gets the value of `context.physicalFilename`, + * but for older ESLint it returns the result of `context.getPhysicalFilename()`. + * Versions older than v7.28.0 return a value guessed from the result of `context.getFilename()`, + * but it may be incorrect. + */ +export function getPhysicalFilename(context: RuleContext): string { + return getPhysicalFilenameBase(context as never); +} + +/** + * Gets the value of `context.cwd`, but for older ESLint it returns the result of `context.getCwd()`. + * Versions older than v6.6.0 return a value from the result of `process.cwd()`. + */ +export function getCwd(context: RuleContext): string { + return getCwdBase(context as never); +} diff --git a/src/utils/css-utils/style-attribute.ts b/src/utils/css-utils/style-attribute.ts index 09eddd80b..f4988ddbd 100644 --- a/src/utils/css-utils/style-attribute.ts +++ b/src/utils/css-utils/style-attribute.ts @@ -4,6 +4,7 @@ import Parser from './template-safe-parser'; import type { Root, ChildNode, AnyNode } from 'postcss'; import { Input } from 'postcss'; import type { TSESTree } from '@typescript-eslint/types'; +import { getSourceCode } from '../compat'; /** Parse for CSS */ function safeParseCss(css: string): Root | null { @@ -36,7 +37,7 @@ export function parseStyleAttributeValue( return null; } const startOffset = node.value[0].range[0]; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const cssCode = node.value.map((value) => sourceCode.getText(value)).join(''); const root = safeParseCss(cssCode); if (!root) { @@ -214,7 +215,7 @@ function convertRoot( if (inlineStyles.has(node)) { return inlineStyles.get(node) || null; } - const sourceCode = ctx.context.getSourceCode(); + const sourceCode = getSourceCode(ctx.context); inlineStyles.set(node, null); let converted: SvelteStyleRoot | null; @@ -361,7 +362,7 @@ function convertRange(node: AnyNode, ctx: Ctx): AST.Range { /** convert range */ function toLoc(range: AST.Range, ctx: Ctx): AST.SourceLocation { return { - start: ctx.context.getSourceCode().getLocFromIndex(range[0]), - end: ctx.context.getSourceCode().getLocFromIndex(range[1]) + start: getSourceCode(ctx.context).getLocFromIndex(range[0]), + end: getSourceCode(ctx.context).getLocFromIndex(range[1]) }; } diff --git a/src/utils/load-module.ts b/src/utils/load-module.ts index 026111b3f..1c29ef8aa 100644 --- a/src/utils/load-module.ts +++ b/src/utils/load-module.ts @@ -2,13 +2,14 @@ import type { AST } from 'svelte-eslint-parser'; import Module from 'module'; import path from 'path'; import type { RuleContext } from '../types'; +import { getCwd, getFilename, getPhysicalFilename, getSourceCode } from './compat'; const cache = new WeakMap>(); const cache4b = new Map(); /** * Load module */ export function loadModule(context: RuleContext, name: string): R | null { - const key = context.getSourceCode().ast; + const key = getSourceCode(context).ast; let modules = cache.get(key); if (!modules) { modules = {}; @@ -18,7 +19,7 @@ export function loadModule(context: RuleContext, name: string): R | null { if (mod) return mod as R; try { // load from cwd - const cwd = context.getCwd?.() ?? process.cwd(); + const cwd = getCwd(context); const relativeTo = path.join(cwd, '__placeholder__.js'); return (modules[name] = Module.createRequire(relativeTo)(name) as R); } catch { @@ -26,9 +27,9 @@ export function loadModule(context: RuleContext, name: string): R | null { } for (const relativeTo of [ // load from lint file name - context.getFilename(), + getFilename(context), // load from lint file name (physical) - context.getPhysicalFilename?.(), + getPhysicalFilename(context), // load from this plugin module typeof __filename !== 'undefined' ? __filename : '' ]) { diff --git a/src/utils/svelte-kit.ts b/src/utils/svelte-kit.ts index 6c9e2f234..c42be3c56 100644 --- a/src/utils/svelte-kit.ts +++ b/src/utils/svelte-kit.ts @@ -6,6 +6,7 @@ import type { RuleContext } from '../types'; import fs from 'fs'; import path from 'path'; import { getPackageJson } from './get-package-json'; +import { getFilename } from './compat'; const isRunOnBrowser = !fs.readFileSync; @@ -17,10 +18,10 @@ const isRunOnBrowser = !fs.readFileSync; export function isKitPageComponent(context: RuleContext): boolean { // Hack: if it runs on browser, it regards as SvelteKit project. if (isRunOnBrowser) return true; - if (!hasSvelteKit(context.getFilename())) return false; + if (!hasSvelteKit(getFilename(context))) return false; const routes = context.settings?.svelte?.kit?.files?.routes?.replace(/^\//, '') ?? 'src/routes'; - const filePath = context.getFilename(); - const projectRootDir = getProjectRootDir(context.getFilename()) ?? ''; + const filePath = getFilename(context); + const projectRootDir = getProjectRootDir(getFilename(context)) ?? ''; const fileName = path.basename(filePath); return ( filePath.startsWith(path.join(projectRootDir, routes)) && diff --git a/src/utils/ts-utils/index.ts b/src/utils/ts-utils/index.ts index af3bd5ab8..8f341fa81 100644 --- a/src/utils/ts-utils/index.ts +++ b/src/utils/ts-utils/index.ts @@ -1,6 +1,7 @@ import type { RuleContext, ASTNode } from '../../types'; import type * as TS from 'typescript'; import { loadModule } from '../load-module'; +import { getSourceCode } from '../compat'; export type TypeScript = typeof TS; export type { TS }; @@ -22,11 +23,12 @@ export function getTypeScriptTools(context: RuleContext): TSTools | null { if (!ts) { return null; } - const { program, esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap } = context.parserServices; + const sourceCode = getSourceCode(context); + const { program, esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap } = sourceCode.parserServices; if (!program || !esTreeNodeToTSNodeMap || !tsNodeToESTreeNodeMap) { return null; } - const hasFullTypeInformation = context.parserServices.hasFullTypeInformation ?? true; + const hasFullTypeInformation = sourceCode.parserServices.hasFullTypeInformation ?? true; if (!hasFullTypeInformation) { // Full type information is required. User must specify parserOptions.project.