Skip to content

Commit

Permalink
fix: correctly backport svelte:element to old AST
Browse files Browse the repository at this point in the history
Both `<svelte:element this="div">` and `<svelte:element this={"div"}>` were backported as `tag: "div"` for the old AST. That's wrong because the latter should result in `tag: { type: 'Literal', .. }`. Fixing this makes all the tests in prettier-plugin-svelte pass with Svelte 5.

Also cleaned up a bit of code in the parser.
  • Loading branch information
dummdidumm committed Jun 5, 2024
1 parent 862949d commit e7831e0
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-colts-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte": patch
---

fix: correctly backport `svelte:element` to old AST
6 changes: 5 additions & 1 deletion packages/svelte/src/compiler/legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,11 @@ export function convert(source, ast) {
SvelteElement(node, { visit }) {
/** @type {import('estree').Expression | string} */
let tag = node.tag;
if (tag.type === 'Literal' && typeof tag.value === 'string') {
if (
tag.type === 'Literal' &&
typeof tag.value === 'string' &&
source[/** @type {number} */ (node.tag.start) - 1] !== '{'
) {
tag = tag.value;
}

Expand Down
1 change: 0 additions & 1 deletion packages/svelte/src/compiler/phases/1-parse/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import full_char_code_at from './utils/full_char_code_at.js';
import * as e from '../../errors.js';
import { create_fragment } from './utils/create.js';
import read_options from './read/options.js';
import { locator } from '../../state.js';

const regex_position_indicator = / \(\d+:\d+\)$/;

Expand Down
15 changes: 8 additions & 7 deletions packages/svelte/src/compiler/phases/1-parse/state/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
/** Invalid attribute characters if the attribute is not surrounded by quotes */
const regex_starts_with_invalid_attr_value = /^(\/>|[\s"'=<>`])/;

/** @type {Map<string, import('#compiler').SvelteNode['type']>} */
/** @type {Map<string, import('#compiler').ElementLike['type']>} */
const root_only_meta_tags = new Map([
['svelte:head', 'SvelteHead'],
['svelte:options', 'SvelteOptions'],
Expand All @@ -23,7 +23,7 @@ const root_only_meta_tags = new Map([
['svelte:body', 'SvelteBody']
]);

/** @type {Map<string, import('#compiler').SvelteNode['type']>} */
/** @type {Map<string, import('#compiler').ElementLike['type']>} */
const meta_tags = new Map([
...root_only_meta_tags,
['svelte:element', 'SvelteElement'],
Expand Down Expand Up @@ -132,24 +132,25 @@ export default function tag(parser) {
: 'RegularElement';

/** @type {import('#compiler').ElementLike} */
// @ts-expect-error TODO can't figure out this error
const element =
type === 'RegularElement'
? {
type: /** @type {import('#compiler').ElementLike['type']} */ (type),
type: type,
start,
end: -1,
name,
attributes: [],
fragment: create_fragment(true),
metadata: {
svg: false,
mathml: false,
scoped: false,
has_spread: false
},
parent: null
}
: {
type: /** @type {import('#compiler').ElementLike['type']} */ (type),
: /** @type {import('#compiler').ElementLike} */ ({
type,
start,
end: -1,
name,
Expand All @@ -159,7 +160,7 @@ export default function tag(parser) {
metadata: {
svg: false
}
};
});

parser.allow_whitespace();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
<svelte:element this="div"></svelte:element>
<!-- prettier-ignore -->
<svelte:element this='div'></svelte:element>
<svelte:element this={"div"}></svelte:element>
<!-- prettier-ignore -->
<svelte:element this={'div'}></svelte:element>
<svelte:element this={"div"} class="foo"></svelte:element>
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,164 @@
"html": {
"type": "Fragment",
"start": 0,
"end": 105,
"end": 292,
"children": [
{
"type": "Element",
"name": "svelte:element",
"start": 0,
"end": 46,
"end": 44,
"tag": "div",
"attributes": [],
"children": []
},
{
"type": "Text",
"start": 46,
"end": 47,
"start": 44,
"end": 45,
"raw": "\n",
"data": "\n"
},
{
"type": "Comment",
"start": 45,
"end": 69,
"data": " prettier-ignore ",
"ignores": []
},
{
"type": "Text",
"start": 69,
"end": 70,
"raw": "\n",
"data": "\n"
},
{
"type": "Element",
"name": "svelte:element",
"start": 47,
"end": 105,
"start": 70,
"end": 114,
"tag": "div",
"attributes": [],
"children": []
},
{
"type": "Text",
"start": 114,
"end": 115,
"raw": "\n",
"data": "\n"
},
{
"type": "Element",
"name": "svelte:element",
"start": 115,
"end": 161,
"tag": {
"type": "Literal",
"start": 137,
"end": 142,
"loc": {
"start": {
"line": 4,
"column": 22
},
"end": {
"line": 4,
"column": 27
}
},
"value": "div",
"raw": "\"div\""
},
"attributes": [],
"children": []
},
{
"type": "Text",
"start": 161,
"end": 162,
"raw": "\n",
"data": "\n"
},
{
"type": "Comment",
"start": 162,
"end": 186,
"data": " prettier-ignore ",
"ignores": []
},
{
"type": "Text",
"start": 186,
"end": 187,
"raw": "\n",
"data": "\n"
},
{
"type": "Element",
"name": "svelte:element",
"start": 187,
"end": 233,
"tag": {
"type": "Literal",
"start": 209,
"end": 214,
"loc": {
"start": {
"line": 6,
"column": 22
},
"end": {
"line": 6,
"column": 27
}
},
"value": "div",
"raw": "'div'"
},
"attributes": [],
"children": []
},
{
"type": "Text",
"start": 233,
"end": 234,
"raw": "\n",
"data": "\n"
},
{
"type": "Element",
"name": "svelte:element",
"start": 234,
"end": 292,
"tag": {
"type": "Literal",
"start": 256,
"end": 261,
"loc": {
"start": {
"line": 7,
"column": 22
},
"end": {
"line": 7,
"column": 27
}
},
"value": "div",
"raw": "\"div\""
},
"attributes": [
{
"type": "Attribute",
"start": 76,
"end": 87,
"start": 263,
"end": 274,
"name": "class",
"value": [
{
"start": 83,
"end": 86,
"start": 270,
"end": 273,
"type": "Text",
"raw": "foo",
"data": "foo"
Expand Down

0 comments on commit e7831e0

Please sign in to comment.