diff --git a/packages/svelte/src/compiler/phases/1-parse/index.js b/packages/svelte/src/compiler/phases/1-parse/index.js index 08c6d90e87..de959ba755 100644 --- a/packages/svelte/src/compiler/phases/1-parse/index.js +++ b/packages/svelte/src/compiler/phases/1-parse/index.js @@ -322,7 +322,9 @@ class Finish { case 'HtmlTag': this.expression(node, node.expression); return; - case 'RenderTag': + case 'RenderTag': { + const call = node.expression.type === 'ChainExpression' ? node.expression.expression : node.expression; + if (call.type !== 'CallExpression') e.render_tag_invalid_expression(node.expression); this.expression(node, node.expression); node.metadata = { ...node.metadata, @@ -332,6 +334,7 @@ class Finish { snippets: new Set() }; return; + } case 'ConstTag': case 'DeclarationTag': this.expression(node, node.declaration); @@ -591,7 +594,10 @@ function throw_error(error, template) { } // a branch that fits no open block, reported at its sigil if (what === 'else') e.expected_token(pos + 1, '{:else}'); - if (what === 'else if or else') e.expected_token(pos + 1, '{:else} or {:else if}'); + if (what === 'else if or else') { + if (template.startsWith('{:elseif', pos)) e.block_invalid_elseif(pos + 1); + e.expected_token(pos + 1, '{:else} or {:else if}'); + } if (what === 'then or catch') e.expected_token(pos + 1, '{:then ...} or {:catch ...}'); if (what === 'a block name') e.expected_block_type(pos); if (what === 'an attribute value') e.expected_attribute_value(pos); @@ -638,6 +644,7 @@ function throw_error(error, template) { if (name === 'script') e.script_duplicate(pos); if (name === 'style') e.style_duplicate(pos); if (name.startsWith('svelte:')) e.svelte_meta_duplicate(pos, name); + if (name.startsWith('{:')) e.block_duplicate_clause(pos + 1, name); e.attribute_duplicate(range); } // eslint-disable-next-line no-fallthrough diff --git a/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/_config.js b/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/_config.js new file mode 100644 index 0000000000..d205dd9756 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'block_duplicate_clause', + message: '{:then} cannot appear more than once within a block', + position: [43, 43] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/main.svelte b/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/main.svelte new file mode 100644 index 0000000000..c70d8c396a --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/block-duplicate-clause/main.svelte @@ -0,0 +1 @@ +{#await p}{:then x}{:then y}{/await} diff --git a/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/_config.js b/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/_config.js new file mode 100644 index 0000000000..cc331c2e28 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'block_invalid_elseif', + message: "'elseif' should be 'else if'", + position: [34, 34] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/main.svelte b/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/main.svelte new file mode 100644 index 0000000000..c50f7ae130 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/block-invalid-elseif/main.svelte @@ -0,0 +1 @@ +{#if x}{:elseif y}{/if} diff --git a/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/_config.js b/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/_config.js new file mode 100644 index 0000000000..0d49bfdcbd --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'render_tag_invalid_expression', + message: '`{@render ...}` tags can only contain call expressions', + position: [34, 37] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/main.svelte b/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/main.svelte new file mode 100644 index 0000000000..16383aa6be --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/render-tag-invalid-expression/main.svelte @@ -0,0 +1 @@ +{@render foo}