What is needed for a new JVM language?

This thread is a spin-off from a conversation on Twitter (https://twitter.com/breskeby/status/669635997580337152) and ate it is going to be a long post. @Rene is currently working on improving the Frege support as a external plugin and I though it would be a good time to talk about what is needed for language support. (I also have a second agenda of actually writing it up as a reference to others).

I think adding support for a new JVM language is a use-case that is as common as new languages being added to the JVM. Adding the support, however, is not trivial and information is sparse. I have seen at least three other related question on the forum related to this topic:

A lot of these focus around trying to use the new model, which is still evolving. My questions goes back to the existing langaueg support (i.e that which exists as a stable form in Gradle 2.0).

Firstly up is the task of adding the new SourceSet. I think one has but little choice to use the internal DefaultSourceDirectorySet which will also involve using the internal FileResolver. A person could implement all of the SourceDirectorySet interface, but that is far too much unnecessary work, so using DefailtSourceDirectorySet is rather obvious even though it is an internal API.

Second up is the case of having a Base plugin and a language plugin. I have found this very confusing as first reaction is why are two classes use, when one will suffice. As @Rene and @CedricChampeau pointed out to me is that the base plugin provides all the necessary functionality, where as the language plugin only adds convention for a language. This according to @CedricChampeau is to allow a script author to use a different convention (or file layout) if necessary. I can clearly see the point in this, but I think one has to guard against writing spaghetti whereby the base plugin becomes unuseable without the language plugin.

An important point to remember is that the base plugin for any JVM language implementation has to apply JavaBasePlugin (There is no BasePlugin at present that can be used as @bmuschko has mentioned in How to add a sourceSet without using any plugins).

Question #1: I am also still concerned about the above split though when I look at a number of current implementations (Groovy, Scala, Frege) is that the base plugin for each language adds the SourceSets. If responsibility of convention belongs in the language plugin why isn’t GroovyPlugin adding sourceSets { main { groovy {} } } instead of GroovyBasePlugin. Or does the issue lay within my understanding of convention?

Thirdly we the compile class which should derive from AbstractCompile. In the most simplisitic way one can just implement the compile method but running a project.javaexec, but then one misses out on a lot of good stuff that is hidden within the core language plugins. This includes easy forking and cleaning stale classes. Actually questions in this regard can get so complex, I’ll create a linked topic.