svelte-intellij icon indicating copy to clipboard operation
svelte-intellij copied to clipboard

style attribute syntax error with curly braces

Open shirotech opened this issue 4 years ago • 12 comments

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.

shirotech avatar Nov 04 '19 23:11 shirotech

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

tomblachut avatar Nov 05 '19 00:11 tomblachut

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

AleksandrSl avatar Nov 05 '19 11:11 AleksandrSl

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.

tomblachut avatar Nov 05 '19 12:11 tomblachut

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

AleksandrSl avatar Nov 05 '19 12:11 AleksandrSl

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.

shirotech avatar Nov 05 '19 12:11 shirotech

@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 :)

tomblachut avatar Nov 05 '19 13:11 tomblachut

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.

shirotech avatar Nov 06 '19 02:11 shirotech

@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 avatar Nov 06 '19 21:11 tomblachut

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

tomblachut avatar Nov 23 '19 17:11 tomblachut

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?

wtesler avatar Oct 23 '21 03:10 wtesler

How does one go about using that Filter?

it works automatically but covers only simplest cases

tomblachut avatar Dec 21 '21 20:12 tomblachut

<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?

ThatOtherAndrew avatar Aug 18 '22 00:08 ThatOtherAndrew

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

tomblachut avatar Jul 04 '23 16:07 tomblachut