From 0c0865ae6df7621916a1478d218429178607351a Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 9 Apr 2022 11:55:18 +0200 Subject: [PATCH 1/2] (feat) add support for svelte:element #1435 --- packages/language-server/package.json | 4 ++-- .../src/plugins/html/dataProvider.ts | 12 ++++++++++++ .../fixtures/svelte-element/expected.json | 9 +++++++++ .../fixtures/svelte-element/expectedv2.json | 9 +++++++++ .../fixtures/svelte-element/input.svelte | 11 +++++++++++ packages/svelte2tsx/package.json | 2 +- packages/svelte2tsx/src/htmlxtojsx/index.ts | 3 +++ .../src/htmlxtojsx/nodes/svelte-tag.ts | 2 +- .../src/htmlxtojsx_v2/nodes/Element.ts | 3 ++- packages/svelte2tsx/svelte-jsx.d.ts | 2 ++ .../samples/svelte-element/expected.tsx | 14 ++++++++++++++ .../samples/svelte-element/expectedv2.ts | 14 ++++++++++++++ .../samples/svelte-element/input.svelte | 7 +++++++ yarn.lock | 16 ++++++++-------- 14 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected.json create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expectedv2.json create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/input.svelte create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected.tsx create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/input.svelte diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 02e6876f1..fef2200dd 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -53,9 +53,9 @@ "fast-glob": "^3.2.7", "lodash": "^4.17.21", "prettier": "2.5.1", - "prettier-plugin-svelte": "~2.6.0", + "prettier-plugin-svelte": "~2.7.0", "source-map": "^0.7.3", - "svelte": "^3.46.1", + "svelte": "^3.47.0", "svelte-preprocess": "~4.10.1", "svelte2tsx": "~0.5.0", "typescript": "*", diff --git a/packages/language-server/src/plugins/html/dataProvider.ts b/packages/language-server/src/plugins/html/dataProvider.ts index e515b1e3f..86323ffb2 100644 --- a/packages/language-server/src/plugins/html/dataProvider.ts +++ b/packages/language-server/src/plugins/html/dataProvider.ts @@ -85,6 +85,18 @@ const svelteTags: ITagData[] = [ } ] }, + { + name: 'svelte:element', + description: + 'Renders a DOM element dynamically, using the string as the this property. When the property changes, the element is destroyed and recreated.\n\nIf this is falsy, no element is rendered.', + attributes: [ + { + name: 'this', + description: + 'DOM element to render.\n\nWhen this property changes, the element is destroyed and recreated.\nIf this is falsy, no element is rendered.' + } + ] + }, { name: 'svelte:window', description: diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected.json new file mode 100644 index 000000000..57e3758f8 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected.json @@ -0,0 +1,9 @@ +[ + { + "range": { "start": { "line": 10, "character": 0 }, "end": { "line": 10, "character": 0 } }, + "severity": 1, + "source": "js", + "message": " must have a 'this' attribute", + "code": -1 + } +] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expectedv2.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expectedv2.json new file mode 100644 index 000000000..57e3758f8 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expectedv2.json @@ -0,0 +1,9 @@ +[ + { + "range": { "start": { "line": 10, "character": 0 }, "end": { "line": 10, "character": 0 } }, + "severity": 1, + "source": "js", + "message": " must have a 'this' attribute", + "code": -1 + } +] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/input.svelte b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/input.svelte new file mode 100644 index 000000000..ec1324d02 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/input.svelte @@ -0,0 +1,11 @@ + + + + +{tag} + tag} /> + + + diff --git a/packages/svelte2tsx/package.json b/packages/svelte2tsx/package.json index 384740f37..b539b8e8d 100644 --- a/packages/svelte2tsx/package.json +++ b/packages/svelte2tsx/package.json @@ -34,7 +34,7 @@ "source-map": "^0.6.1", "source-map-support": "^0.5.16", "sourcemap-codec": "^1.4.8", - "svelte": "~3.46.1", + "svelte": "~3.47.0", "tiny-glob": "^0.2.6", "tslib": "^1.10.0", "typescript": "^4.6.2" diff --git a/packages/svelte2tsx/src/htmlxtojsx/index.ts b/packages/svelte2tsx/src/htmlxtojsx/index.ts index 2947d35cc..f4b4eccb7 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/index.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/index.ts @@ -111,6 +111,9 @@ export function convertHtmlxToJsx( ); break; case 'Element': + if (node.name === 'svelte:element') { + handleSvelteTag(htmlx, str, node); + } templateScopeManager.componentOrSlotTemplateOrElementEnter(node); handleElement( htmlx, diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/svelte-tag.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/svelte-tag.ts index 44a64db07..143e2e183 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/nodes/svelte-tag.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/svelte-tag.ts @@ -3,7 +3,7 @@ import { BaseNode } from '../../interfaces'; /** * `...` ----> `...` - * (same for :head, :body, :options, :fragment) + * (same for :head, :body, :options, :fragment, :element) */ export function handleSvelteTag(htmlx: string, str: MagicString, node: BaseNode): void { const colon = htmlx.indexOf(':', node.start); diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Element.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Element.ts index 6403dbf74..19f432dc2 100644 --- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Element.ts +++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Element.ts @@ -11,7 +11,7 @@ import { const voidTags = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'.split(','); /** - * Handles HTML elements as well as svelte:options, svelte:head, svelte:window, svelte:body + * Handles HTML elements as well as svelte:options, svelte:head, svelte:window, svelte:body, svelte:element * * Children of this element should call the methods on this class to add themselves to the correct * position within the transformation. @@ -94,6 +94,7 @@ export class Element { case 'svelte:head': case 'svelte:window': case 'svelte:body': + case 'svelte:element': case 'svelte:fragment': { // remove the colon: svelte:xxx -> sveltexxx const nodeName = `svelte${this.node.name.substring(7)}`; diff --git a/packages/svelte2tsx/svelte-jsx.d.ts b/packages/svelte2tsx/svelte-jsx.d.ts index 92655d158..ed36e15e6 100644 --- a/packages/svelte2tsx/svelte-jsx.d.ts +++ b/packages/svelte2tsx/svelte-jsx.d.ts @@ -298,6 +298,7 @@ declare namespace svelteHTML { sveltefragment: { slot?: string; }; svelteoptions: { [name: string]: any }; sveltehead: { [name: string]: any }; + svelteelement: { 'this': string | undefined | null; } & HTMLProps & SVGProps; [name: string]: { [name: string]: any }; } @@ -1453,6 +1454,7 @@ declare namespace svelte.JSX { sveltefragment: { slot?: string; }; svelteoptions: { [name: string]: any }; sveltehead: { [name: string]: any }; + svelteelement: { 'this': string | undefined | null; } & HTMLProps & SVGProps; [name: string]: { [name: string]: any }; } diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected.tsx b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected.tsx new file mode 100644 index 000000000..134e60738 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected.tsx @@ -0,0 +1,14 @@ +/// +<>;function render() { + + let tag = 'div'; +; +() => (<> + + +{tag} + tag} />); +return { props: {}, slots: {}, getters: {}, events: {} }} + +export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) { +} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expectedv2.ts new file mode 100644 index 000000000..312059a87 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expectedv2.ts @@ -0,0 +1,14 @@ +/// +;function render() { + + let tag = 'div'; +; +async () => { + + { svelteHTML.createElement("svelteelement", { });} + { svelteHTML.createElement("svelteelement", { });tag; } + { svelteHTML.createElement("svelteelement", { "onclick":() => tag,});}}; +return { props: {}, slots: {}, getters: {}, events: {} }} + +export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) { +} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/input.svelte new file mode 100644 index 000000000..e0c57b76b --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/input.svelte @@ -0,0 +1,7 @@ + + + +{tag} + tag} /> diff --git a/yarn.lock b/yarn.lock index 5d3752b76..ba1ba014d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2093,10 +2093,10 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier-plugin-svelte@~2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.6.0.tgz#0e845b560b55cd1d951d6c50431b4949f8591746" - integrity sha512-NPSRf6Y5rufRlBleok/pqg4+1FyGsL0zYhkYP6hnueeL1J/uCm3OfOZPsLX4zqD9VAdcXfyEL2PYqGv8ZoOSfA== +prettier-plugin-svelte@~2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.7.0.tgz#ecfa4fe824238a4466a3497df1a96d15cf43cabb" + integrity sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA== prettier@2.3.2: version "2.3.2" @@ -2533,10 +2533,10 @@ svelte-preprocess@~4.10.1: sorcery "^0.10.0" strip-indent "^3.0.0" -svelte@^3.46.1, svelte@~3.46.1: - version "3.46.1" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.46.1.tgz#8ea23595824a39d47d04c16c217000fbc4c52c49" - integrity sha512-Ue8ivq+G45AfZZL4Z93xNFiC352wPkyGiY9QSuWjxXh6jiaZMrpthinjc1rz0OSTceuST7Pxr1HDBj2KioliZg== +svelte@^3.47.0, svelte@~3.47.0: + version "3.47.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.47.0.tgz#ba46fe4aea99fc650d6939c215cd4694f5325a19" + integrity sha512-4JaJp3HEoTCGARRWZQIZDUanhYv0iyoHikklVHVLH9xFE9db22g4TDv7CPeNA8HD1JgjXI1vlhR1JZvvhaTu2Q== table@^5.2.3: version "5.4.6" From c68819a23b8228e78595a9b114495e684b6b3f47 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 9 Apr 2022 12:01:44 +0200 Subject: [PATCH 2/2] adjust test --- .../test/plugins/svelte/features/getDiagnostics.test.ts | 7 +++---- .../plugins/svelte/testfiles/diagnostics-module.svelte | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts index ceb6902fe..8ce588264 100644 --- a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts +++ b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts @@ -471,12 +471,11 @@ describe('SveltePlugin#getDiagnostics', () => { assert.deepStrictEqual(diagnostics, [ { - range: { start: { line: 1, character: 15 }, end: { line: 1, character: 27 } }, - message: - "Component has unused export property 'name'. If it is for external reference only, please consider using `export const name`", + range: { start: { line: 1, character: 4 }, end: { line: 1, character: 26 } }, + message: '$: has no effect in a module script', severity: 2, source: 'svelte', - code: 'unused-export-let' + code: 'module-script-reactive-declaration' } ]); }); diff --git a/packages/language-server/test/plugins/svelte/testfiles/diagnostics-module.svelte b/packages/language-server/test/plugins/svelte/testfiles/diagnostics-module.svelte index e85090964..3abb81402 100644 --- a/packages/language-server/test/plugins/svelte/testfiles/diagnostics-module.svelte +++ b/packages/language-server/test/plugins/svelte/testfiles/diagnostics-module.svelte @@ -1,3 +1,3 @@