fix: handle TypeScript's optional parameter syntax in snippets (#10671)

fixes #10530
pull/10674/head
Simon H 10 months ago committed by GitHub
parent b1b51a404b
commit 1ac313594c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: handle TypeScript's optional parameter syntax in snippets

@ -13,16 +13,17 @@ import { error } from '../../../errors.js';
/**
* @param {import('../index.js').Parser} parser
* @param {boolean} [optional_allowed]
* @returns {import('estree').Pattern}
*/
export default function read_pattern(parser) {
export default function read_pattern(parser, optional_allowed = false) {
const start = parser.index;
let i = parser.index;
const code = full_char_code_at(parser.template, i);
if (isIdentifierStart(code, true)) {
const name = /** @type {string} */ (parser.read_identifier());
const annotation = read_type_annotation(parser);
const annotation = read_type_annotation(parser, optional_allowed);
return {
type: 'Identifier',
@ -83,7 +84,7 @@ export default function read_pattern(parser) {
parse_expression_at(`${space_with_newline}(${pattern_string} = 1)`, parser.ts, start - 1)
).left;
expression.typeAnnotation = read_type_annotation(parser);
expression.typeAnnotation = read_type_annotation(parser, optional_allowed);
if (expression.typeAnnotation) {
expression.end = expression.typeAnnotation.end;
}
@ -96,12 +97,19 @@ export default function read_pattern(parser) {
/**
* @param {import('../index.js').Parser} parser
* @param {boolean} [optional_allowed]
* @returns {any}
*/
function read_type_annotation(parser) {
function read_type_annotation(parser, optional_allowed = false) {
const start = parser.index;
parser.allow_whitespace();
if (optional_allowed && parser.eat('?')) {
// Acorn-TS puts the optional info as a property on the surrounding node.
// We spare the work here because it doesn't matter for us anywhere else.
parser.allow_whitespace();
}
if (!parser.eat(':')) {
parser.index = start;
return undefined;

@ -276,7 +276,7 @@ function open(parser) {
const parameters = [];
while (!parser.match(')')) {
let pattern = read_pattern(parser);
let pattern = read_pattern(parser, true);
parser.allow_whitespace();
if (parser.eat('=')) {

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: '1 2 3 4 5'
});

@ -0,0 +1,24 @@
<script lang="ts">
</script>
{#snippet counter1(c: number)}
{c}
{/snippet}
{#snippet counter2({ c }: {c: number})}
{c}
{/snippet}
{#snippet counter3(c?: number)}
{c}
{/snippet}
{#snippet counter4(c: number = 4)}
{c}
{/snippet}
{#snippet counter5(c?: number = 5)}
{c}
{/snippet}
{@render counter1(1)}
{@render counter2({ c: 2 })}
{@render counter3(3)}
{@render counter4()}
{@render counter5()}
Loading…
Cancel
Save