Implementing a CSS extension language.

Hi,

We are trying to write a plugin adding support for GSS (https://github.com/google/closure-stylesheets) which is essentially a CSS extension (i.e. any valid CSS is valid GSS). To avoid reimplementing the CSS support from scratch we are trying to use the ConfigurableTemplateLanguageFileViewProvider and leave the CSS part to the CSS parser.

 

The problem we've encountered is as follows:

1. We have to distinguish CSS from GSS on the lexer level, which means, in particular, that for every brace we need to be able to tell whether it should be forwarded to CSS lexer or not.

2. GSS (and CSS) can theoretically have arbitrary level of block nestedness, for example

@component / gss / {

@media / css / {

@media / css / {

@if (...) / gss / {... }

}

}

}

is possible.

 

We are happy to implement our own Lexer that would maintain a block stack and keep track of which context we're in, but the Lexer.start(..) method (https://github.com/JetBrains/intellij-community/blob/master/platform/core-api/src/com/intellij/lexer/Lexer.java#L40) only receives an integer state (not LexerPosition which we would be able to extend with the stack state) and thus it becomes very tricky to restore the block stack from an integer state.

 

We are considering now whether we should use that integer as a bit stack (which should allow us to support some reasonable level of nestedness), but that seems rather hacky.

 

Could you help us realise what is the proper way of implementing support for a CSS extension like this one?

 

Thank you!

1
2 comments
Official comment

Hi Kaathewise,

Yes, you have to implement your own lexer.

No, it's not supposed to change Lexer interface. As you said, usually, we use that integer state as a bit stack, e.g. https://github.com/JetBrains/intellij-community/blob/master/xml/xml-psi-impl/src/com/intellij/lexer/BaseHtmlLexer.java#L300.

Alexander,

 

Thank you for your timely response. That's what we decided to do in the end.

0

Please sign in to leave a comment.