For Fedex XII I thought I'd see how far I could get with support for rudimentary Scala code in Clover.
Preparation, preparation, preparation
My attempt was not a triumph of organisation nor planning: expecting to start moving house on the Thursday I had given up plans to participate in this Fedex but instead found myself with a clear schedule on Thursday morning and Brendan telling me over IM about the progress he'd made with Clover for Groovy. Red rag to a bull...
Most of my actual Fedex time was actually spent:
- Wrestling with the crappy IDE support for Scala (Eclipse < IDEA < Netbeans)
- Reading the two dated blog posts about the neat Scala plugin compiler architecture
- Trying to grok the Scala language enough to understand the internals of the compiler
- Making rudimentary efforts to generate a "Hello, world" compiler plugin without the aid of decent IDE and running against Scala 2.7 which, turns out, is not a suitable target for compiler plugins.
So by Friday afternoon I had not much to show for my efforts. Over the last few evenings, however, I've managed to get a working Clover Scala compiler plugin.
Approach
Like Groovy, Scala has a compiler plugin architecture allowing you to intercept and rewrite source code AST at various points in the compilation process. Compilation is broken up into various phases (e.g. "parsing", "naming", "typer") and new plugins have the opportunity to request running before/after certain phases or to attach themselves straight after a given phase. The Clover Scala plugin lodges itself just after the parsing phase. Scala also has a nice mechanism for discovering plugins and allowing configuration to passed through to plugins.
Adding instrumentation instructions is mostly about inserting nodes at various points in the AST. As Brendan mentions, this approach is superior to the string-based rewriting we use for Java code because there's less heavy lifting to do but has the disadvantage of requiring complex code to generate the right AST. E.g.
to generate this code:
Integrating with the Clover database
For the purposes of this Fedex project, Clover's data model was sufficient to capture the language constructs in my test source however some notable improvements are required:
- Package -> File -> Class hierarchy do not hold for Scala (naming invariants, multiple package declarations per file). Some rework required.
- We need to introduce the concept of types other than Java classes/interfaces/enums/annotations. Scala has classes (case, sealed, final, abstract), traits and objects some of which can have the same name (e.g. class HelloWorld vs object HelloWorld) which we need to handle and differentiate in reports.
- Advanced concepts like anonymous functions may pose problems depending on where they are declared and how they are used e.g.
Getting reports to work
Like with Brendan's project, Clover's HTML reports just kinda worked with Scala code.

Next steps
As with Clover for Groovy, AST transformation is the way to go, I believe. With a reasonable amount of model refactoring to better support Scala constructs and some serious edge-case testing I think this could fairly quickly make its way into Clover.

4 Comments
Hide/Show CommentsMar 08, 2010
Christian Maslen
Hi Michael,
I know this was worked on a while ago now, but I'm very interested to see this make its way into a Clover release offering. Is there any chance of this happening?
Thanks in advance,
Christian Maslen
Mar 19, 2010
Michael Studman
Hi Christian,
We've just putting the finishing touches on Clover-for-Groovy and when that's finished we'll take a close look at what's required for Clover-for-Scala and if/when we want to schedule it. So I can't promise anything right now but do check back for any updates.
Michael.
Mar 29, 2010
Zac Thompson
Anywhere we can vote for this change? :)
Mar 29, 2010
Michael Studman
http://jira.atlassian.com/browse/CLOV-932