Kotlin-dsl-samples: Reduce noise for plugin application and configuration methods

Created on 8 Jun 2016  路  13Comments  路  Source: gradle/kotlin-dsl-samples

apply<ApplicationPlugin>()

seems unnecessarily noisy. We should try to get closer to:

apply ApplicationPlugin

Also, users might be confused by the difference in sytnax between by-name and by-type methods.

tasks.getByName('compileJava') {...}
tasks.getByType<JavaCompile>() {...}

I don't fully understand why we have to use reified generics instead of using a type literal argument, which would be more regular:

tasks.getByName('compileJava') {...}
tasks.getByType(JavaCompile) {...}
superseded

Most helpful comment

My 2 垄...

I'd rather have to use ::class than relying on "passing" generic parameters to a method that takes no arguments.

apply<MyPlugin>() is worse than apply(MyPlugin::class)

tasks.getByType<JavaCompile>() is worse than tasks.getByType(JavaCompile::class)

All 13 comments

:+1: to what @oehme said. I also had comments from people that do not like the brackets syntax. It's definitely Kotlin-idiomatic, but not build script-ish.

@oehme, would you rather write

tasks.getByType(JavaCompile::class)

or

tasks.getByType<JavaCompile>()

?

Because that's the tradeoff with Kotlin class references.

I understand what you're saying about regularity but could that be the desire for familiarity speaking? In Kotlin types as arguments are regularly enclosed in angle brackets.

I prefer the bracket version over the JavaCompile::class, but I thought this project was also about improving the DSL capabilities of Kotlin (like default imports, ...). So I would put this in the same category. Kotlin could support class literals just like Groovy does.

Unfortunately the syntax is already taken. A naked type reference refers to its companion object:

class MyClass { companion object {} }
val c = MyClass
println(c) // MyClass$Companion@60e789fe

I know but here since a method takes a Class argument I think the compiler could disambiguate. At least from my point of view it seems doable.

It could disambiguate in that particular case, yes, the tradeoff would be to introduce an ambiguity thus complexity of reasoning:

class MyClass { companion object { } }

fun ky(o: Any) =  "Any"
fun ky(k: Class<*>) = "Class<*>"
println(ky(MyClass)) // ???

It doesn't feel like a good tradeoff for the language.

That's too bad. It also means that type arguments could never benefit from a potential parentheses-free method call syntax, e.g.

apply {
  plugin("foo")
}

could become

apply {
  plugin "foo"
}

Can we at least get rid of the empty parentheses in apply<FooPlugin>()? That just seems like clutter.

This is not about a syntax I'm used to. I'd be fine with a wildly different syntax from Groovy. I'm not attached to any particular style. What I care about is it being regular and free of accidental noise.

My 2 垄...

I'd rather have to use ::class than relying on "passing" generic parameters to a method that takes no arguments.

apply<MyPlugin>() is worse than apply(MyPlugin::class)

tasks.getByType<JavaCompile>() is worse than tasks.getByType(JavaCompile::class)

@bamboo mmm, wouldn't the compiler chose the most specific version, aka the Class one? A companion object is not really different from any other object. I don't see why it would introduce more ambiguity that the general case.

Actually I see where there would be an ambiguity:

val x = A // could be Class or companion object

This is really unfortunate...

I wish something like that was supported:

class Script { 
   @JvmStatic fun <T: Plugin> T.apply() {
       [email protected](this)
   }

   fun <T> apply(plugin: T) {
       println("Applying $plugin")
   }

   fun test() {
       MyPlugin.apply()
   }
}

open class Plugin
class MyPlugin: Plugin()

fun main(args: Array<String>) {
   val script = Script()
   script.test()
}

Basically the extension method needs to be static, because the plugin is not necessarily written in Kotlin (and so would most of classes in Gradle, like TaskContainer, ...), so you can't define a companion object.

Just a quick note that we're slating this issue 1.0 M3, where it'll be a theme to polish these and other syntax issues. Please keep the comments (and new issues where appropriate) coming in. Thanks all.

Superseded by #186, #168, #159, #35 and #200.

Was this page helpful?
0 / 5 - 0 ratings