Skip to content
This repository has been archived by the owner on Aug 19, 2020. It is now read-only.

Commit

Permalink
Provide convenience closureOf<T>(T.() -> Unit)
Browse files Browse the repository at this point in the history
For interoperability with Groovy plugins and/or missing Action<T> APIs.

Resolves #103
  • Loading branch information
bamboo committed Jul 19, 2016
1 parent 07145a2 commit 950eb75
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.gradle.script.lang.kotlin

import groovy.lang.Closure

/**
* Adapts a Kotlin function to a single argument Groovy [Closure].
*
* @param T the expected type of the single argument to the closure.
* @param function the function to be adapted.
*
* @see KotlinClosure
*/
fun <T : Any> closureOf(function: T.() -> Unit): Closure<Any?> =
KotlinClosure(function)

/**
* Adapts a Kotlin function to a single argument Groovy [Closure].
*
* @param T the type of the single argument to the closure.
* @param V the return type.
* @param function the function to be adapted.
* @param owner optional owner of the Closure.
* @param thisObject optional _this Object_ of the Closure.
*
* @see Closure
*/
class KotlinClosure<in T : Any, V : Any>(
val function: T.() -> V?,
owner: Any? = null,
thisObject: Any? = null) : Closure<V?>(owner, thisObject) {

@Suppress("unused") // to be called dynamically by Groovy
fun doCall(it: T): V? =
it.function()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.gradle.script.lang.kotlin

import org.junit.Test
import kotlin.test.assertEquals

class GroovyInteroperabilityTest {

@Test
fun `can use closure with single argument call`() {
val list = arrayListOf<Int>()
closureOf<MutableList<Int>> { add(42) }.call(list)
assertEquals(42, list.first())
}

@Test
fun `can use KotlinClosure to control return type`() {
fun stringClosure(function: String.() -> String) =
KotlinClosure(function)

assertEquals(
"GROOVY",
stringClosure { toUpperCase() }.call("groovy"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ class GradleScriptKotlinIntegrationTest {
kotlinBuildScriptModel().classPath.isNotEmpty())
}

@Test
fun `can use Closure only APIs`() {

withBuildScript("""
gradle.buildFinished(closureOf<org.gradle.BuildResult> {
println("*" + action + "*") // <- BuildResult.getAction()
})
""")

assert(
build("build").output.contains("*Build*"))
}

private fun buildSrcOutput(): File =
existing("buildSrc/build/classes/main")

Expand Down Expand Up @@ -283,7 +296,7 @@ class GradleScriptKotlinIntegrationTest {
private fun gradleRunnerFor(projectDir: File): GradleRunner =
GradleRunner
.create()
.withDebug(false)
.withDebug(true)
.withGradleInstallation(customInstallation())
.withProjectDir(projectDir)

Expand Down

0 comments on commit 950eb75

Please sign in to comment.