sveltejs / prettier-plugin-svelte

Format your svelte components using prettier.
MIT License
714 stars 95 forks source link

Formatting bug with @render children() and class=")" #433

Closed eddiemcconkie closed 4 months ago

eddiemcconkie commented 4 months ago

Describe the bug

I ran into a bug where I have {@render children()} in my markup, and later on I have an element with a closing paren inside the class string. When I format on save, the markup between the closing paren for children() and the closing paren in the element's class gets duplicated.

Reproduction

This is the markup I start with:

<script lang="ts">
  import type { Snippet } from 'svelte';

  const { children } = $props<{ children: Snippet }>();
</script>

<main>{@render children()}</main>
<ul>
  <li>
    <button class=")"></button>
  </li>
</ul>

and this is what it turns into when I run the formatter:

<script lang="ts">
  import type { Snippet } from 'svelte';

  const { children } = $props<{ children: Snippet }>();
</script>

<main>{@render children()}</main>
<ul>
  <li>
    <button class=")}</main>
<ul>
  <li>
    <button class=")"></button>
  </li>
</ul>

Expected behaviour

Markup shouldn't get duplicated

System Info

Which package is the issue about?

Svelte for VS Code extension

Additional Information, eg. Screenshots

I just barely upgraded the extension, and while it formatted correctly before, it breaks with the new version.


Edit:

I tried installing some older versions of the extension (back to 107.10.0), and those broke the formatter as well. Anything earlier than that and I would get a message saying the Svelte server crashed multiple times. I'm not 100% sure why the formatter started breaking, but it only happened after I uninstalled the Svelte Intellisense and Svelte 3 Snippets extensions. However, if I install them again, the formatter still breaks.

eddiemcconkie commented 4 months ago

Just for extra context on why I have a ) in the class, I'm using UnoCSS which can preprocess

<div class="flex-(column align-center)">

into

<div class="flex-column flex-align-center">

I've tried disabling UnoCSS just to be sure, and the bug persists, so I'm pretty sure it's just the formatter.

eddiemcconkie commented 4 months ago

Just a couple more tests, and it seems to happen whenever there is a closing paren anywhere after @render children(). This component will get formatted incorrectly and duplicate the markup between the opening paren after children and the closing paren in the onclick handler. If you switch the order of the last two lines, the bug goes away.

<script lang="ts">
  import type { Snippet } from "svelte";
  const { children } = $props<{ children:Snippet }>()
</script>

{@render children()}
<button onclick={()=>{}}></button>
dummdidumm commented 4 months ago

Make sure you're running the latest version of the VS Code extension, and that you have installed the latest version of prettier-plugin-svelte - then the error should go away.