Custom Language Plugin for Groovy DSL

Answered

Hi everybody,

as part of my Bachelor-Thesis, I am trying to implement a custom language plugin which primarily adds syntax highlighting to a Groovy DSL (called LSL) within a custom file type. However, I have some problems finding the right approach as I am still very new to plugin development. Since the custom language is a Groovy based DSL, I really want the LSL-files to be parsed by the Groovy Parser already implemented in the IntelliJ Groovy Plugin (if possible), as rewriting basicially the entire Groovy Grammar doesnt't seem to be really feasible. I thought, that I could just register the GroovyParserDefinition.java in the plugin.xml via:

<lang.parserDefinition language="LSL" implementationClass="org.jetbrains.plugins.groovy.lang.parser.GroovyParserDefinition"/>

 however I get the following error during execution:

java.lang.AssertionError: Language Language: Groovy doesn't participate in view provider com.intellij.psi.SingleRootFileViewProvider{vFile=file://D:/IntelliJ Workspace/LSLTestProject/src/lsl-archive_tds_method_base64.lsl, vFileId=106772, content=VirtualFileContent{size=3150}, eventSystemEnabled=true}: [Language: LSL]

and don't really know how to resolve it.

I additionally found these two rather old posts (https://intellij-support.jetbrains.com/hc/en-us/community/posts/206133829-MultiplePsiFilesPerDocumentFileViewProvider-replacement-for-Diana & https://intellij-support.jetbrains.com/hc/en-us/community/posts/206135649-java-intentions-for-custom-language-extending-groovy?input_string=Custom%20Language%20for%20Groovy%20DSL ), which both seem to be closely related to my concrete scenario, yet with either no answer or one that I have difficulties comprehending.

Is there a rather simple fix for this problem or a preferred approach for such an use case that I should use instead?

Thanks in advance,
Tim

0
5 comments

Assuming LSL files are actually Groovy code, the simplest solution would be using same approach as for GDSL in Groovy plugin

see org.jetbrains.plugins.groovy.GdslFileType which is mapped to dedicated extension but re-using Groovy.

Additional highlighting could then be applied using regular API (Annotator, Inspections, ...)

0
Avatar
Permanently deleted user

Thanks Yann for your prompt response. Indeed, LSL files contain just normal Groovy code while Java code is occasionally found within Strings.
To which language would I then assign components like the annotator? Because if I assign it to the Groovy language via: 

<annotator language="Groovy" implementationClass="lsl.annotator.LslAnnotator"/>

the keywords specific to LSL will also get highlighted in plain .groovy files which could get quite confusing when a LSL specific keywords is accidently used in normal Groovy code.

I have tried to avoid this by differentiating between Groovy and LSL files by checking the returned String of

element.getContainingFile().getFileType().getDefaultExtension()

in the annotate method of the annotator. Yet, it always returns "groovy" instead of "lsl" for LSL files.

Also, is there an easy way to enable syntax highlighting for the Java code contained in some Strings? (Instead of manually including  the

// language=Java

comment before every String which contains Java code)

Thanks again!

 

0

How did you register your custom filetype? It should be possible to check VirtualFile#getType == YourFileType.INSTANCE (in general, never rely on file extensions as these could be changed by user)

To provide automatic language injection, see com.intellij.lang.injection.MultiHostInjector. Sample plugins: https://plugins.jetbrains.com/intellij-platform-explorer/?extensions=com.intellij.multiHostInjector

0
Avatar
Permanently deleted user

I registered the file type via:

<fileType name="LSL File" implementationClass="lsl.language.LslFileType" fieldName="INSTANCE" extensions="lsl"/>

Additionally, did I understand you right that with checking VirtualFile#getType == YourFileType.INSTANCE you mean element.getContainingFile().getVirtualFile().getFileType() == YourFileType.INSTANCE? (where element is the PsiElement parameter of the annotate method). To my knowledge the VirtualFile class does not privide a getType method.

And thank you for the hint with the com.intellij.lang.injection.MultiHostInjector!

0

Yes, I meant com.intellij.openapi.vfs.VirtualFile#getFileType

0

Please sign in to leave a comment.