tomblachut / svelte-intellij

Svelte components in WebStorm and friends
MIT License
485 stars 38 forks source link

style attribute syntax error with curly braces #80

Closed shirotech closed 1 year ago

shirotech commented 5 years ago

It's not really breaking, but would be good if there is a way to suppress this error.

Screen Shot 2019-11-05 at 10 46 38 am

From reading around, this is a low-level inspection that is tied to the css language itself and cannot be "turned off" by normal means, was wondering if this can be overwritten on the plugin level? Thanks.

tomblachut commented 5 years ago

Oh my... this is actually parser error, not an inspection, which is even harder to fix.

This would require overriding at least CSS parsing only for inline styles

com.intellij.psi.css.impl.parsing.CssParser2#createTermExpectedErrorElement

AleksandrSl commented 5 years ago

Maybe Vue plugin will save us as always, I will try to find what they do with :style attributes

tomblachut commented 5 years ago

This is more complicated than that. As far as I know you can't interpolate string attributes in Vue. Attribute value is either JS expression or string, which is then handled specially by IntelliJ for style and event handler attributes.

In Svelte case you can do basically whatever you want, and CSS parser sees only opacity:. Try to write that inside normal CSS file and you'll get the same error.

AleksandrSl commented 5 years ago

I see, so inline styles parsing should be enhanced allowing arbitrary JS expressions inside {}

shirotech commented 5 years ago

hmm, I see two options here, correct me if I'm wrong please, this is all guesswork.

  1. We disable css parsing of style attributes, treat it as a normal attribute.
  2. We try to interpolate the variable and pass it to the css parser? If this is even possible.
tomblachut commented 5 years ago

@shirotech

  1. It could work for now. We could even detect interpolations and disable CSS parsing only when they are present to avoid conflict. I like to write inline styles from time to time and CSS parsing is valuable.
  2. More like @AleksandrSl has said, disable parsing of curlies inside style tag on HTML level and override CSS parsing so curlies are handled there.
  3. There's a flag strict inside CSS parser. It's set to true by default, changing it hides those errors, but AST will be still wrong so CSS inspections etc. may fail

1 & 2 will require a lot of if statements :)

shirotech commented 5 years ago

Cool, @tomblachut can you show me where can I disable the strict flag in the code? I can help test it out to see any problems. Thanks.

tomblachut commented 5 years ago

@shirotech The short answer is that I don't know :)

It works like this: IntelliJ has decoupled lexing and parsing. Lexing is more basic, converts characters into tokens like keyword or number. What's interesing, there's something called lazy parseable tokens, or chameleons. CSS inside HTML is lazy parseable.

You need to check how SvelteHtmlLexer decides which classes to use when encountering style attribute. It's somewhere in superclasses. It's important to only change inline styles, not the style tags. Good starting point is com.intellij.lexer.HtmlLexer#ourInlineStyleElementType. It's private static so unfortunately it can't be just overriden.

Then you'll probably need to create dedicated element type, you can check SvelteJSLazyElementType for inspiration, or look for something that has CSS in the name. I think default is com.intellij.psi.css.impl.CssElementTypes.CssDeclarationBlockElementType

In said element you can define which parser class is used to parse inline CSS. By default it's very roundabout. Token has Language bound in constructor. Language has associated ParserDefiniton.

com.intellij.lang.css.CSSParserDefinition#createParser returns com.intellij.psi.css.impl.parsing.CssParser2. It needs to be replaced in lazy element type with something that ignores errors (check com.intellij.psi.css.impl.parsing.CssParser2#createErrorElement)

I know this is monumental work if it's your first time with IntelliJ SDK. Good luck. I realised even more how complicated is that after writing this comment.

tomblachut commented 4 years ago

I was able to suppress this error cheaply with HighlightErrorFilter java_2019-11-23_18-40-04

Keep in mind there are more complicated cases than one word interpolation and they are still broken

wtesler commented 3 years ago

I was able to suppress this error cheaply with HighlightErrorFilter java_2019-11-23_18-40-04

Keep in mind there are more complicated cases than one word interpolation and they are still broken

How does one go about using that Filter?

tomblachut commented 2 years ago

How does one go about using that Filter?

it works automatically but covers only simplest cases

ThatOtherAndrew commented 2 years ago
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">

This line from the official SvelteKit demo project results in a mis-parse, I'm assuming this is one of the more complex cases you were talking about. Is there any workaround for this currently?

tomblachut commented 1 year ago

Fixed in WEB-59773 Svelte: "mismatched parameters" error when using variables as function arguments in inline style