Generate gradle options from compiler arguments

#KT-13633 fixed
This commit is contained in:
Alexey Tsvetkov
2016-09-23 19:57:11 +03:00
parent 2c34088859
commit 892fc63fd1
36 changed files with 972 additions and 410 deletions
@@ -25,13 +25,16 @@ import java.util.List;
public abstract class CommonCompilerArguments {
public static final String PLUGIN_OPTION_FORMAT = "plugin:<pluginId>:<optionName>=<value>";
@GradleOption(defaultValue = "\"1.0\"", possibleValues = { "\"1.0\"" })
@Argument(value = "language-version", description = "Provide source compatibility with specified language version")
@ValueDescription("<version>")
public String languageVersion;
@GradleOption(defaultValue = "false")
@Argument(value = "nowarn", description = "Generate no warnings")
public boolean suppressWarnings;
@GradleOption(defaultValue = "false")
@Argument(value = "verbose", description = "Enable verbose logging output")
public boolean verbose;
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.jetbrains.kotlin.cli.common.arguments
@Retention(AnnotationRetention.RUNTIME)
annotation class GradleOption(val defaultValue: String,
val possibleValues: Array<String> = arrayOf())
@@ -24,10 +24,12 @@ import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CA
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL;
public class K2JSCompilerArguments extends CommonCompilerArguments {
@GradleOption(defaultValue = "null")
@Argument(value = "output", description = "Output file path")
@ValueDescription("<path>")
public String outputFile;
@GradleOption(defaultValue = "true")
@Argument(value = "no-stdlib", description = "Don't use bundled Kotlin stdlib")
public boolean noStdlib;
@@ -35,25 +37,31 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
@ValueDescription("<path[,]>")
public String[] libraryFiles;
@GradleOption(defaultValue = "false")
@Argument(value = "source-map", description = "Generate source map")
public boolean sourceMap;
@GradleOption(defaultValue = "true")
@Argument(value = "meta-info", description = "Generate metadata")
public boolean metaInfo;
@GradleOption(defaultValue = "true")
@Argument(value = "kjsm", description = "Generate kjsm-files (for creating libraries)")
public boolean kjsm;
@Argument(value = "target", description = "Generate JS files for specific ECMA version (only ECMA 5 is supported)")
@ValueDescription("<version>")
@GradleOption(defaultValue = "\"v5\"", possibleValues = { "\"v5\"" })
@Argument(value = "target", description = "Generate JS files for specific ECMA version)")
@ValueDescription("{ v5 }")
public String target;
@Argument(value = "module-kind", description = "Kind of a module generated by compiler. Supported values are: plain (by default), " +
"amd, commonjs, umd.")
@GradleOption(defaultValue = "\"plain\"", possibleValues = { "\"plain\"", "\"amd\"", "\"commonjs\"", "\"umd\"" })
@Argument(value = "module-kind", description = "Kind of a module generated by compiler")
@ValueDescription("{ plain, amd, commonjs, umd }")
public String moduleKind;
@GradleOption(defaultValue = "\"" + NO_CALL + "\"", possibleValues = { "\"" + CALL + "\"", "\"" + NO_CALL + "\"" })
@Nullable
@Argument(value = "main", description = "Whether a main function should be called; default '" + CALL + "' (main function will be auto detected)")
@Argument(value = "main", description = "Whether a main function should be called")
@ValueDescription("{" + CALL + "," + NO_CALL + "}")
public String main;
@@ -28,19 +28,24 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@ValueDescription("<path>")
public String classpath;
@GradleOption(defaultValue = "false")
@Argument(value = "include-runtime", description = "Include Kotlin runtime in to resulting .jar")
public boolean includeRuntime;
@GradleOption(defaultValue = "null")
@Argument(value = "jdk-home", description = "Path to JDK home directory to include into classpath, if differs from default JAVA_HOME")
@ValueDescription("<path>")
public String jdkHome;
@GradleOption(defaultValue = "false")
@Argument(value = "no-jdk", description = "Don't include Java runtime into classpath")
public boolean noJdk;
@GradleOption(defaultValue = "true")
@Argument(value = "no-stdlib", description = "Don't include Kotlin runtime into classpath")
public boolean noStdlib;
@GradleOption(defaultValue = "true")
@Argument(value = "no-reflect", description = "Don't include Kotlin reflection implementation into classpath")
public boolean noReflect;
@@ -62,6 +67,7 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@Argument(value = "module-name", description = "Module name")
public String moduleName;
@GradleOption(defaultValue = "\"1.6\"", possibleValues = { "\"1.6\"", "\"1.8\"" })
@Argument(value = "jvm-target", description = "Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6")
@ValueDescription("<version>")
public String jvmTarget;
@@ -0,0 +1,211 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.jetbrains.kotlin.generators.arguments
import com.sampullara.cli.Argument
import org.jetbrains.kotlin.cli.common.arguments.GradleOption
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.utils.Printer
import java.io.File
import java.io.PrintStream
import kotlin.reflect.*
// Additional properties that should be included in interface
interface AdditionalGradleProperties {
@GradleOption(defaultValue = "emptyList()")
@Argument(description = "A list of additional compiler arguments")
var freeCompilerArgs: List<String>
}
fun main(args: Array<String>) {
val dslSrcDir = File("libraries/tools/kotlin-gradle-plugin-dsl/src/main/kotlin")
val dslImplDir = File("libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin")
val additionalGradleOptions = gradleOptions<AdditionalGradleProperties>()
// generate jvm interface
val jvmInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions")
val optionsFromK2JVMCompilerArguments = gradleOptions<K2JVMCompilerArguments>()
File(dslSrcDir, jvmInterfaceFqName).usePrinter {
generateInterface(jvmInterfaceFqName,
optionsFromK2JVMCompilerArguments + additionalGradleOptions)
}
// generate jvm impl
val k2JvmCompilerArgumentsFqName = FqName(K2JVMCompilerArguments::class.qualifiedName!!)
val jvmImplFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsBase")
File(dslImplDir, jvmImplFqName).usePrinter {
generateImpl(jvmImplFqName,
jvmInterfaceFqName,
k2JvmCompilerArgumentsFqName,
optionsFromK2JVMCompilerArguments)
}
// generate js interface
val jsInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions")
val optionsFromK2JSCompilerArguments = gradleOptions<K2JSCompilerArguments>()
File(dslSrcDir, jsInterfaceFqName).usePrinter {
generateInterface(jsInterfaceFqName,
optionsFromK2JSCompilerArguments +
additionalGradleOptions)
}
val k2JsCompilerArgumentsFqName = FqName(K2JSCompilerArguments::class.qualifiedName!!)
val jsImplFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJsOptionsBase")
File(dslImplDir, jsImplFqName).usePrinter {
generateImpl(jsImplFqName,
jsInterfaceFqName,
k2JsCompilerArgumentsFqName,
optionsFromK2JSCompilerArguments)
}
}
private inline fun <reified T : Any> gradleOptions(): List<KProperty1<T, *>> =
T::class.memberProperties.filter { it.findAnnotation<GradleOption>() != null }.sortedBy { it.name }
private fun File(baseDir: File, fqName: FqName): File {
val fileRelativePath = fqName.asString().replace(".", "/") + ".kt"
return File(baseDir, fileRelativePath)
}
private inline fun File.usePrinter(fn: Printer.()->Unit) {
if (!exists()) {
parentFile.mkdirs()
createNewFile()
}
PrintStream(outputStream()).use {
val printer = Printer(it)
printer.fn()
}
}
private fun Printer.generateInterface(type: FqName, properties: List<KProperty1<*, *>>) {
generateDeclaration("interface", type) {
for (property in properties) {
println()
generateDoc(property)
generatePropertyDeclaration(property)
}
}
}
private fun Printer.generateImpl(
type: FqName,
parentType: FqName,
argsType: FqName,
properties: List<KProperty1<*, *>>
) {
generateDeclaration("abstract class", type, afterType = ": $parentType") {
fun KProperty1<*, *>.backingField(): String = "${this.name}Field"
for (property in properties) {
println()
val backingField = property.backingField()
val backingFieldType = property.gradleReturnType + "?"
println("private var $backingField: $backingFieldType = null")
generatePropertyDeclaration(property, modifiers = "override")
withIndent {
println("get() = $backingField ?: ${property.gradleDefaultValue}")
println("set(value) { $backingField = value }")
}
}
println()
println("open fun updateArguments(args: $argsType) {")
withIndent {
for (property in properties) {
val backingField = property.backingField()
println("$backingField?.let { args.${property.name} = it }")
}
}
println("}")
}
println()
println("fun $argsType.fillDefaultValues() {")
withIndent {
for (property in properties) {
println("${property.name} = ${property.gradleDefaultValue}")
}
}
println("}")
}
private fun Printer.generateDeclaration(
modifiers: String,
type: FqName,
afterType: String? = null,
generateBody: Printer.()->Unit
) {
println("// DO NOT EDIT MANUALLY!")
println("// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt")
if (!type.parent().isRoot) {
println("package ${type.parent()}")
println()
}
print("$modifiers ${type.shortName()} ")
afterType?.let { print("$afterType ") }
println("{")
withIndent {
generateBody()
}
println("}")
}
private fun Printer.generatePropertyDeclaration(property: KProperty1<*, *>, modifiers: String = "") {
val returnType = property.gradleReturnType
println("$modifiers var ${property.name}: $returnType")
}
private fun Printer.generateDoc(property: KProperty1<*, *>) {
val description = property.findAnnotation<Argument>()!!.description
val possibleValues = property.gradlePossibleValues
val defaultValue = property.gradleDefaultValue
println("/**")
println(" * $description")
if (possibleValues.isNotEmpty()) {
println(" * Possible values: ${possibleValues.joinToString()}")
}
println(" * Default value: $defaultValue")
println(" */")
}
private inline fun Printer.withIndent(fn: Printer.()->Unit) {
pushIndent()
fn()
popIndent()
}
private val KProperty1<*, *>.gradlePossibleValues: Array<String>
get() = findAnnotation<GradleOption>()!!.possibleValues
private val KProperty1<*, *>.gradleDefaultValue: String
get() = findAnnotation<GradleOption>()!!.defaultValue
private val KProperty1<*, *>.gradleReturnType: String
get() {
var type = returnType.toString().substringBeforeLast("!")
if (gradleDefaultValue == "null") {
type += "?"
}
return type
}
private inline fun <reified T> KAnnotatedElement.findAnnotation(): T? =
annotations.filterIsInstance<T>().firstOrNull()
+1
View File
@@ -101,6 +101,7 @@
<module>examples/annotation-processor-example</module>
<module>tools/kotlin-gradle-plugin</module>
<module>tools/kotlin-gradle-plugin-core</module>
<module>tools/kotlin-gradle-plugin-dsl</module>
<module>tools/kotlin-gradle-plugin-api</module>
<module>tools/kotlin-android-extensions</module>
<module>tools/kotlin-maven-plugin-test</module>
@@ -31,6 +31,11 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-plugin-dsl</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <!-- required in runtime -->
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
@@ -0,0 +1,89 @@
// DO NOT EDIT MANUALLY!
// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt
package org.jetbrains.kotlin.gradle.dsl
abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions {
private var kjsmField: kotlin.Boolean? = null
override var kjsm: kotlin.Boolean
get() = kjsmField ?: true
set(value) { kjsmField = value }
private var languageVersionField: kotlin.String? = null
override var languageVersion: kotlin.String
get() = languageVersionField ?: "1.0"
set(value) { languageVersionField = value }
private var mainField: kotlin.String? = null
override var main: kotlin.String
get() = mainField ?: "noCall"
set(value) { mainField = value }
private var metaInfoField: kotlin.Boolean? = null
override var metaInfo: kotlin.Boolean
get() = metaInfoField ?: true
set(value) { metaInfoField = value }
private var moduleKindField: kotlin.String? = null
override var moduleKind: kotlin.String
get() = moduleKindField ?: "plain"
set(value) { moduleKindField = value }
private var noStdlibField: kotlin.Boolean? = null
override var noStdlib: kotlin.Boolean
get() = noStdlibField ?: true
set(value) { noStdlibField = value }
private var outputFileField: kotlin.String?? = null
override var outputFile: kotlin.String?
get() = outputFileField ?: null
set(value) { outputFileField = value }
private var sourceMapField: kotlin.Boolean? = null
override var sourceMap: kotlin.Boolean
get() = sourceMapField ?: false
set(value) { sourceMapField = value }
private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value }
private var targetField: kotlin.String? = null
override var target: kotlin.String
get() = targetField ?: "v5"
set(value) { targetField = value }
private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean
get() = verboseField ?: false
set(value) { verboseField = value }
open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments) {
kjsmField?.let { args.kjsm = it }
languageVersionField?.let { args.languageVersion = it }
mainField?.let { args.main = it }
metaInfoField?.let { args.metaInfo = it }
moduleKindField?.let { args.moduleKind = it }
noStdlibField?.let { args.noStdlib = it }
outputFileField?.let { args.outputFile = it }
sourceMapField?.let { args.sourceMap = it }
suppressWarningsField?.let { args.suppressWarnings = it }
targetField?.let { args.target = it }
verboseField?.let { args.verbose = it }
}
}
fun org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments.fillDefaultValues() {
kjsm = true
languageVersion = "1.0"
main = "noCall"
metaInfo = true
moduleKind = "plain"
noStdlib = true
outputFile = null
sourceMap = false
suppressWarnings = false
target = "v5"
verbose = false
}
@@ -0,0 +1,13 @@
package org.jetbrains.kotlin.gradle.dsl
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.js.K2JSCompiler
class KotlinJsOptionsImpl() : KotlinJsOptionsBase() {
override var freeCompilerArgs: List<String> = listOf()
override fun updateArguments(args: K2JSCompilerArguments) {
super.updateArguments(args)
K2JSCompiler().parseArguments(freeCompilerArgs.toTypedArray(), args)
}
}
@@ -0,0 +1,75 @@
// DO NOT EDIT MANUALLY!
// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt
package org.jetbrains.kotlin.gradle.dsl
abstract class KotlinJvmOptionsBase : org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions {
private var includeRuntimeField: kotlin.Boolean? = null
override var includeRuntime: kotlin.Boolean
get() = includeRuntimeField ?: false
set(value) { includeRuntimeField = value }
private var jdkHomeField: kotlin.String?? = null
override var jdkHome: kotlin.String?
get() = jdkHomeField ?: null
set(value) { jdkHomeField = value }
private var jvmTargetField: kotlin.String? = null
override var jvmTarget: kotlin.String
get() = jvmTargetField ?: "1.6"
set(value) { jvmTargetField = value }
private var languageVersionField: kotlin.String? = null
override var languageVersion: kotlin.String
get() = languageVersionField ?: "1.0"
set(value) { languageVersionField = value }
private var noJdkField: kotlin.Boolean? = null
override var noJdk: kotlin.Boolean
get() = noJdkField ?: false
set(value) { noJdkField = value }
private var noReflectField: kotlin.Boolean? = null
override var noReflect: kotlin.Boolean
get() = noReflectField ?: true
set(value) { noReflectField = value }
private var noStdlibField: kotlin.Boolean? = null
override var noStdlib: kotlin.Boolean
get() = noStdlibField ?: true
set(value) { noStdlibField = value }
private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value }
private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean
get() = verboseField ?: false
set(value) { verboseField = value }
open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments) {
includeRuntimeField?.let { args.includeRuntime = it }
jdkHomeField?.let { args.jdkHome = it }
jvmTargetField?.let { args.jvmTarget = it }
languageVersionField?.let { args.languageVersion = it }
noJdkField?.let { args.noJdk = it }
noReflectField?.let { args.noReflect = it }
noStdlibField?.let { args.noStdlib = it }
suppressWarningsField?.let { args.suppressWarnings = it }
verboseField?.let { args.verbose = it }
}
}
fun org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments.fillDefaultValues() {
includeRuntime = false
jdkHome = null
jvmTarget = "1.6"
languageVersion = "1.0"
noJdk = false
noReflect = true
noStdlib = true
suppressWarnings = false
verbose = false
}
@@ -0,0 +1,13 @@
package org.jetbrains.kotlin.gradle.dsl
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
open class KotlinJvmOptionsImpl : KotlinJvmOptionsBase() {
override var freeCompilerArgs: List<String> = listOf()
override fun updateArguments(args: K2JVMCompilerArguments) {
super.updateArguments(args)
K2JVMCompiler().parseArguments(freeCompilerArgs.toTypedArray(), args)
}
}
@@ -25,21 +25,13 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.com.intellij.ide.highlighter.JavaFileType
import org.jetbrains.kotlin.com.intellij.lang.Language
import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.com.intellij.psi.PsiClass
import org.jetbrains.kotlin.com.intellij.psi.PsiFileFactory
import org.jetbrains.kotlin.com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.com.intellij.psi.impl.PsiFileFactoryImpl
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollector
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
@@ -51,7 +43,6 @@ import org.jetbrains.kotlin.utils.LibraryUtils
import java.io.File
import java.util.*
const val DEFAULT_ANNOTATIONS = "org.jebrains.kotlin.gradle.defaultAnnotations"
const val ANNOTATIONS_PLUGIN_NAME = "org.jetbrains.kotlin.kapt"
const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val CACHES_DIR_NAME = "caches"
@@ -61,12 +52,7 @@ const val USING_EXPERIMENTAL_INCREMENTAL_MESSAGE = "Using experimental kotlin in
abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCompile() {
abstract protected val compiler: CLICompiler<T>
abstract protected fun createBlankArgs(): T
open protected fun beforeCompileHook(args: T) {
}
open protected fun afterCompileHook(args: T) {
}
abstract protected fun populateTargetSpecificArgs(args: T)
abstract protected fun populateCompilerArguments(): T
// indicates that task should compile kotlin incrementally if possible
// it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build)
@@ -79,12 +65,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
System.setProperty("kotlin.incremental.compilation.experimental", value.toString())
}
var kotlinOptions: T = createBlankArgs()
var compilerCalled: Boolean = false
// TODO: consider more reliable approach (see usage)
var anyClassesCompiled: Boolean = false
var friendTaskName: String? = null
var javaOutputDir: File? = null
var moduleName: String = "${project.name}-${this.name}"
private val loggerInstance = Logging.getLogger(this.javaClass)
override fun getLogger() = loggerInstance
@@ -105,15 +91,13 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
}
logger.kotlinDebug("modified ${modified.joinToString { it.path }}")
logger.kotlinDebug("removed ${removed.joinToString { it.path }}")
val args = createBlankArgs()
val sources = getKotlinSources()
if (sources.isEmpty()) {
logger.warn("No Kotlin files found, skipping Kotlin compiler task")
return
}
populateCommonArgs(args)
populateTargetSpecificArgs(args)
val args = populateCompilerArguments()
compilerCalled = true
callCompiler(args, sources, inputs.isIncremental, modified, removed)
}
@@ -123,35 +107,17 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
protected fun File.isKotlinFile(): Boolean =
FilenameUtils.isExtension(name.toLowerCase(), listOf("kt", "kts"))
private fun populateSources(args:T, sources: List<File>) {
args.freeArgs = sources.map { it.absolutePath }
}
private fun populateCommonArgs(args: T) {
args.suppressWarnings = kotlinOptions.suppressWarnings
args.verbose = kotlinOptions.verbose
args.version = kotlinOptions.version
args.noInline = kotlinOptions.noInline
}
protected open fun callCompiler(args: T, sources: List<File>, isIncremental: Boolean, modified: List<File>, removed: List<File>) {
populateSources(args, sources)
val messageCollector = GradleMessageCollector(logger)
logger.debug("Calling compiler")
val exitCode = compiler.exec(messageCollector, Services.EMPTY, args)
when (exitCode) {
ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details")
ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details")
}
}
protected abstract fun callCompiler(args: T, sources: List<File>, isIncremental: Boolean, modified: List<File>, removed: List<File>)
}
open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
override val compiler = K2JVMCompiler()
override fun createBlankArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
var parentKotlinOptionsImpl: KotlinJvmOptionsImpl? = null
private val kotlinOptionsImpl = KotlinJvmOptionsImpl()
override val kotlinOptions: KotlinJvmOptions
get() = kotlinOptionsImpl
private val sourceRoots = HashSet<File>()
@@ -189,68 +155,37 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
// created only if kapt2 is active
var sourceAnnotationsRegistry: SourceAnnotationsRegistry? = null
override fun populateTargetSpecificArgs(args: K2JVMCompilerArguments) {
logger.kotlinDebug("args.freeArgs = ${args.freeArgs}")
override fun populateCompilerArguments(): K2JVMCompilerArguments {
val args = K2JVMCompilerArguments().apply { fillDefaultValues() }
if (kotlinOptions.classpath?.isNotBlank() ?: false) {
logger.warn("kotlinOptions.classpath will be ignored")
}
if (kotlinOptions.destination?.isNotBlank() ?: false) {
logger.warn("kotlinOptions.destination will be ignored")
}
logger.kotlinDebug("destinationDir = $destinationDir")
val extraProperties = extensions.extraProperties
args.pluginClasspaths = pluginOptions.classpath.toTypedArray()
logger.kotlinDebug("args.pluginClasspaths = ${args.pluginClasspaths.joinToString(File.pathSeparator)}")
handleKaptProperties()
args.pluginClasspaths = pluginOptions.classpath.toTypedArray()
args.pluginOptions = pluginOptions.arguments.toTypedArray()
logger.kotlinDebug("args.pluginOptions = ${args.pluginOptions.joinToString(File.pathSeparator)}")
args.moduleName = moduleName
args.noStdlib = true
args.jdkHome = kotlinOptions.jdkHome
args.noJdk = kotlinOptions.noJdk
args.noInline = kotlinOptions.noInline
args.noOptimize = kotlinOptions.noOptimize
args.noCallAssertions = kotlinOptions.noCallAssertions
args.noParamAssertions = kotlinOptions.noParamAssertions
args.moduleName = kotlinOptions.moduleName ?: extraProperties.getOrNull<String>("defaultModuleName")
args.languageVersion = kotlinOptions.languageVersion
args.jvmTarget = kotlinOptions.jvmTarget
args.allowKotlinPackage = kotlinOptions.allowKotlinPackage
args.reportPerf = kotlinOptions.reportPerf
args.inheritMultifileParts = kotlinOptions.inheritMultifileParts
args.declarationsOutputPath = kotlinOptions.declarationsOutputPath
args.scriptTemplates = kotlinOptions.scriptTemplates
if (args.scriptTemplates?.isNotEmpty() ?: false) {
logger.kotlinDebug { "scriptTemplates = ${args.scriptTemplates.joinToString()}" }
}
fun addFriendPathForTestTask(friendKotlinTaskName: String) {
val friendTask = project.getTasksByName(friendKotlinTaskName, /* recursive = */false).firstOrNull() as? KotlinCompile ?: return
friendTaskName?.let addFriendPathForTestTask@ { friendKotlinTaskName ->
val friendTask = project.getTasksByName(friendKotlinTaskName, /* recursive = */false).firstOrNull() as? KotlinCompile ?: return@addFriendPathForTestTask
args.friendPaths = arrayOf(friendTask.javaOutputDir!!.absolutePath)
args.moduleName = friendTask.kotlinOptions.moduleName ?: friendTask.extensions.extraProperties.getOrNull<String>("defaultModuleName")
args.moduleName = friendTask.moduleName
logger.kotlinDebug("java destination directory for production = ${friendTask.javaOutputDir}")
}
logger.kotlinDebug { "friendTaskName = $friendTaskName" }
friendTaskName?.let { addFriendPathForTestTask(it) }
logger.kotlinDebug("args.moduleName = ${args.moduleName}")
parentKotlinOptionsImpl?.updateArguments(args)
kotlinOptionsImpl.updateArguments(args)
fun dumpPaths(files: Iterable<File>): String =
"[${files.map { it.canonicalPath }.sorted().joinToString(prefix = "\n\t", separator = ",\n\t")}]"
logger.kotlinDebug { "$name destinationDir = $destinationDir" }
logger.kotlinDebug { "$name source roots: ${dumpPaths(sourceRoots)}" }
logger.kotlinDebug { "$name java source roots: ${dumpPaths(getJavaSourceRoots())}" }
return args
}
override fun callCompiler(args: K2JVMCompilerArguments, sources: List<File>, isIncrementalRequested: Boolean, modified: List<File>, removed: List<File>) {
val rootProjectDir = project.rootProject.projectDir
fun projectRelativePath(file: File) =
file.toRelativeString(project.rootProject.projectDir)
fun projectRelativePath(f: File) = f.toRelativeString(rootProjectDir)
fun filesToString(files: Iterable<File>) =
"[" + files.map(::projectRelativePath).sorted().joinToString(separator = ", \n") + "]"
@@ -428,7 +363,7 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
// can be empty if only removed sources are present
if (sourcesToCompile.isNotEmpty()) {
logger.kotlinInfo("compile iteration: ${sourcesToCompile.joinToString { projectRelativePath(it) }}")
logger.kotlinInfo("compile iteration: ${sourcesToCompile.joinToString(transform = ::projectRelativePath)}")
}
val (existingSource, nonExistingSource) = sourcesToCompile.partition { it.isFile }
@@ -537,7 +472,8 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
}
}
logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}")
logger.kotlinDebug("compiling with args: ${ArgumentUtils.convertArgumentsToStringList(args)}")
logger.kotlinDebug("compiling with classpath: ${compileClasspath.toList().sorted().joinToString()}")
val compileServices = makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus, sourceAnnotationsRegistry)
val exitCode = compiler.exec(messageCollector, compileServices, args)
return CompileChangedResults(
@@ -583,7 +519,8 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
}
try {
logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}")
logger.kotlinDebug("compiling with args: ${ArgumentUtils.convertArgumentsToStringList(args)}")
logger.kotlinDebug("compiling with classpath: ${compileClasspath.toList().sorted().joinToString()}")
return compiler.exec(messageCollector, services, args)
}
finally {
@@ -615,7 +552,7 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
private fun File.isJavaFile() =
extension.equals(JavaFileType.INSTANCE.defaultExtension, ignoreCase = true)
private fun File.isKapt2GeneratedDirectory(): Boolean {
if (!kapt2GeneratedSourcesDir.isDirectory) return false
return FileUtil.isAncestor(kapt2GeneratedSourcesDir, this, /* strict = */ false)
@@ -671,71 +608,51 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
}
}
open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>() {
open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(), KotlinJsCompile {
override val compiler = K2JSCompiler()
private val kotlinOptionsImpl = KotlinJsOptionsImpl()
override val kotlinOptions: KotlinJsOptions
get() = kotlinOptionsImpl
override fun createBlankArgs(): K2JSCompilerArguments {
val args = K2JSCompilerArguments()
args.libraryFiles = arrayOf<String>() // defaults to null
args.metaInfo = true
args.kjsm = true
return args
}
fun addLibraryFiles(vararg fs: String) {
kotlinOptions.libraryFiles += fs
}
fun addLibraryFiles(vararg fs: File) {
val strs = fs.map { it.path }.toTypedArray()
addLibraryFiles(*strs)
}
@Suppress("unused")
val outputFile: String?
get() = kotlinOptions.outputFile
val sourceMapDestinationDir: File
get() = File(outputFile).let { if (it.isDirectory) it else it.parentFile!! }
val sourceMap: Boolean
get() = kotlinOptions.sourceMap
get() = kotlinOptions.outputFile
init {
outputs.file(MethodClosure(this, "getOutputFile"))
}
override fun populateTargetSpecificArgs(args: K2JSCompilerArguments) {
args.noStdlib = true
args.outputFile = outputFile
args.outputPrefix = kotlinOptions.outputPrefix
args.outputPostfix = kotlinOptions.outputPostfix
args.metaInfo = kotlinOptions.metaInfo
args.kjsm = kotlinOptions.kjsm
args.moduleKind = kotlinOptions.moduleKind
override fun populateCompilerArguments(): K2JSCompilerArguments {
val args = K2JSCompilerArguments().apply { fillDefaultValues() }
args.libraryFiles = project.configurations.getByName("compile")
.filter { LibraryUtils.isKotlinJavascriptLibrary(it) }
.map { it.canonicalPath }
.toTypedArray()
kotlinOptionsImpl.updateArguments(args)
return args
}
val kotlinJsLibsFromDependencies =
project.configurations.getByName("compile")
.filter { LibraryUtils.isKotlinJavascriptLibrary(it) }
.map { it.absolutePath }
args.libraryFiles = kotlinOptions.libraryFiles + kotlinJsLibsFromDependencies
args.target = kotlinOptions.target
args.sourceMap = kotlinOptions.sourceMap
override fun callCompiler(args: K2JSCompilerArguments, sources: List<File>, isIncremental: Boolean, modified: List<File>, removed: List<File>) {
val messageCollector = GradleMessageCollector(logger)
logger.debug("Calling compiler")
destinationDir.mkdirs()
args.freeArgs = args.freeArgs + sources.map { it.absolutePath }
if (args.outputFile == null) {
throw GradleException("$name.kotlinOptions.outputFile should be specified.")
}
val outputDir = File(args.outputFile).let { if (it.isDirectory) it else it.parentFile!! }
if (!outputDir.exists()) {
if (!outputDir.mkdirs()) {
throw GradleException("Failed to create output directory ${outputDir} or one of its ancestors")
logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}")
val exitCode = compiler.exec(messageCollector, Services.EMPTY, args)
when (exitCode) {
ExitCode.OK -> {
logger.kotlinInfo("Compilation succeeded")
}
ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details")
ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details")
else -> throw GradleException("Unexpected exit code: $exitCode")
}
logger.debug("$name set libraryFiles to ${args.libraryFiles.joinToString(",")}")
logger.debug("$name set outputFile to ${args.outputFile}")
}
}
@@ -0,0 +1 @@
local-repo
@@ -0,0 +1,104 @@
# Module kotlin-gradle-plugin-dsl
`kotlin-gradle-plugin` artifact provides multiple plugins.
### kotlin
How to apply:
```
apply plugin: 'kotlin'
```
Tasks:
| Name | Type | Description
|------------------------------|--------------------|---------------|
| compileKotlin | [KotlinJvmCompile] | A task is created for `main` source set |
| compileTestKotlin | [KotlinJvmCompile] | A task is created for `test` source set |
| compile*SourceSetName*Kotlin | [KotlinJvmCompile] | A task is created for each additional source set |
Each [KotlinJvmCompile] task provides `kotlinOptions` ([KotlinJvmOptions]) extension:
```
compileKotlin {
kotlinOptions {
noStdlib = true
}
// kotlinOptions.noStdlib = true
}
```
### kotlin-android
A plugin that should be used for Android development.
How to apply:
```
apply plugin: 'kotlin-android'
```
Tasks:
| Name | Type | Description
|------------------------------|--------------------|---------------|
| compile*VariantName*Kotlin | [KotlinJvmCompile] | A task is created for each variant |
Note that tasks are created after evaluation, so all references to tasks should be done in `afterEvaluate` section:
```
afterEvaluate {
compileDebugKotlin {
kotlinOptions {
noStdlib = true
}
}
}
```
Android plugin also adds `kotlinOptions` extension to `android` section to set options for all kotlin tasks:
```
android {
kotlinOptions {
noStdlib = true
}
}
```
Task's `kotlinOptions` "override" ones in `android` section:
```
android {
kotlinOptions {
noStdlib = true
}
}
afterEvaluate {
compileDebugKotlin {
kotlinOptions {
noStdlib = false
}
}
}
// compileProductionKotlin.noStdlib == true
// compileDebugKotlin.noStdlib == false
```
### kotlin2js
How to apply:
```
apply plugin: 'kotlin2js'
```
Tasks:
| Name | Type | Description
|--------------------------------|--------------------|---------------|
| compileKotlin2Js | [KotlinJsCompile] | A task is created for `main` source set |
| compileTestKotlin2Js | [KotlinJsCompile] | A task is created for `test` source set |
| compile*SourceSetName*Kotlin2Js| [KotlinJsCompile] | A task is created for each additional source set |
Each [KotlinJsCompile] task provides `kotlinOptions` ([KotlinJsOptions]) extension:
```
compileKotlin2Js {
kotlinOptions {
noStdlib = true
}
// kotlinOptions.noStdlib = true
}
```
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.version>3.0.4</maven.version>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-project</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>kotlin-gradle-plugin-dsl</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-plugin-api</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>gradle-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-compiler-embeddable</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${project.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals><goal>compile</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
<version>0.9.9</version>
<executions>
<execution>
<phase>pre-site</phase>
<goals>
<goal>dokka</goal>
</goals>
</execution>
</executions>
<configuration>
<outputFormat>markdown</outputFormat>
<includes>
<include>
${project.basedir}/Module.md
</include>
</includes>
<sourceLinks>
<link>
<dir>${project.basedir}/src/main/kotlin</dir>
<url>http://github.com/me/myrepo</url>
</link>
</sourceLinks>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jetbrains-utils</id>
<url>http://repository.jetbrains.com/utils</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jcenter</id>
<name>JCenter</name>
<url>https://jcenter.bintray.com/</url>
</pluginRepository>
</pluginRepositories>
</project>
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.jetbrains.kotlin.gradle.dsl
import groovy.lang.Closure
import org.gradle.api.Task
interface KotlinCompile<T> : Task {
val kotlinOptions: T
fun kotlinOptions(fn: T.() -> Unit) {
kotlinOptions.fn()
}
fun kotlinOptions(fn: Closure<*>) {
fn.delegate = kotlinOptions
fn.call()
}
}
interface KotlinJsCompile : KotlinCompile<KotlinJsOptions>
interface KotlinJvmCompile : KotlinCompile<KotlinJvmOptions>
@@ -0,0 +1,82 @@
// DO NOT EDIT MANUALLY!
// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt
package org.jetbrains.kotlin.gradle.dsl
interface KotlinJsOptions {
/**
* Generate kjsm-files (for creating libraries)
* Default value: true
*/
var kjsm: kotlin.Boolean
/**
* Provide source compatibility with specified language version
* Possible values: "1.0"
* Default value: "1.0"
*/
var languageVersion: kotlin.String
/**
* Whether a main function should be called
* Possible values: "call", "noCall"
* Default value: "noCall"
*/
var main: kotlin.String
/**
* Generate metadata
* Default value: true
*/
var metaInfo: kotlin.Boolean
/**
* Kind of a module generated by compiler
* Possible values: "plain", "amd", "commonjs", "umd"
* Default value: "plain"
*/
var moduleKind: kotlin.String
/**
* Don't use bundled Kotlin stdlib
* Default value: true
*/
var noStdlib: kotlin.Boolean
/**
* Output file path
* Default value: null
*/
var outputFile: kotlin.String?
/**
* Generate source map
* Default value: false
*/
var sourceMap: kotlin.Boolean
/**
* Generate no warnings
* Default value: false
*/
var suppressWarnings: kotlin.Boolean
/**
* Generate JS files for specific ECMA version)
* Possible values: "v5"
* Default value: "v5"
*/
var target: kotlin.String
/**
* Enable verbose logging output
* Default value: false
*/
var verbose: kotlin.Boolean
/**
* A list of additional compiler arguments
* Default value: emptyList()
*/
var freeCompilerArgs: kotlin.collections.List<kotlin.String>
}
@@ -0,0 +1,68 @@
// DO NOT EDIT MANUALLY!
// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt
package org.jetbrains.kotlin.gradle.dsl
interface KotlinJvmOptions {
/**
* Include Kotlin runtime in to resulting .jar
* Default value: false
*/
var includeRuntime: kotlin.Boolean
/**
* Path to JDK home directory to include into classpath, if differs from default JAVA_HOME
* Default value: null
*/
var jdkHome: kotlin.String?
/**
* Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6
* Possible values: "1.6", "1.8"
* Default value: "1.6"
*/
var jvmTarget: kotlin.String
/**
* Provide source compatibility with specified language version
* Possible values: "1.0"
* Default value: "1.0"
*/
var languageVersion: kotlin.String
/**
* Don't include Java runtime into classpath
* Default value: false
*/
var noJdk: kotlin.Boolean
/**
* Don't include Kotlin reflection implementation into classpath
* Default value: true
*/
var noReflect: kotlin.Boolean
/**
* Don't include Kotlin runtime into classpath
* Default value: true
*/
var noStdlib: kotlin.Boolean
/**
* Generate no warnings
* Default value: false
*/
var suppressWarnings: kotlin.Boolean
/**
* Enable verbose logging output
* Default value: false
*/
var verbose: kotlin.Boolean
/**
* A list of additional compiler arguments
* Default value: emptyList()
*/
var freeCompilerArgs: kotlin.collections.List<kotlin.String>
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.com.intellij.psi.PsiFileFactory
import org.jetbrains.kotlin.com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.com.intellij.psi.impl.PsiFileFactoryImpl
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
@@ -44,7 +45,7 @@ fun Project.initKapt(
javaTask: AbstractCompile,
kaptManager: AnnotationProcessingManager,
variantName: String,
kotlinOptions: Any?,
kotlinOptions: KotlinJvmOptionsImpl?,
subpluginEnvironment: SubpluginEnvironment,
tasksProvider: KotlinTasksProvider
): KotlinCompile? {
@@ -102,7 +103,7 @@ fun Project.initKapt(
private fun Project.createKotlinAfterJavaTask(
javaTask: AbstractCompile,
kotlinTask: KotlinCompile,
kotlinOptions: Any?,
kotlinOptions: KotlinJvmOptionsImpl?,
tasksProvider: KotlinTasksProvider
): KotlinCompile {
val kotlinAfterJavaTask = with (tasksProvider.createKotlinJVMTask(this, kotlinTask.name + KOTLIN_AFTER_JAVA_TASK_SUFFIX)) {
@@ -113,10 +114,8 @@ private fun Project.createKotlinAfterJavaTask(
kotlinAfterJavaTask.dependsOn(javaTask)
javaTask.finalizedByIfNotFailed(kotlinAfterJavaTask)
kotlinAfterJavaTask.extensions.extraProperties.set("defaultModuleName", "${project.name}-${kotlinTask.name}")
if (kotlinOptions != null) {
kotlinAfterJavaTask.setProperty("kotlinOptions", kotlinOptions)
}
kotlinAfterJavaTask.moduleName = kotlinTask.moduleName
kotlinAfterJavaTask.parentKotlinOptionsImpl = kotlinOptions
return kotlinAfterJavaTask
}
@@ -19,7 +19,7 @@ import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import org.jetbrains.kotlin.gradle.internal.Kapt2GradleSubplugin
import org.jetbrains.kotlin.gradle.internal.Kapt2KotlinGradleSubplugin
@@ -38,7 +38,7 @@ val KOTLIN_DSL_NAME = "kotlin"
val KOTLIN_JS_DSL_NAME = "kotlin2js"
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
val project: Project,
val javaBasePlugin: JavaBasePlugin,
val sourceSet: SourceSet,
@@ -82,7 +82,7 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
logger.kotlinDebug("Creating kotlin compile task $name")
val kotlinCompile = doCreateTask(project, name)
kotlinCompile.description = taskDescription
kotlinCompile.extensions.extraProperties.set("defaultModuleName", "${project.name}-$name")
kotlinCompile.moduleName = "${project.name}-$name"
kotlinCompile.mapClasspath { sourceSet.compileClasspath }
kotlinCompile.destinationDir = defaultKotlinDestinationDir
return kotlinCompile
@@ -181,11 +181,9 @@ class Kotlin2JsSourceSetProcessor(
override val defaultKotlinDestinationDir: File
get() = File(project.buildDir, "kotlin2js/${sourceSetName}")
private val clean = project.tasks.findByName("clean")
private val build = project.tasks.findByName("build")
override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile =
tasksProvider.createKotlinJSTask(project, taskName)
@@ -200,7 +198,7 @@ class Kotlin2JsSourceSetProcessor(
private fun createCleanSourceMapTask() {
val taskName = sourceSet.getTaskName("clean", "sourceMap")
val task = project.tasks.create(taskName, Delete::class.java)
task.onlyIf { kotlinTask.property("sourceMap") as Boolean }
task.onlyIf { kotlinTask.kotlinOptions.sourceMap }
task.delete(object : Closure<String>(this) {
override fun call(): String? = (kotlinTask.property("outputFile") as String) + ".map"
})
@@ -289,7 +287,7 @@ open class KotlinAndroidPlugin(
aptConfigurations.put(sourceSet.name, project.createAptConfiguration(sourceSet.name, kotlinPluginVersion))
}
val kotlinOptions = K2JVMCompilerArguments()
val kotlinOptions = KotlinJvmOptionsImpl()
kotlinOptions.noJdk = true
ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions)
@@ -314,7 +312,7 @@ open class KotlinAndroidPlugin(
androidExt: BaseExtension,
androidPlugin: BasePlugin,
aptConfigurations: Map<String, Configuration>,
kotlinOptions: K2JVMCompilerArguments
rootKotlinOptions: KotlinJvmOptionsImpl
) {
val logger = project.logger
val subpluginEnvironment = loadSubplugins(project)
@@ -332,9 +330,7 @@ open class KotlinAndroidPlugin(
val kotlinTaskName = "compile${variantDataName.capitalize()}Kotlin"
// todo: Investigate possibility of creating and configuring kotlinTask before evaluation
val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName)
kotlinTask.extensions.extraProperties.set("defaultModuleName", "${project.name}-$kotlinTaskName")
kotlinTask.kotlinOptions = kotlinOptions
kotlinTask.parentKotlinOptionsImpl = rootKotlinOptions
// store kotlin classes in separate directory. They will serve as class-path to java compiler
kotlinTask.destinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName")
@@ -373,7 +369,7 @@ open class KotlinAndroidPlugin(
aptFiles.toSet(), aptOutputDir, aptWorkingDir, variantData)
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
variantDataName, kotlinOptions, subpluginEnvironment, tasksProvider)
variantDataName, rootKotlinOptions, subpluginEnvironment, tasksProvider)
}
configureSources(kotlinTask, variantData)
@@ -118,23 +118,6 @@ fun getSomething() = 10
}
}
@Test
fun testModuleNameAndroid() {
val project = Project("AndroidProject", gradleVersion)
project.build("build") {
assertContains(
"args.moduleName = Lib-compileReleaseKotlin",
"args.moduleName = Lib-compileDebugKotlin",
"args.moduleName = Android-compileFlavor1DebugKotlin",
"args.moduleName = Android-compileFlavor2DebugKotlin",
"args.moduleName = Android-compileFlavor1JnidebugKotlin",
"args.moduleName = Android-compileFlavor2JnidebugKotlin",
"args.moduleName = Android-compileFlavor1ReleaseKotlin",
"args.moduleName = Android-compileFlavor2ReleaseKotlin")
}
}
@Test
fun testAndroidDaggerIC() {
val project = Project("AndroidDaggerProject", gradleVersion)
@@ -1,3 +1,19 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
@@ -26,37 +26,14 @@ class SimpleKotlinGradleIT : BaseGradleIT() {
}
@Test
fun testSuppressWarningsAndVersionInVerboseMode() {
val project = Project("suppressWarningsAndVersion", GRADLE_VERSION)
fun testSuppressWarnings() {
val project = Project("suppressWarnings", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin", "i: Kotlin Compiler version", "v: Using Kotlin home directory")
assertContains(":compileKotlin")
assertNotContains("w:")
}
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
assertNotContains("w:")
}
}
@Test
fun testSuppressWarningsAndVersionInNonVerboseMode() {
val project = Project("suppressWarningsAndVersion", GRADLE_VERSION, minLogLevel = LogLevel.INFO)
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin", "i: Kotlin Compiler version")
assertNotContains("w:", "v:")
}
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
assertNotContains("w:", "v:")
}
}
@Test
@@ -66,29 +43,6 @@ class SimpleKotlinGradleIT : BaseGradleIT() {
}
}
@Test
fun testKotlinCustomModuleName() {
Project("moduleNameCustom", GRADLE_VERSION).build("build") {
assertSuccessful()
assertContains("args.moduleName = myTestName")
}
}
@Test
fun testKotlinDefaultModuleName() {
Project("moduleNameDefault", GRADLE_VERSION).build("build") {
assertSuccessful()
assertContains("args.moduleName = moduleNameDefault-compileKotlin")
}
}
@Test
fun testAdvancedOptions() {
Project("advancedOptions", GRADLE_VERSION).build("build") {
assertSuccessful()
}
}
@Test
fun testKotlinExtraJavaSrc() {
Project("additionalJavaSrc", GRADLE_VERSION).build("build") {
@@ -1,3 +1,19 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder
@@ -44,4 +44,8 @@ android {
}
publishNonDefault true
kotlinOptions {
noJdk = true
}
}
@@ -1,52 +0,0 @@
buildscript {
repositories {
mavenCentral()
maven {
url 'file://' + pathToKotlinPlugin
}
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1-SNAPSHOT'
}
}
apply plugin: "kotlin"
sourceSets {
main {
kotlin {
srcDir 'src'
}
}
}
repositories {
maven {
url 'file://' + pathToKotlinPlugin
}
mavenCentral()
}
dependencies {
compile 'com.google.guava:guava:12.0'
testCompile 'org.testng:testng:6.8'
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1-SNAPSHOT'
}
test {
useTestNG()
}
compileKotlin {
kotlinOptions.noInline = true
kotlinOptions.noOptimize = true
kotlinOptions.noCallAssertions = true
kotlinOptions.noParamAssertions = true
}
task wrapper(type: Wrapper) {
gradleVersion="1.4"
}
@@ -1,13 +0,0 @@
package demo
import java.util.ArrayList
class KotlinGreetingJoiner() {
val names = ArrayList<String?>()
fun addName(name : String?): Unit{
names.add(name)
}
}
@@ -32,7 +32,9 @@ dependencies {
}
compileKotlin {
kotlinOptions.languageVersion = "1.0"
kotlinOptions {
languageVersion = "1.0"
}
}
task wrapper(type: Wrapper) {
@@ -1,38 +0,0 @@
buildscript {
repositories {
mavenCentral()
maven {
url 'file://' + pathToKotlinPlugin
}
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1-SNAPSHOT'
}
}
apply plugin: "kotlin"
repositories {
maven {
url 'file://' + pathToKotlinPlugin
}
mavenCentral()
}
dependencies {
testCompile 'org.testng:testng:6.8'
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1-SNAPSHOT'
}
test {
useTestNG()
}
compileKotlin {
kotlinOptions.moduleName = "myTestName"
}
task wrapper(type: Wrapper) {
gradleVersion="1.4"
}
@@ -1,9 +0,0 @@
package demo
public fun isModuleFileExists(): Boolean {
val systemClassLoader = ClassLoader.getSystemClassLoader()
val moduleFile = "META-INF/myTestName.kotlin_module"
val resourceAsStream = systemClassLoader.getResourceAsStream(moduleFile)
return resourceAsStream != null
}
@@ -1,11 +0,0 @@
package demo
import org.testng.Assert.assertTrue
import org.testng.annotations.Test as test
class TestSource() {
@test fun f() {
assertTrue(isModuleFileExists(), "Kotlin module file should exists")
}
}
@@ -1,33 +0,0 @@
buildscript {
repositories {
mavenCentral()
maven {
url 'file://' + pathToKotlinPlugin
}
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1-SNAPSHOT'
}
}
apply plugin: "kotlin"
repositories {
maven {
url 'file://' + pathToKotlinPlugin
}
mavenCentral()
}
dependencies {
testCompile 'org.testng:testng:6.8'
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1-SNAPSHOT'
}
test {
useTestNG()
}
task wrapper(type: Wrapper) {
gradleVersion="1.4"
}
@@ -1,10 +0,0 @@
package demo
public fun isModuleFileExists(): Boolean {
val systemClassLoader = ClassLoader.getSystemClassLoader()
val moduleFile = "META-INF/moduleNameDefault-compileKotlin.kotlin_module"
val resourceAsStream = systemClassLoader.getResourceAsStream(moduleFile)
return resourceAsStream != null
}
@@ -1,11 +0,0 @@
package demo
import org.testng.Assert.assertTrue
import org.testng.annotations.Test as test
class TestSource() {
@test fun f() {
assertTrue(isModuleFileExists(), "Kotlin module file should exists")
}
}
@@ -31,7 +31,6 @@ repositories {
compileKotlin {
kotlinOptions.suppressWarnings = true
kotlinOptions.version = true
}