Writing plugin for compiler extention.

I have a compiler plugin that rewrites parts of Scala by adding new methods, etc.. Is there a way to extend existing Scala plugin to recognize the construct of my extension, e.g. be aware of generated methods? Can this be achieved by writing separate plugin or am I forced to direclty manipulate exisiting Scala plugin sources?

Comment actions Permalink

Hi Pawel!

You may check Developing IDEA plugin with dependency on Scala plugin for a start.

Initially you can tinker with the Scala plugin code directly, and then, when you discover and refine all the requirement, we can introduce special extension points for such purposes.

We've created a corresponding issue in our YouTrack: SCL-6928.

Please feel free to ask question either here or by email (pavel.fatin@jetbrains.com, alexander.podkhalyuzin@jetbrains.com).

Comment actions Permalink

I've been recently looking into Scala plugin code. I have some thoughts about possible solutions for handling new members with compiler extension.

1. Modifying type/name resolution.
One of the options I thought about was to hook into names/types resolution algorithm. What I found were ScalaAnnotatorHighlightVisitor, ScReferenceExpressionImpl and ResolvableReferenceExpression. The there code looks complicated. I seems like handling compiler plugins' new members discovery would probably require careful placement of extension points to cover all cases (eg. new method, new class) and would not be very robust against future code changes.

2. Transforming PsiFile
The other option would be to modify PsiFile contents, so that it would contain all synthetic members, thus making it possible for the highlighter to discover it. The problem there would be that, any changes to PsiFile are reflected in the editor (right?), and with synthetic members that's not what I want. I wonder if just making corresponding synthetic psi elements be empty string is the right solution, though I haven't tested it yet. The potential extension would be in org.jetbrains.plugins.scala.lang.parser.ScalaParserDefinition#createFile, that is, just after reading psi file to enrich it with synthetic members.

3. Using SyntheticNamedElement
Talking about synthetic members, I found that there are already such creatures in the codebase: org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.SyntheticNamedElement, but there's a problem that it does not inherit from org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.ScMember, which seems like a trait for most (all?) regular Scala code stuff.
Is it feasible to make SyntheticNamedElement extend ScMember or maybe creating separate synthetic class hierarchy would be better? What do you think?
Also, org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.SyntheticClasses looked promising for adding new members, but it seems that it only deals with hardcoded, top level stuff, e.g. scala.predef. Maybe I could use it as a way for adding new Scala objects, but its limitation seems to be that it is a ProjectComponent, so it would run only once at project initialization and thus would not handle cases when new code is written in the editor (maybe it could be alleviated by setting up PsiTreeChangeListeners). Anyway, this solution alone would not handle adding new methods/fields to existing classes, because it's probably wrong to have multiple definitions of the same class..

To sum up, I lean towards option no. 2.
The thing I'm not sure is how to represent my synthetic members:
a) adjust existing synthetic stuff: SyntheticNamedElement,

b) invent my own synthetic members
c) or maybe use regular ScMember with empty string so that nothing would be displayed?

Comment actions Permalink

One of Saint-Petersburg Academic University students made fork of Scala plugin: https://github.com/OsipovStas/intellij-scala
In this fork it's possible to add scam scripts to project, which will be dinamically loaded by IDE. This scripts are able to add members to classes/comanions according to this script. There is very simple DSL for such things. I'm not ready to work with this fork to integrate into Scala plugin right now (my estimate is August). But you can take a look right now and probably collaborate on this project.

Best regards,
Alexander Podkhalyuzin.


Please sign in to leave a comment.