eslint-plugin-svelte 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/lib/main.d.ts +1 -1
  2. package/lib/meta.d.ts +1 -1
  3. package/lib/meta.js +1 -1
  4. package/lib/rule-types.d.ts +1 -0
  5. package/lib/rules/@typescript-eslint/no-unnecessary-condition.js +1 -2
  6. package/lib/rules/block-lang.js +3 -4
  7. package/lib/rules/comment-directive.js +2 -3
  8. package/lib/rules/consistent-selector-style.js +1 -2
  9. package/lib/rules/first-attribute-linebreak.js +1 -2
  10. package/lib/rules/html-closing-bracket-new-line.js +1 -2
  11. package/lib/rules/html-closing-bracket-spacing.js +1 -1
  12. package/lib/rules/html-quotes.js +1 -2
  13. package/lib/rules/html-self-closing.js +1 -2
  14. package/lib/rules/indent-helpers/index.js +2 -3
  15. package/lib/rules/infinite-reactive-loop.js +3 -4
  16. package/lib/rules/max-attributes-per-line.js +1 -2
  17. package/lib/rules/mustache-spacing.js +1 -2
  18. package/lib/rules/no-dupe-else-if-blocks.js +1 -2
  19. package/lib/rules/no-dupe-on-directives.js +1 -2
  20. package/lib/rules/no-dupe-use-directives.js +1 -2
  21. package/lib/rules/no-dynamic-slot-name.js +1 -2
  22. package/lib/rules/no-extra-reactive-curlies.js +1 -2
  23. package/lib/rules/no-goto-without-base.js +1 -2
  24. package/lib/rules/no-immutable-reactive-statements.js +1 -2
  25. package/lib/rules/no-navigation-without-base.js +1 -2
  26. package/lib/rules/no-reactive-functions.js +1 -2
  27. package/lib/rules/no-reactive-literals.js +1 -2
  28. package/lib/rules/no-reactive-reassign.js +1 -2
  29. package/lib/rules/no-spaces-around-equal-signs-in-attribute.js +1 -1
  30. package/lib/rules/no-trailing-spaces.js +1 -2
  31. package/lib/rules/no-unnecessary-state-wrap.js +10 -5
  32. package/lib/rules/no-unused-class-name.js +1 -2
  33. package/lib/rules/no-unused-props.js +27 -10
  34. package/lib/rules/no-unused-svelte-ignore.js +1 -2
  35. package/lib/rules/no-useless-mustaches.js +1 -2
  36. package/lib/rules/prefer-class-directive.js +1 -2
  37. package/lib/rules/prefer-destructured-store-props.js +2 -3
  38. package/lib/rules/prefer-style-directive.js +1 -2
  39. package/lib/rules/reference-helpers/svelte-store.js +1 -2
  40. package/lib/rules/require-event-dispatcher-types.js +1 -2
  41. package/lib/rules/require-store-callbacks-use-set-param.js +1 -2
  42. package/lib/rules/require-store-reactive-access.js +1 -2
  43. package/lib/rules/shorthand-attribute.js +1 -2
  44. package/lib/rules/shorthand-directive.js +1 -2
  45. package/lib/rules/sort-attributes.js +1 -2
  46. package/lib/rules/system.js +1 -2
  47. package/lib/rules/valid-compile.js +1 -2
  48. package/lib/rules/valid-style-parse.js +2 -3
  49. package/lib/shared/svelte-compile-warns/extract-leading-comments.js +1 -2
  50. package/lib/shared/svelte-compile-warns/ignore-comment.js +1 -2
  51. package/lib/shared/svelte-compile-warns/index.js +10 -11
  52. package/lib/shared/svelte-compile-warns/transform/babel.js +1 -2
  53. package/lib/shared/svelte-compile-warns/transform/less.js +1 -2
  54. package/lib/shared/svelte-compile-warns/transform/postcss.js +2 -3
  55. package/lib/shared/svelte-compile-warns/transform/stylus.js +1 -2
  56. package/lib/shared/svelte-compile-warns/transform/typescript.js +1 -2
  57. package/lib/types.d.ts +4 -4
  58. package/lib/utils/ast-utils.js +2 -3
  59. package/lib/utils/css-utils/style-attribute.js +4 -5
  60. package/lib/utils/load-module.js +4 -5
  61. package/lib/utils/svelte-context.js +5 -6
  62. package/lib/utils/ts-utils/index.js +1 -2
  63. package/package.json +1 -1
  64. package/lib/utils/compat.d.ts +0 -22
  65. package/lib/utils/compat.js +0 -32
