Intellisense suggests Javascript inside style tag
TheIcyColdPenguin opened this issue · 2 comments
Describe the bug
Intellisense suggests Javascript objects instead of CSS properties when Ctrl+Space is pressed.
This is the minimal amount of code I could reproduce the issue with.
Even changing the comparison from <=
to <
resolves the issue.
Reproduction
- Create a new svelte project using vite
- replace
App.svelte
with the following code
<button
on:mousedown={(e) => {
if ({ x: 1 }.x <= 0) {
}
}}
/>
<style>
button {
}
</style>
Expected behaviour
Should display CSS properties when Ctrl-Space is pressed
System Info
- OS: Windows 11
- IDE: VSCode 1.89.1 (Running in WSL 2)
- Extension: Svelte For VSCode v108.5.0
Which package is the issue about?
Svelte for VS Code extension
Additional Information, eg. Screenshots
dependencies in package.json
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"svelte": "^4.2.12",
"vite": "^5.2.0"
}
Investigation
This bug occurs because the vscode-html-languageservice
HTMLParser
is not meant to parse Svelte, and interprets the '<' character in JS as starting tag character.
When it happens, <style>
is no longer a root node in parsed node tree, but a child of another node that starts from the '<' character. As root <style>
can't be found, during autocomplete, the caret position is not determined to be inside <style>
tag. (this.styleInfo == null
in below code)
language-tools/packages/language-server/src/lib/documents/Document.ts
Lines 48 to 52 in cc25dbd
This bug does not trigger often because usually the vscode lsp's HTMLParser manages to generate a good-enough tree even when given a very incorrect (Svelte) HTML code.
Reproduction
Here is an even more minimal reproducable code:
<button on:click={() => {console.log({x:1}.x < 2)}}></button>
<style>
/* autocomplete here returns js/ts autocomplete */
</style>
I am closing this in favour of #2155. As pointed out, the problem is the moustache tag is not strictly compliant with HTML. Both cases have an end bracket that looks like it ends the moustache and a >
or <
that looks like a start or end tag. A proper fix would need a js/ts parser to determine where the expression ends. But It might be slower in large files and could also have problems when the expression has syntax errors. You can workaround it by wrapping the expression with double-quote or move it to the script tag.
<button
on:mousedown="{(e) => {
if ({ x: 1 }.x <= 0) {
}
}}"
/>
<style>
button {
}
</style>