From 470ef6cd1ef4767528ff15b5fbdfec1740a5ec02 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Wed, 22 Nov 2023 09:43:26 +0900 Subject: [PATCH] feat: add support for `{@snippet}`and `{@render}` in indent rule (#622) --- .changeset/calm-fans-refuse.md | 5 +++ .eslintignore | 1 + src/rules/indent-helpers/svelte.ts | 40 +++++++++++++++++++ .../indent/invalid/snippets01-errors.yaml | 40 +++++++++++++++++++ .../indent/invalid/snippets01-input.svelte | 16 ++++++++ .../indent/invalid/snippets01-output.svelte | 16 ++++++++ .../invalid/snippets01-requirements.json | 3 ++ 7 files changed, 121 insertions(+) create mode 100644 .changeset/calm-fans-refuse.md create mode 100644 tests/fixtures/rules/indent/invalid/snippets01-errors.yaml create mode 100644 tests/fixtures/rules/indent/invalid/snippets01-input.svelte create mode 100644 tests/fixtures/rules/indent/invalid/snippets01-output.svelte create mode 100644 tests/fixtures/rules/indent/invalid/snippets01-requirements.json diff --git a/.changeset/calm-fans-refuse.md b/.changeset/calm-fans-refuse.md new file mode 100644 index 000000000..57cfe6a6c --- /dev/null +++ b/.changeset/calm-fans-refuse.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat: add support for `{@snippet}`and `{@render}` in indent rule diff --git a/.eslintignore b/.eslintignore index e895477e0..108621b22 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,6 +8,7 @@ /prettier-playground /tests/fixtures/rules/indent/invalid/ts /tests/fixtures/rules/indent/invalid/ts-v5 +/tests/fixtures/rules/indent/invalid/snippets01-input.svelte /tests/fixtures/rules/indent/valid/ /tests/fixtures/rules/no-unused-class-name/valid/invalid-style01-input.svelte /tests/fixtures/rules/no-unused-class-name/valid/unknown-lang01-input.svelte diff --git a/src/rules/indent-helpers/svelte.ts b/src/rules/indent-helpers/svelte.ts index 54350190f..910913b9a 100644 --- a/src/rules/indent-helpers/svelte.ts +++ b/src/rules/indent-helpers/svelte.ts @@ -6,6 +6,7 @@ import type { IndentContext } from './commons'; import { isBeginningOfElement } from './commons'; import { isBeginningOfLine } from './commons'; import { getFirstAndLastTokens } from './commons'; +import { isClosingParenToken, isOpeningParenToken } from '@eslint-community/eslint-utils'; type NodeListener = SvelteNodeListener; const PREFORMATTED_ELEMENT_NAMES = ['pre', 'textarea', 'template']; @@ -213,6 +214,21 @@ export function defineVisitor(context: IndentContext): NodeListener { offsets.setOffsetToken(declarationToken, 1, openToken); offsets.setOffsetToken(closeToken, 0, openToken); }, + SvelteRenderTag(node: AST.SvelteRenderTag) { + const openToken = sourceCode.getFirstToken(node); + const renderToken = sourceCode.getTokenAfter(openToken)!; + offsets.setOffsetToken(renderToken, 1, openToken); + const calleeToken = sourceCode.getFirstToken(node.callee); + offsets.setOffsetToken(calleeToken, 1, renderToken); + const leftParenToken = sourceCode.getTokenAfter(node.callee, { + filter: isOpeningParenToken, + includeComments: false + })!; + const rightParenToken = sourceCode.getTokenBefore(sourceCode.getLastToken(node)); + + offsets.setOffsetToken(leftParenToken, 1, calleeToken); + offsets.setOffsetElementList([node.argument], leftParenToken, rightParenToken, 1); + }, // ---------------------------------------------------------------------- // BLOCKS // ---------------------------------------------------------------------- @@ -462,6 +478,30 @@ export function defineVisitor(context: IndentContext): NodeListener { offsets.setOffsetToken(endAwaitToken, 1, openCloseTagToken); offsets.setOffsetToken(closeCloseTagToken, 0, openCloseTagToken); }, + SvelteSnippetBlock(node: AST.SvelteSnippetBlock) { + const [openToken, snippetToken] = sourceCode.getFirstTokens(node, { + count: 2, + includeComments: false + }); + offsets.setOffsetToken(snippetToken, 1, openToken); + const id = getFirstAndLastTokens(sourceCode, node.id); + offsets.setOffsetToken(id.firstToken, 1, snippetToken); + + const leftParenToken = sourceCode.getTokenBefore( + node.context || sourceCode.getLastToken(node), + { + filter: isOpeningParenToken, + includeComments: false + } + )!; + + const rightParenToken = sourceCode.getTokenAfter(node.context || leftParenToken, { + filter: isClosingParenToken, + includeComments: false + })!; + offsets.setOffsetToken(leftParenToken, 1, id.firstToken); + offsets.setOffsetElementList([node.context], leftParenToken, rightParenToken, 1); + }, // ---------------------------------------------------------------------- // COMMENTS // ---------------------------------------------------------------------- diff --git a/tests/fixtures/rules/indent/invalid/snippets01-errors.yaml b/tests/fixtures/rules/indent/invalid/snippets01-errors.yaml new file mode 100644 index 000000000..0e010e0be --- /dev/null +++ b/tests/fixtures/rules/indent/invalid/snippets01-errors.yaml @@ -0,0 +1,40 @@ +- message: Expected indentation of 2 spaces but found 0 spaces. + line: 3 + column: 1 + suggestions: null +- message: Expected indentation of 4 spaces but found 0 spaces. + line: 4 + column: 1 + suggestions: null +- message: Expected indentation of 6 spaces but found 0 spaces. + line: 5 + column: 1 + suggestions: null +- message: Expected indentation of 4 spaces but found 0 spaces. + line: 6 + column: 1 + suggestions: null +- message: Expected indentation of 2 spaces but found 0 spaces. + line: 7 + column: 1 + suggestions: null +- message: Expected indentation of 2 spaces but found 0 spaces. + line: 11 + column: 1 + suggestions: null +- message: Expected indentation of 4 spaces but found 0 spaces. + line: 12 + column: 1 + suggestions: null +- message: Expected indentation of 6 spaces but found 0 spaces. + line: 13 + column: 1 + suggestions: null +- message: Expected indentation of 4 spaces but found 0 spaces. + line: 14 + column: 1 + suggestions: null +- message: Expected indentation of 2 spaces but found 0 spaces. + line: 15 + column: 1 + suggestions: null diff --git a/tests/fixtures/rules/indent/invalid/snippets01-input.svelte b/tests/fixtures/rules/indent/invalid/snippets01-input.svelte new file mode 100644 index 000000000..e86807d17 --- /dev/null +++ b/tests/fixtures/rules/indent/invalid/snippets01-input.svelte @@ -0,0 +1,16 @@ + +{#snippet +foo( +{ +a +} +) +} +{/snippet} +{@render +foo( +{ +a +} +) +} diff --git a/tests/fixtures/rules/indent/invalid/snippets01-output.svelte b/tests/fixtures/rules/indent/invalid/snippets01-output.svelte new file mode 100644 index 000000000..e07895e54 --- /dev/null +++ b/tests/fixtures/rules/indent/invalid/snippets01-output.svelte @@ -0,0 +1,16 @@ + +{#snippet + foo( + { + a + } + ) +} +{/snippet} +{@render + foo( + { + a + } + ) +} diff --git a/tests/fixtures/rules/indent/invalid/snippets01-requirements.json b/tests/fixtures/rules/indent/invalid/snippets01-requirements.json new file mode 100644 index 000000000..0192b1098 --- /dev/null +++ b/tests/fixtures/rules/indent/invalid/snippets01-requirements.json @@ -0,0 +1,3 @@ +{ + "svelte": ">=5.0.0-0" +}