Javascript dialects, dialectSpecificHandlersFactory
Hello,
I'm working on language plugin for template engine based on Nashorn. I've got some dialect-specific handlers (JavaScript.dialectSpecificHandlersFactory) and my language class looks like this:
public class MyTemplateInnerJs extends JSLanguageDialect
{
protected MyTemplateInnerJs()
{
super("MyTemplateInnerJs", DialectOptionHolder.OTHER);
}
}
I'd like to use it with DialectOptionHolder.NASHORN because of some features, e.g. this one. But if I use that (or anything else than DialectOptionHolder,OTHER), my dialect-specific handlers for some reason just stop working. Am I missing something?
Please sign in to leave a comment.
Hello Peter.
Did you try using DialectOptionHolder.OTHER with your dialectSpecificHandlersFactory extending NashornJSSpecificHandlersFactory?
That helped, thanks a lot!
Actually it's not totally perfect. If I extend my reference expression resolver from NashornJSReferenceExpressionResolver or if I use NashornJSSpecificHandlersFactory as is, references resolve just fine, but there is no autocompletion for packages / classes / class members. Autocompletion works only together with DialectOptionHolder.NASHORN. Any ideas?
There's one more thing, which may be a bug. Let's have the following class:
and js:
The AEnum resolves to private property aEnum and A is unresolved variable.
AEnum in
resolves properly to enum class for me. Could you please recheck it?
I'm sorry, the example I provided really works well, so one more try:
Thanks for the issue!
I'm still not really clear about nashorn dialect in Idea. If I choose language version NashornJS in idea settings for .js file, I do get all the features like for each support for example. If I set DialectOptionHolder.NASHORN for my language, I don't get any of these. If I use DialectOptionHolder.NASHORN, my dialectSpecificHandlersFactory is never instantiated - I've done some research and is seems, that nashorn acts in this case just as a different language and javascript extension namespace is not working for it. If I use DialectOptionHolder.OTHER and my factory / handlers extend appropriate nashorn classes, I still don't get any for each support, java class / package autocompletion etc. Why's that?
I think you should use DialectOptionHolder.NASHORN language and extend NashornJSSpecificHandlersFactory. I'm not sure if it helps, but please try order="first" attribute for your JSDialectSpecificHandlersFactory in plugin.xml file. BTW, is your plugin open-source?
Thanks, order="first" is something, that always gets me. So now I do have nashorn dialect set, java package / class completion works very well, but still there is no for each support. You can find my code here. I've created lexer layer which treats 'for each' as if it was 'for', but that code is commented out.
edit: I've been just overjoyed with the idea that it would be so simple. So no, it's not working even with order="first".
So finally I got it. For each support is achieved by extending NashornJSParserDefinition instead of base JavascriptParserDefinition, class / package completion is done in NashornJSCompletionHelper (javascript completionHelper extension point) and using DialectOptionHolder.NASHORN is just not possible. I'm using DialectOptionHolder.OTHER and my dialectSpecificHandlersFactory extend NashornJSSpecificHandlersFactory.
The 'each' keyword is not highlighted as a keyword in my templates anymore. Unfortunately I'm not able to tell since which version this happens. The structure is described in my previous comment and the code is here. This is strange, because the for each works just fine (PSI element JSForInStatement, type resolver works, no syntax errors...). Any ideas?
Using DialectOptionHolder.OTHER instead of NASHORN makes lexer interpret 'each' as JSTokenTypes.IDENTIFIER, not EACH_KEYWORD. I suggest to highlight 'each' manually, e.g. by adding an extension to JavaScript.analysisHandlersFactory extension point and overriding createKeywordHighlighterVisitor method.
That is not true actually, it doesn't make any difference if I use DialectOptionHolder.OTHER or DialectOptionHolder.NASHORN, the PSI is the same in both cases and looks like this:
I have tried to override the createKeywordHighlighterVisitor in my InnerJsAnalysisHandlersFactory, however this method is never called. I can see that the JSSemanticKeywordHighlighter in JSSemanticKeywordHighlighterFactory is instantiated (quite often) and the JSSemanticKeywordHighlighter#doCollectInformation() is called, but the condition 'this.myFile instanceof JSFile' is false, therefore the JSAnalysisHandlersFactory.forElement(this.myFile) is never called. So what would you suggest for template languages?
Do you have JSEmbeddedContent, like in .vue files? If not, you may register com.intellij.lang.annotation.Annotator and highlight 'each' in it.
Ok thanks, here is the solution.