diff --git a/package.json b/package.json index 91790d6a..a22a7601 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "prettier-plugin-svelte": "^2.5.0", "semver": "^7.3.5", "string-replace-loader": "^3.0.3", - "svelte": "^3.44.1", + "svelte": "^3.46.1", "ts-node": "^10.4.0", "typescript": "~4.5.0-0", "vue-eslint-parser": "^8.0.1" diff --git a/src/parser/converts/attr.ts b/src/parser/converts/attr.ts index 8b5d2623..1eaf8f69 100644 --- a/src/parser/converts/attr.ts +++ b/src/parser/converts/attr.ts @@ -13,7 +13,6 @@ import type { SvelteStartTag, SvelteName, SvelteStyleDirective, - SvelteMustacheTagText, SvelteStyleDirectiveLongform, SvelteStyleDirectiveShorthand, } from "../../ast" @@ -22,9 +21,13 @@ import type { Context } from "../../context" import type * as SvAST from "../svelte-ast-types" import { getWithLoc, indexOf } from "./common" import { convertMustacheTag } from "./mustache" -import { convertTemplateLiteralToLiteral, convertTextToLiteral } from "./text" +import { + convertAttributeValueTokenToLiteral, + convertTextToLiteral, +} from "./text" import { ParseError } from "../../errors" import type { ScriptLetCallback } from "../../context/script-let" +import type { AttributeToken } from "../html" /** Convert for Attributes */ export function* convertAttributes( @@ -79,13 +82,16 @@ export function* convertAttributes( yield convertLetDirective(attr, parent, ctx) continue } - if (attr.type === "Style") { - yield convertOldStyleDirective(attr, parent, ctx) - continue - } if (attr.type === "Ref") { throw new ParseError("Ref are not supported.", attr.start, ctx) } + if ((attr as any).type === "Style") { + throw new ParseError( + `Svelte v3.46.0 is no longer supported. Please use Svelte>=v3.46.1.`, + attr.start, + ctx, + ) + } throw new ParseError( `Unknown directive or attribute (${attr.type}) are not supported.`, attr.start, @@ -94,6 +100,42 @@ export function* convertAttributes( } } +/** Convert for attribute tokens */ +export function* convertAttributeTokens( + attributes: AttributeToken[], + parent: SvelteStartTag, + ctx: Context, +): IterableIterator { + for (const attr of attributes) { + const attribute: SvelteAttribute = { + type: "SvelteAttribute", + boolean: false, + key: null as any, + value: [], + parent, + ...ctx.getConvertLocation({ + start: attr.key.start, + end: attr.value?.end ?? attr.key.end, + }), + } + attribute.key = { + type: "SvelteName", + name: attr.key.name, + parent: attribute, + ...ctx.getConvertLocation(attr.key), + } + ctx.addToken("HTMLIdentifier", attr.key) + if (attr.value == null) { + attribute.boolean = true + } else { + attribute.value.push( + convertAttributeValueTokenToLiteral(attr.value, attribute, ctx), + ) + } + yield attribute + } +} + /** Convert for Attribute */ function convertAttribute( node: SvAST.Attribute, @@ -354,100 +396,6 @@ function convertStyleDirective( return directive } -/** Convert for Style Directive for svelte v3.46.0 */ -function convertOldStyleDirective( - node: SvAST.DirectiveForExpression, - parent: SvelteStyleDirective["parent"], - ctx: Context, -): SvelteStyleDirective { - const directive: SvelteStyleDirective = { - type: "SvelteStyleDirective", - key: null as any, - shorthand: false, - value: [], - parent, - ...ctx.getConvertLocation(node), - } - processDirectiveKey(node, directive, ctx) - if (processStyleDirectiveValue(node, ctx)) { - processDirectiveExpression(node, directive, ctx, { - processExpression(expression) { - directive.value.push( - convertTemplateLiteralToLiteral(expression, directive, ctx), - ) - return [] - }, - }) - } else { - processDirectiveExpression(node, directive, ctx, { - processExpression(expression, shorthand) { - ;(directive as any).shorthand = shorthand - return ctx.scriptLet.addExpression( - expression, - directive, - null, - (e) => { - const mustache: SvelteMustacheTagText = { - type: "SvelteMustacheTag", - kind: "text", - expression: e, - parent: directive, - ...ctx.getConvertLocation({ - start: ctx.code.lastIndexOf("{", e.range![0]), - end: ctx.code.indexOf("}", e.range![0]) + 1, - }), - } - directive.value.push(mustache) - }, - ) - }, - }) - } - - return directive -} - -/** Process plain value */ -function processStyleDirectiveValue( - node: SvAST.DirectiveForExpression, - ctx: Context, -): node is SvAST.DirectiveForExpression & { - expression: ESTree.TemplateLiteral -} { - const { expression } = node - if ( - !expression || - expression.type !== "TemplateLiteral" || - expression.expressions.length !== 0 - ) { - return false - } - const quasi = expression.quasis[0] - if (quasi.value.cooked != null) { - return false - } - const eqIndex = ctx.code.indexOf("=", node.start) - if (eqIndex < 0 || eqIndex >= node.end) { - return false - } - const valueIndex = ctx.code.indexOf(quasi.value.raw, eqIndex + 1) - if (valueIndex < 0 || valueIndex >= node.end) { - return false - } - const maybeEnd = valueIndex + quasi.value.raw.length - const maybeOpenQuote = ctx.code.slice(eqIndex + 1, valueIndex).trimStart() - if (maybeOpenQuote && maybeOpenQuote !== '"' && maybeOpenQuote !== "'") { - return false - } - const maybeCloseQuote = ctx.code.slice(maybeEnd, node.end).trimEnd() - if (maybeCloseQuote !== maybeOpenQuote) { - return false - } - getWithLoc(expression).start = valueIndex - getWithLoc(expression).end = maybeEnd - return true -} - /** Convert for Transition Directive */ function convertTransitionDirective( node: SvAST.TransitionDirective, @@ -648,7 +596,7 @@ function processDirectiveKey< /** Common process for directive expression */ function processDirectiveExpression< D extends SvAST.Directive, - S extends SvelteDirective | SvelteStyleDirective, + S extends SvelteDirective, E extends D["expression"], >( node: D & { expression: null | E }, @@ -679,9 +627,7 @@ function processDirectiveExpression< getWithLoc(node.expression).end = keyName.range[1] } processors.processExpression(node.expression, shorthand).push((es) => { - if (directive.type === "SvelteDirective") { - directive.expression = es - } + directive.expression = es }) } if (!shorthand) { diff --git a/src/parser/converts/root.ts b/src/parser/converts/root.ts index 62613185..ba361869 100644 --- a/src/parser/converts/root.ts +++ b/src/parser/converts/root.ts @@ -1,6 +1,5 @@ import type * as SvAST from "../svelte-ast-types" import type { - SvelteAttribute, SvelteName, SvelteProgram, SvelteScriptElement, @@ -9,7 +8,7 @@ import type { import {} from "./common" import type { Context } from "../../context" import { convertChildren, extractElementTags } from "./element" -import { extractTextTokens } from "./text" +import { convertAttributeTokens } from "./attr" /** * Convert root @@ -152,40 +151,8 @@ function extractAttributes( } const block = ctx.findBlock(element) if (block) { - for (const attr of block.attrs) { - const attrNode: SvelteAttribute = { - type: "SvelteAttribute", - boolean: false, - key: null as any, - value: [], - parent: element.startTag, - ...ctx.getConvertLocation({ - start: attr.key.start, - end: attr.value?.end ?? attr.key.end, - }), - } - element.startTag.attributes.push(attrNode) - attrNode.key = { - type: "SvelteName", - name: attr.key.name, - parent: attrNode, - ...ctx.getConvertLocation(attr.key), - } - ctx.addToken("HTMLIdentifier", attr.key) - if (attr.value == null) { - attrNode.boolean = true - } else { - const valueLoc = attr.value.quote - ? { start: attr.value.start + 1, end: attr.value.end - 1 } - : attr.value - attrNode.value.push({ - type: "SvelteLiteral", - value: attr.value.value, - parent: attrNode, - ...ctx.getConvertLocation(valueLoc), - }) - extractTextTokens(valueLoc, ctx) - } - } + element.startTag.attributes.push( + ...convertAttributeTokens(block.attrs, element.startTag, ctx), + ) } } diff --git a/src/parser/converts/text.ts b/src/parser/converts/text.ts index bdda6f8d..dfd7ac12 100644 --- a/src/parser/converts/text.ts +++ b/src/parser/converts/text.ts @@ -1,8 +1,7 @@ -import type ESTree from "estree" import type { SvelteLiteral, SvelteText } from "../../ast" import type { Context } from "../../context" +import type { AttributeValueToken } from "../html" import type * as SvAST from "../svelte-ast-types" -import { getWithLoc } from "./common" /** Convert for Text */ export function convertText( node: SvAST.Text, @@ -34,24 +33,28 @@ export function convertTextToLiteral( extractTextTokens(node, ctx) return text } -/** Convert for Old StyleDir's TemplateLiteral to Literal for svelte v3.46.0 */ -export function convertTemplateLiteralToLiteral( - node: ESTree.TemplateLiteral, + +/** Convert for AttributeValueToken to Literal */ +export function convertAttributeValueTokenToLiteral( + node: AttributeValueToken, parent: SvelteLiteral["parent"], ctx: Context, ): SvelteLiteral { + const valueLoc = node.quote + ? { start: node.start + 1, end: node.end - 1 } + : node const text: SvelteLiteral = { type: "SvelteLiteral", - value: node.quasis[0].value.raw, + value: node.value, parent, - ...ctx.getConvertLocation(node), + ...ctx.getConvertLocation(valueLoc), } - extractTextTokens(getWithLoc(node), ctx) + extractTextTokens(valueLoc, ctx) return text } /** Extract tokens */ -export function extractTextTokens( +function extractTextTokens( node: { start: number; end: number }, ctx: Context, ): void { diff --git a/src/parser/svelte-ast-types.ts b/src/parser/svelte-ast-types.ts index 06db0ad7..5ddb770d 100644 --- a/src/parser/svelte-ast-types.ts +++ b/src/parser/svelte-ast-types.ts @@ -198,14 +198,7 @@ interface BaseDirective extends BaseNode { modifiers: string[] } export interface DirectiveForExpression extends BaseDirective { - type: - | "Action" - | "Animation" - | "Binding" - | "Class" - | "Style" // For Svelte 3.46.0 - | "EventHandler" - | "Ref" + type: "Action" | "Animation" | "Binding" | "Class" | "EventHandler" | "Ref" expression: null | ESTree.Expression } export interface LetDirective extends BaseDirective {