package/lib/main.d.ts CHANGED
@@ -14,7 +14,7 @@ export declare const configs: {
14
14
  export declare const rules: Record<string, Rule.RuleModule>;
15
15
  export declare const meta: {
16
16
  name: "eslint-plugin-svelte";
17
- version: "3.4.0";
17
+ version: "3.5.0";
18
18
  };
19
19
  export declare const processors: {
20
20
  '.svelte': typeof processor;
package/lib/meta.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare const name = "eslint-plugin-svelte";
2
- export declare const version = "3.4.0";
2
+ export declare const version = "3.5.0";
package/lib/meta.js CHANGED
@@ -2,4 +2,4 @@
2
2
  // This file has been automatically generated,
3
3
  // in order to update its content execute "pnpm run update"
4
4
  export const name = 'eslint-plugin-svelte';
5
- export const version = '3.4.0';
5
+ export const version = '3.5.0';
@@ -547,6 +547,7 @@ type SvelteNoUnusedProps = [] | [
547
547
  checkImportedTypes?: boolean;
548
548
  ignoreTypePatterns?: string[];
549
549
  ignorePropertyPatterns?: string[];
550
+ allowUnusedNestedProperties?: boolean;
550
551
  }
551
552
  ];
552
553
  type SvelteNoUselessMustaches = [] | [
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../../utils/index.js';
2
2
  import { isFalsyType, getConstrainedTypeAtLocation, isTruthyLiteral, isPossiblyFalsyType, isNullishType, isBooleanLiteralType, getTypeScriptTools, isAnyType, isUnknownType, isNeverType, getCallSignaturesOfType, isNullableType, getTypeOfPropertyOfType, getTypeName, isTupleType } from '../../utils/ts-utils/index.js';
3
- import { getSourceCode } from '../../utils/compat.js';
4
3
  /**
5
4
  * Returns all types of a union type or an array containing `type` itself if it's no union type.
6
5
  * This method is heavily inspired by tsutils. https://github.com/ajafff/tsutils
@@ -112,7 +111,7 @@ export default createRule('@typescript-eslint/no-unnecessary-condition', {
112
111
  }
113
112
  const { service, ts } = tools;
114
113
  const checker = service.program.getTypeChecker();
115
- const sourceCode = getSourceCode(context);
114
+ const sourceCode = context.sourceCode;
116
115
  const compilerOptions = service.program.getCompilerOptions();
117
116
  const isStrictNullChecks = compilerOptions.strict
118
117
  ? compilerOptions.strictNullChecks !== false
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { findAttribute, getLangValue } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('block-lang', {
5
4
  meta: {
6
5
  docs: {
@@ -55,7 +54,7 @@ export default createRule('block-lang', {
55
54
  hasSuggestions: true
56
55
  },
57
56
  create(context) {
58
- if (!getSourceCode(context).parserServices.isSvelte) {
57
+ if (!context.sourceCode.parserServices.isSvelte) {
59
58
  return {};
60
59
  }
61
60
  const enforceScriptPresent = context.options[0]?.enforceScriptPresent ?? false;
@@ -82,7 +81,7 @@ export default createRule('block-lang', {
82
81
  context.report({
83
82
  loc: { line: 1, column: 1 },
84
83
  message: `The <script> block should be present and its lang attribute should be ${prettyPrintLangs(allowedScriptLangs)}.`,
85
- suggest: buildAddLangSuggestions(allowedScriptLangs, 'script', getSourceCode(context))
84
+ suggest: buildAddLangSuggestions(allowedScriptLangs, 'script', context.sourceCode)
86
85
  });
87
86
  }
88
87
  for (const scriptNode of scriptNodes) {
@@ -95,7 +94,7 @@ export default createRule('block-lang', {
95
94
  }
96
95
  }
97
96
  if (styleNodes.length === 0 && enforceStylePresent) {
98
- const sourceCode = getSourceCode(context);
97
+ const sourceCode = context.sourceCode;
99
98
  context.report({
100
99
  loc: { line: 1, column: 1 },
101
100
  message: `The <style> block should be present and its lang attribute should be ${prettyPrintLangs(allowedStyleLangs)}.`,
@@ -1,6 +1,5 @@
1
1
  import { getShared } from '../shared/index.js';
2
2
  import { createRule } from '../utils/index.js';
3
- import { getFilename, getSourceCode } from '../utils/compat.js';
4
3
  // -----------------------------------------------------------------------------
5
4
  // Helpers
6
5
  // -----------------------------------------------------------------------------
@@ -43,7 +42,7 @@ export default createRule('comment-directive', {
43
42
  type: 'problem'
44
43
  },
45
44
  create(context) {
46
- const shared = getShared(getFilename(context));
45
+ const shared = getShared(context.filename);
47
46
  if (!shared)
48
47
  return {};
49
48
  const options = context.options[0] || {};
@@ -52,7 +51,7 @@ export default createRule('comment-directive', {
52
51
  ruleId: 'svelte/comment-directive',
53
52
  reportUnusedDisableDirectives
54
53
  });
55
- const sourceCode = getSourceCode(context);
54
+ const sourceCode = context.sourceCode;
56
55
  /**
57
56
  * Parse a given comment.
58
57
  */
@@ -1,5 +1,4 @@
1
1
  import { findClassesInAttribute } from '../utils/ast-utils.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  import { createRule } from '../utils/index.js';
4
3
  export default createRule('consistent-selector-style', {
5
4
  meta: {
@@ -39,7 +38,7 @@ export default createRule('consistent-selector-style', {
39
38
  type: 'suggestion'
40
39
  },
41
40
  create(context) {
42
- const sourceCode = getSourceCode(context);
41
+ const sourceCode = context.sourceCode;
43
42
  if (!sourceCode.parserServices.isSvelte ||
44
43
  sourceCode.parserServices.getStyleSelectorAST === undefined ||
45
44
  sourceCode.parserServices.styleSelectorNodeLoc === undefined) {
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  export default createRule('first-attribute-linebreak', {
4
3
  meta: {
5
4
  docs: {
@@ -28,7 +27,7 @@ export default createRule('first-attribute-linebreak', {
28
27
  create(context) {
29
28
  const multiline = context.options[0]?.multiline || 'below';
30
29
  const singleline = context.options[0]?.singleline || 'beside';
31
- const sourceCode = getSourceCode(context);
30
+ const sourceCode = context.sourceCode;
32
31
  /**
33
32
  * Report attribute
34
33
  */
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  function getPhrase(lineBreaks) {
4
3
  switch (lineBreaks) {
5
4
  case 0: {
@@ -80,7 +79,7 @@ export default createRule('html-closing-bracket-new-line', {
80
79
  const options = { ...(context.options[0] ?? {}) };
81
80
  options.singleline ?? (options.singleline = 'never');
82
81
  options.multiline ?? (options.multiline = 'always');
83
- const sourceCode = getSourceCode(context);
82
+ const sourceCode = context.sourceCode;
84
83
  return {
85
84
  'SvelteStartTag, SvelteEndTag'(node) {
86
85
  const data = node.type === 'SvelteStartTag' && node.selfClosing
@@ -38,7 +38,7 @@ export default createRule('html-closing-bracket-spacing', {
38
38
  selfClosingTag: 'always',
39
39
  ...ctx.options[0]
40
40
  };
41
- const src = ctx.getSourceCode();
41
+ const src = ctx.sourceCode;
42
42
  /**
43
43
  * Returns true if string contains newline characters
44
44
  */
@@ -1,7 +1,6 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { getMustacheTokens } from '../utils/ast-utils.js';
3
3
  import { getAttributeValueQuoteAndRange } from '../utils/ast-utils.js';
4
- import { getSourceCode } from '../utils/compat.js';
5
4
  const QUOTE_CHARS = {
6
5
  double: '"',
7
6
  single: "'"
@@ -45,7 +44,7 @@ export default createRule('html-quotes', {
45
44
  type: 'layout' // "problem",
46
45
  },
47
46
  create(context) {
48
- const sourceCode = getSourceCode(context);
47
+ const sourceCode = context.sourceCode;
49
48
  const preferQuote = context.options[0]?.prefer ?? 'double';
50
49
  const dynamicQuote = context.options[0]?.dynamic?.quoted ? preferQuote : 'unquoted';
51
50
  const avoidInvalidUnquotedInHTML = Boolean(context.options[0]?.dynamic?.avoidInvalidUnquotedInHTML);
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { getNodeName, isVoidHtmlElement, isSvgElement, isMathMLElement } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  const TYPE_MESSAGES = {
5
4
  normal: 'HTML elements',
6
5
  void: 'HTML void elements',
@@ -149,7 +148,7 @@ export default createRule('html-self-closing', {
149
148
  context.report({
150
149
  node,
151
150
  loc: {
152
- start: getSourceCode(context).getLocFromIndex(node.startTag.range[1] - (node.startTag.selfClosing ? 2 : 1)),
151
+ start: context.sourceCode.getLocFromIndex(node.startTag.range[1] - (node.startTag.selfClosing ? 2 : 1)),
153
152
  end: node.loc.end
154
153
  },
155
154
  messageId: shouldBeClosed ? 'requireClosing' : 'disallowClosing',
@@ -4,7 +4,6 @@ import * as TS from './ts.js';
4
4
  import { isNotWhitespace } from './ast.js';
5
5
  import { isCommentToken } from '@eslint-community/eslint-utils';
6
6
  import { OffsetContext } from './offset-context.js';
7
- import { getFilename, getSourceCode } from '../../utils/compat.js';
8
7
  /**
9
8
  * Normalize options.
10
9
  * @param type The type of indentation.
@@ -54,10 +53,10 @@ function parseOptions(options, defaultOptions) {
54
53
  * @returns AST event handlers.
55
54
  */
56
55
  export function defineVisitor(context, defaultOptions) {
57
- if (!getFilename(context).endsWith('.svelte'))
56
+ if (!context.filename.endsWith('.svelte'))
58
57
  return {};
59
58
  const options = parseOptions(context.options[0] || {}, defaultOptions);
60
- const sourceCode = getSourceCode(context);
59
+ const sourceCode = context.sourceCode;
61
60
  const offsets = new OffsetContext({ sourceCode, options });
62
61
  /**
63
62
  * Get the text of the indentation part of the given location.
@@ -2,12 +2,11 @@ import { ReferenceTracker } from '@eslint-community/eslint-utils';
2
2
  import { createRule } from '../utils/index.js';
3
3
  import { findVariable } from '../utils/ast-utils.js';
4
4
  import { traverseNodes } from 'svelte-eslint-parser';
5
- import { getSourceCode } from '../utils/compat.js';
6
5
  /**
7
6
  * Get usage of `tick`
8
7
  */
9
8
  function extractTickReferences(context) {
10
- const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope);
9
+ const referenceTracker = new ReferenceTracker(context.sourceCode.scopeManager.globalScope);
11
10
  const a = referenceTracker.iterateEsmReferences({
12
11
  svelte: {
13
12
  [ReferenceTracker.ESM]: true,
@@ -27,7 +26,7 @@ function extractTickReferences(context) {
27
26
  * Get usage of `setTimeout`, `setInterval`, `queueMicrotask`
28
27
  */
29
28
  function extractTaskReferences(context) {
30
- const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope);
29
+ const referenceTracker = new ReferenceTracker(context.sourceCode.scopeManager.globalScope);
31
30
  const a = referenceTracker.iterateGlobalReferences({
32
31
  setTimeout: { [ReferenceTracker.CALL]: true },
33
32
  setInterval: { [ReferenceTracker.CALL]: true },
@@ -106,7 +105,7 @@ function isPromiseThenOrCatchBody(node) {
106
105
  * Get all reactive variable reference.
107
106
  */
108
107
  function getReactiveVariableReferences(context) {
109
- const scopeManager = getSourceCode(context).scopeManager;
108
+ const scopeManager = context.sourceCode.scopeManager;
110
109
  // Find the top-level (module or global) scope.
111
110
  // Any variable defined at the top-level (module scope or global scope) can be made reactive.
112
111
  const toplevelScope = scopeManager.globalScope?.childScopes.find((scope) => scope.type === 'module') ||
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  /**
4
3
  * Check whether the component is declared in a single line or not.
5
4
  */
@@ -54,7 +53,7 @@ export default createRule('max-attributes-per-line', {
54
53
  create(context) {
55
54
  const multilineMaximum = context.options[0]?.multiline ?? 1;
56
55
  const singlelineMaximum = context.options[0]?.singleline ?? 1;
57
- const sourceCode = getSourceCode(context);
56
+ const sourceCode = context.sourceCode;
58
57
  /**
59
58
  * Report attributes
60
59
  */
@@ -1,7 +1,6 @@
1
1
  import { isClosingBraceToken, isOpeningBraceToken } from '@eslint-community/eslint-utils';
2
2
  import { createRule } from '../utils/index.js';
3
3
  import { getMustacheTokens } from '../utils/ast-utils.js';
4
- import { getSourceCode } from '../utils/compat.js';
5
4
  const VALUE_SCHEMA = { enum: ['never', 'always'] };
6
5
  /**
7
6
  * Normalize options.
@@ -57,7 +56,7 @@ export default createRule('mustache-spacing', {
57
56
  },
58
57
  create(context) {
59
58
  const options = parseOptions(context.options[0]);
60
- const sourceCode = getSourceCode(context);
59
+ const sourceCode = context.sourceCode;
61
60
  /** Verify */
62
61
  function verifyBraces(openingBrace, closingBrace, openingOption, closingOption, hasExpression) {
63
62
  const firstToken = sourceCode.getTokenAfter(openingBrace, {
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { equalTokens } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  /**
5
4
  * Splits the given node by the given logical operator.
6
5
  * @param operator Logical operator `||` or `&&`.
@@ -58,7 +57,7 @@ export default createRule('no-dupe-else-if-blocks', {
58
57
  type: 'problem' // "problem",
59
58
  },
60
59
  create(context) {
61
- const sourceCode = getSourceCode(context);
60
+ const sourceCode = context.sourceCode;
62
61
  /**
63
62
  * Determines whether the two given nodes are considered to be equal. In particular, given that the nodes
64
63
  * represent expressions in a boolean context, `||` and `&&` can be considered as commutative operators.
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { equalTokens } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-dupe-on-directives', {
5
4
  meta: {
6
5
  docs: {
@@ -15,7 +14,7 @@ export default createRule('no-dupe-on-directives', {
15
14
  type: 'problem'
16
15
  },
17
16
  create(context) {
18
- const sourceCode = getSourceCode(context);
17
+ const sourceCode = context.sourceCode;
19
18
  const directiveDataMap = new Map();
20
19
  return {
21
20
  SvelteDirective(node) {
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { equalTokens, getAttributeKeyText } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-dupe-use-directives', {
5
4
  meta: {
6
5
  docs: {
@@ -15,7 +14,7 @@ export default createRule('no-dupe-use-directives', {
15
14
  type: 'problem'
16
15
  },
17
16
  create(context) {
18
- const sourceCode = getSourceCode(context);
17
+ const sourceCode = context.sourceCode;
19
18
  const directiveDataMap = new Map();
20
19
  return {
21
20
  SvelteDirective(node) {
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { findVariable, getAttributeValueQuoteAndRange, getStringIfConstant } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-dynamic-slot-name', {
5
4
  meta: {
6
5
  docs: {
@@ -21,7 +20,7 @@ export default createRule('no-dynamic-slot-name', {
21
20
  }
22
21
  },
23
22
  create(context) {
24
- const sourceCode = getSourceCode(context);
23
+ const sourceCode = context.sourceCode;
25
24
  return {
26
25
  "SvelteElement[name.name='slot'] > SvelteStartTag.startTag > SvelteAttribute[key.name='name']"(node) {
27
26
  if (node.value.length === 0) {
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  export default createRule('no-extra-reactive-curlies', {
4
3
  meta: {
5
4
  docs: {
@@ -20,7 +19,7 @@ export default createRule('no-extra-reactive-curlies', {
20
19
  return {
21
20
  // $: { foo = "bar"; }
22
21
  [`SvelteReactiveStatement > BlockStatement[body.length=1]`]: (node) => {
23
- const source = getSourceCode(context);
22
+ const source = context.sourceCode;
24
23
  return context.report({
25
24
  node,
26
25
  loc: node.loc,
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { ReferenceTracker } from '@eslint-community/eslint-utils';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  import { findVariable } from '../utils/ast-utils.js';
5
4
  export default createRule('no-goto-without-base', {
6
5
  meta: {
@@ -20,7 +19,7 @@ export default createRule('no-goto-without-base', {
20
19
  create(context) {
21
20
  return {
22
21
  Program() {
23
- const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope);
22
+ const referenceTracker = new ReferenceTracker(context.sourceCode.scopeManager.globalScope);
24
23
  const basePathNames = extractBasePathReferences(referenceTracker, context);
25
24
  for (const gotoCall of extractGotoReferences(referenceTracker)) {
26
25
  if (gotoCall.arguments.length < 1) {
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { findVariable, iterateIdentifiers } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-immutable-reactive-statements', {
5
4
  meta: {
6
5
  docs: {
@@ -15,7 +14,7 @@ export default createRule('no-immutable-reactive-statements', {
15
14
  type: 'suggestion'
16
15
  },
17
16
  create(context) {
18
- const scopeManager = getSourceCode(context).scopeManager;
17
+ const scopeManager = context.sourceCode.scopeManager;
19
18
  const globalScope = scopeManager.globalScope;
20
19
  const toplevelScope = globalScope?.childScopes.find((scope) => scope.type === 'module') || globalScope;
21
20
  if (!globalScope || !toplevelScope) {
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { ReferenceTracker } from '@eslint-community/eslint-utils';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  import { findVariable } from '../utils/ast-utils.js';
5
4
  export default createRule('no-navigation-without-base', {
6
5
  meta: {
@@ -41,7 +40,7 @@ export default createRule('no-navigation-without-base', {
41
40
  let basePathNames = new Set();
42
41
  return {
43
42
  Program() {
44
- const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope);
43
+ const referenceTracker = new ReferenceTracker(context.sourceCode.scopeManager.globalScope);
45
44
  basePathNames = extractBasePathReferences(referenceTracker, context);
46
45
  const { goto: gotoCalls, pushState: pushStateCalls, replaceState: replaceStateCalls } = extractFunctionCallReferences(referenceTracker);
47
46
  if (context.options[0]?.ignoreGoto !== true) {
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  export default createRule('no-reactive-functions', {
4
3
  meta: {
5
4
  docs: {
@@ -33,7 +32,7 @@ export default createRule('no-reactive-functions', {
33
32
  if (!parent) {
34
33
  return false;
35
34
  }
36
- const source = getSourceCode(context);
35
+ const source = context.sourceCode;
37
36
  return context.report({
38
37
  node: parent,
39
38
  loc: parent.loc,
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  export default createRule('no-reactive-literals', {
4
3
  meta: {
5
4
  docs: {
@@ -40,7 +39,7 @@ export default createRule('no-reactive-literals', {
40
39
  if (!parent) {
41
40
  return false;
42
41
  }
43
- const source = getSourceCode(context);
42
+ const source = context.sourceCode;
44
43
  return context.report({
45
44
  node: parent,
46
45
  loc: parent.loc,
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { getPropertyName } from '@eslint-community/eslint-utils';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-reactive-reassign', {
5
4
  meta: {
6
5
  docs: {
@@ -36,7 +35,7 @@ export default createRule('no-reactive-reassign', {
36
35
  },
37
36
  create(context) {
38
37
  const props = context.options[0]?.props !== false; // default true
39
- const sourceCode = getSourceCode(context);
38
+ const sourceCode = context.sourceCode;
40
39
  const scopeManager = sourceCode.scopeManager;
41
40
  const globalScope = scopeManager.globalScope;
42
41
  const toplevelScope = globalScope?.childScopes.find((scope) => scope.type === 'module') || globalScope;
@@ -15,7 +15,7 @@ export default createRule('no-spaces-around-equal-signs-in-attribute', {
15
15
  type: 'layout'
16
16
  },
17
17
  create(ctx) {
18
- const source = ctx.getSourceCode();
18
+ const source = ctx.sourceCode;
19
19
  /**
20
20
  * Returns source text between attribute key and value, and range of that source
21
21
  */
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  export default createRule('no-trailing-spaces', {
4
3
  meta: {
5
4
  type: 'layout',
@@ -29,7 +28,7 @@ export default createRule('no-trailing-spaces', {
29
28
  const options = context.options[0];
30
29
  const skipBlankLines = options?.skipBlankLines || false;
31
30
  const ignoreComments = options?.ignoreComments || false;
32
- const sourceCode = getSourceCode(context);
31
+ const sourceCode = context.sourceCode;
33
32
  const ignoreLineNumbers = new Set();
34
33
  if (ignoreComments) {
35
34
  for (const { type, loc } of sourceCode.getAllComments()) {
@@ -1,5 +1,4 @@
1
1
  import { createRule } from '../utils/index.js';
2
- import { getSourceCode } from '../utils/compat.js';
3
2
  import { ReferenceTracker } from '@eslint-community/eslint-utils';
4
3
  const REACTIVE_CLASSES = [
5
4
  'SvelteSet',
@@ -51,7 +50,11 @@ export default createRule('no-unnecessary-state-wrap', {
51
50
  const options = context.options[0] ?? {};
52
51
  const additionalReactiveClasses = options.additionalReactiveClasses ?? [];
53
52
  const allowReassign = options.allowReassign ?? false;
54
- const referenceTracker = new ReferenceTracker(getSourceCode(context).scopeManager.globalScope);
53
+ const { globalScope } = context.sourceCode.scopeManager;
54
+ if (globalScope == null) {
55
+ return {};
56
+ }
57
+ const referenceTracker = new ReferenceTracker(globalScope);
55
58
  const traceMap = {};
56
59
  for (const reactiveClass of REACTIVE_CLASSES) {
57
60
  traceMap[reactiveClass] = {
@@ -73,8 +76,10 @@ export default createRule('no-unnecessary-state-wrap', {
73
76
  };
74
77
  });
75
78
  function isReassigned(identifier) {
76
- const variable = getSourceCode(context).scopeManager.getDeclaredVariables(identifier.parent)[0];
77
- return variable.references.some((ref) => {
79
+ const references = context.sourceCode.scopeManager
80
+ .getDeclaredVariables(identifier.parent)
81
+ .flatMap((v) => v.references);
82
+ return references.some((ref) => {
78
83
  return ref.isWrite() && ref.identifier !== identifier;
79
84
  });
80
85
  }
@@ -92,7 +97,7 @@ export default createRule('no-unnecessary-state-wrap', {
92
97
  {
93
98
  messageId: 'suggestRemoveStateWrap',
94
99
  fix(fixer) {
95
- return fixer.replaceText(stateNode, getSourceCode(context).getText(targetNode));
100
+ return fixer.replaceText(stateNode, context.sourceCode.getText(targetNode));
96
101
  }
97
102
  }
98
103
  ]
@@ -1,6 +1,5 @@
1
1
  import { createRule } from '../utils/index.js';
2
2
  import { findClassesInAttribute } from '../utils/ast-utils.js';
3
- import { getSourceCode } from '../utils/compat.js';
4
3
  export default createRule('no-unused-class-name', {
5
4
  meta: {
6
5
  docs: {
@@ -26,7 +25,7 @@ export default createRule('no-unused-class-name', {
26
25
  type: 'suggestion'
27
26
  },
28
27
  create(context) {
29
- const sourceCode = getSourceCode(context);
28
+ const sourceCode = context.sourceCode;
30
29
  if (!sourceCode.parserServices.isSvelte) {
31
30
  return {};
32
31
  }
@@ -2,7 +2,6 @@ import { createRule } from '../utils/index.js';
2
2
  import { getTypeScriptTools } from '../utils/ts-utils/index.js';
3
3
  import { findVariable } from '../utils/ast-utils.js';
4
4
  import { toRegExp } from '../utils/regexp.js';
5
- import { getFilename } from '../utils/compat.js';
6
5
  let isRemovedWarningShown = false;
7
6
  export default createRule('no-unused-props', {
8
7
  meta: {
@@ -32,6 +31,10 @@ export default createRule('no-unused-props', {
32
31
  type: 'string'
33
32
  },
34
33
  default: []
34
+ },
35
+ allowUnusedNestedProperties: {
36
+ type: 'boolean',
37
+ default: false
35
38
  }
36
39
  },
37
40
  additionalProperties: false
@@ -51,7 +54,7 @@ export default createRule('no-unused-props', {
51
54
  ]
52
55
  },
53
56
  create(context) {
54
- const fileName = getFilename(context);
57
+ const fileName = context.filename;
55
58
  const tools = getTypeScriptTools(context);
56
59
  if (!tools) {
57
60
  return {};
@@ -160,8 +163,15 @@ export default createRule('no-unused-props', {
160
163
  function getUsedPropertyNamesFromPattern(pattern) {
161
164
  const usedProps = new Set();
162
165
  for (const prop of pattern.properties) {
163
- if (prop.type === 'Property' && prop.key.type === 'Identifier') {
164
- usedProps.add(prop.key.name);
166
+ if (prop.type === 'Property') {
167
+ if (prop.key.type === 'Identifier') {
168
+ usedProps.add({ originalName: prop.key.name, aliasName: prop.key.name });
169
+ }
170
+ else if (prop.key.type === 'Literal' &&
171
+ typeof prop.key.value === 'string' &&
172
+ prop.value.type === 'Identifier') {
173
+ usedProps.add({ originalName: prop.key.value, aliasName: prop.value.name });
174
+ }
165
175
  }
166
176
  else if (prop.type === 'RestElement') {
167
177
  // If there's a rest element, all properties are potentially used
@@ -240,7 +250,9 @@ export default createRule('no-unused-props', {
240
250
  if (isUsedThisInPath && !isUsedInPath) {
241
251
  continue;
242
252
  }
243
- const isUsedInProps = declaredPropertyNames.has(propName);
253
+ const isUsedInProps = Array.from(declaredPropertyNames).some((p) => {
254
+ return p.originalName === propName;
255
+ });
244
256
  if (!isUsedInPath && !isUsedInProps) {
245
257
  reportedPropertyPaths.add(currentPathStr);
246
258
  context.report({
@@ -285,10 +297,10 @@ export default createRule('no-unused-props', {
285
297
  * Returns true if the destructuring pattern includes a rest element,
286
298
  * which means all remaining properties are potentially used.
287
299
  */
288
- function hasRestElement(usedProps) {
289
- return usedProps.size === 0;
300
+ function hasRestElement(declaredPropertyNames) {
301
+ return declaredPropertyNames.size === 0;
290
302
  }
291
- function normalizeUsedPaths(paths) {
303
+ function normalizeUsedPaths(paths, allowUnusedNestedProperties) {
292
304
  const normalized = [];
293
305
  for (const path of paths.sort((a, b) => a.length - b.length)) {
294
306
  if (path.length === 0)
@@ -298,7 +310,12 @@ export default createRule('no-unused-props', {
298
310
  }
299
311
  normalized.push(path);
300
312
  }
301
- return normalized;
313
+ return normalized.map((path) => {
314
+ // If we allow unused nested properties, only return first level properties
315
+ if (allowUnusedNestedProperties)
316
+ return [path[0]];
317
+ return path;
318
+ });
302
319
  }
303
320
  return {
304
321
  'VariableDeclaration > VariableDeclarator': (node) => {
@@ -340,7 +357,7 @@ export default createRule('no-unused-props', {
340
357
  }
341
358
  checkUnusedProperties({
342
359
  propsType,
343
- usedPropertyPaths: normalizeUsedPaths(usedPropertyPathsArray).map((pathArray) => {
360
+ usedPropertyPaths: normalizeUsedPaths(usedPropertyPathsArray, options.allowUnusedNestedProperties).map((pathArray) => {
344
361
  return pathArray.join('.');
345
362
  }),
346
363
  declaredPropertyNames,