diff --git a/build.xml b/build.xml
index 5b4cb3db4df..31c72ab8991 100644
--- a/build.xml
+++ b/build.xml
@@ -568,6 +568,10 @@
public protected *;
}
+ -keepclassmembers class com.intellij.openapi.vfs.VirtualFile {
+ public InputStream getInputStream();
+ }
+
-keep class jet.** {
public protected *;
}
diff --git a/libraries/pom.xml b/libraries/pom.xml
index 8de54ae3fdd..d2cb17df171 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -84,6 +84,7 @@
tools/kotlin-js-library
tools/kotlin-gradle-plugin
tools/kotlin-gradle-plugin-core
+ tools/kotlin-gradle-plugin-api
tools/kotlin-android-compiler-plugin
tools/kotlin-maven-plugin
tools/kotlin-maven-plugin-test
diff --git a/libraries/tools/kotlin-android-compiler-plugin/pom.xml b/libraries/tools/kotlin-android-compiler-plugin/pom.xml
index e5b04dde929..fadf54595f8 100644
--- a/libraries/tools/kotlin-android-compiler-plugin/pom.xml
+++ b/libraries/tools/kotlin-android-compiler-plugin/pom.xml
@@ -17,7 +17,7 @@
kotlin-android-compiler-plugin
- pom
+ jar
Android compiler plugin for Kotlin
@@ -26,40 +26,95 @@
org.jetbrains.kotlin
kotlin-stdlib
${project.version}
+ provided
org.jetbrains.kotlin
- kotlin-gradle-plugin-core
+ kotlin-gradle-plugin-api
${project.version}
provided
+
+ org.jetbrains.kotlin
+ gradle-api
+ 1.6
+ provided
+
+
+ com.android.tools.build
+ gradle
+ 0.4.2
+ provided
+
+ ${project.basedir}/src/main/kotlin
+
+
+
+ ${project.basedir}/src/main/resources
+ true
+
+
+
- org.codehaus.mojo
- build-helper-maven-plugin
+ kotlin-maven-plugin
+ org.jetbrains.kotlin
+ ${project.version}
+
+
+ ${basedir}/kotlinAnnotation
+
+
+
+
+
+ compile
+ compile
+ compile
+
+
+ ${project.basedir}/src/main/kotlin
+
+
+
+
+
+ test-compile
+ test-compile
+ test-compile
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
1.7
- attach-artifacts
+ prepare
compile
-
- attach-artifact
-
-
-
- ${kotlin-sdk}/lib/android-compiler-plugin.jar
- jar
-
-
+
+
+
+
+ run
+
+
+
+
+ jetbrains-utils
+ http://repository.jetbrains.com/utils
+
+
diff --git a/libraries/tools/kotlin-android-compiler-plugin/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt b/libraries/tools/kotlin-android-compiler-plugin/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt
new file mode 100644
index 00000000000..eebf2988df8
--- /dev/null
+++ b/libraries/tools/kotlin-android-compiler-plugin/src/main/kotlin/org/jetbrains/kotlin/android/AndroidSubplugin.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2014 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.android
+
+import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
+import org.gradle.api
+import com.android.build.gradle.BaseExtension
+import java.io.File
+import org.gradle.api.tasks.compile.AbstractCompile
+import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
+
+public class AndroidSubplugin : KotlinGradleSubplugin {
+
+ override fun getExtraArguments(project: api.Project, task: AbstractCompile): List? {
+ val androidExtension = project.getExtensions().getByName("android") as? BaseExtension
+
+ if (androidExtension == null) return null
+
+ val sourceSets = androidExtension.getSourceSets()
+ val mainSourceSet = sourceSets.getByName("main")
+
+ val resourceDir = mainSourceSet.getRes().getSrcDirs().firstOrNull()
+ val manifestFile = mainSourceSet.getManifest().getSrcFile()
+
+ if (resourceDir != null) {
+ val layoutDir = File(resourceDir, "layout")
+ task.source(layoutDir)
+ return listOf(
+ SubpluginOption("androidRes", layoutDir.getAbsolutePath()),
+ SubpluginOption("androidManifest", manifestFile.getAbsolutePath())
+ )
+ }
+
+ return null
+ }
+
+ override fun getPluginName(): String {
+ return "org.jetbrains.kotlin.android"
+ }
+
+ override fun getGroupName(): String {
+ return "org.jetbrains.kotlin"
+ }
+
+ override fun getArtifactName(): String {
+ return "kotlin-android-compiler-plugin"
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-android-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/libraries/tools/kotlin-android-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
new file mode 100644
index 00000000000..3237be5f789
--- /dev/null
+++ b/libraries/tools/kotlin-android-compiler-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
@@ -0,0 +1 @@
+org.jetbrains.kotlin.android.AndroidSubplugin
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-api/pom.xml b/libraries/tools/kotlin-gradle-plugin-api/pom.xml
new file mode 100644
index 00000000000..d0332e5495f
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-api/pom.xml
@@ -0,0 +1,81 @@
+
+
+
+ 4.0.0
+
+ 1.4.1
+ 3.0.4
+
+
+
+ org.jetbrains.kotlin
+ kotlin-project
+ 0.1-SNAPSHOT
+ ../../pom.xml
+
+
+ kotlin-gradle-plugin-api
+ jar
+
+ Gradle plugin API for Kotlin
+
+
+
+ jetbrains-utils
+ http://repository.jetbrains.com/utils
+
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${project.version}
+
+
+ org.jetbrains.kotlin
+ gradle-api
+ 1.6
+ provided
+
+
+ com.android.tools.build
+ gradle
+ 0.4.2
+ provided
+
+
+
+
+ ${project.basedir}/src/main/kotlin
+
+
+
+ kotlin-maven-plugin
+ org.jetbrains.kotlin
+ ${project.version}
+
+
+ ${basedir}/kotlinAnnotation
+
+
+
+
+
+ compile
+ compile
+ compile
+
+
+
+ test-compile
+ test-compile
+ test-compile
+
+
+
+
+
+
diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
new file mode 100644
index 00000000000..971b4a75215
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010-2014 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.plugin
+
+import org.gradle.api.Project
+import org.gradle.api.tasks.compile.AbstractCompile
+
+public class SubpluginOption(val key: String, val value: String)
+
+public trait KotlinGradleSubplugin {
+ public fun getExtraArguments(project: Project, task: AbstractCompile): List?
+ public fun getPluginName(): String
+ public fun getGroupName(): String
+ public fun getArtifactName(): String
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-core/pom.xml b/libraries/tools/kotlin-gradle-plugin-core/pom.xml
index b95f9a02538..26a86bf4dab 100644
--- a/libraries/tools/kotlin-gradle-plugin-core/pom.xml
+++ b/libraries/tools/kotlin-gradle-plugin-core/pom.xml
@@ -25,6 +25,12 @@
commons-io
2.4
+
+ org.jetbrains.kotlin
+ kotlin-gradle-plugin-api
+ ${project.version}
+ provided
+
commons-lang
commons-lang
diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt
index 26a02b367f8..362a296cda9 100644
--- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt
+++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt
@@ -46,8 +46,8 @@ abstract class AbstractKotlinCompile() : AbstractCo
private val logger = Logging.getLogger(this.javaClass)
override fun getLogger() = logger
- public var resPath: String = ""
- public var manifestPath: String = ""
+ var compilerPluginClasspaths: Array = array()
+ var compilerPluginArguments: Array = array()
// override setSource to track source directory sets
override fun setSource(source: Any?) {
@@ -97,10 +97,14 @@ abstract class AbstractKotlinCompile() : AbstractCo
afterCompileHook(args)
}
- protected fun isJava(it: File): Boolean = it.extension.equalsIgnoreCase(JavaFileType.INSTANCE.getDefaultExtension())
- protected fun isKotlin(it: File): Boolean = it.extension.equalsIgnoreCase(JetFileType.INSTANCE.getDefaultExtension())
+ private fun getKotlinSources(): List = getSource().filter { it.isKotlinFile() }
- private fun getKotlinSources(): List = getSource().filter{ isKotlin(it) }
+ private fun File.isKotlinFile(): Boolean {
+ return when (FilenameUtils.getExtension(getName()).toLowerCase()) {
+ "kt", "kts" -> true
+ else -> false
+ }
+ }
private fun populateCommonArgs(args: T, sources: List) {
args.freeArgs = sources.map { it.getAbsolutePath() }
@@ -131,8 +135,8 @@ public open class KotlinCompile() : AbstractKotlinCompile()
override fun populateTargetSpecificArgs(args: K2JVMCompilerArguments) {
- args.pluginClasspaths = kotlinOptions.pluginClasspaths
- args.pluginOptions = kotlinOptions.pluginOptions
+ args.pluginClasspaths = compilerPluginClasspaths
+ args.pluginOptions = compilerPluginArguments
if (StringUtils.isEmpty(kotlinOptions.classpath)) {
val existingClasspathEntries = getClasspath().filter({ it != null && it.exists() })
@@ -161,11 +165,13 @@ public open class KotlinCompile() : AbstractKotlinCompile =
getSource()
- .filter { isJava(it) }
+ .filter { it.isJavaFile() }
.map { findSrcDirRoot(it) }
.filterNotNull()
.toSet()
+ private fun File.isJavaFile() = extension.equalsIgnoreCase(JavaFileType.INSTANCE.getDefaultExtension())
+
override fun afterCompileHook(args: K2JVMCompilerArguments) {
getLogger().debug("Copying resulting files to classes")
diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin/pom.xml
index f4229d8f4b3..836f7855f00 100644
--- a/libraries/tools/kotlin-gradle-plugin/pom.xml
+++ b/libraries/tools/kotlin-gradle-plugin/pom.xml
@@ -49,6 +49,11 @@
${project.version}
test
+
+ org.jetbrains.kotlin
+ kotlin-gradle-plugin-api
+ ${project.version}
+
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
index 14312dca5ac..f53f8cce516 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt
@@ -39,6 +39,8 @@ import groovy.lang.Closure
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.compiler.plugin.CliOption
import org.jetbrains.kotlin.android.AndroidCommandLineProcessor
+import java.util.ServiceLoader
+import org.jetbrains.kotlin.compiler.plugin.getPluginOptionString
val DEFAULT_ANNOTATIONS = "org.jebrains.kotlin.gradle.defaultAnnotations"
@@ -144,6 +146,8 @@ class Kotlin2JvmSourceSetProcessor(
}
}
}
+
+ loadSubplugins(project).addSubpluginArguments(project, kotlinTask)
}
}
@@ -304,10 +308,6 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
project.getExtensions().add(DEFAULT_ANNOTATIONS, GradleUtils(scriptHandler, project).resolveKotlinPluginDependency("kotlin-android-sdk-annotations"))
}
- private fun makePluginOption(option: CliOption, value: String): String {
- return "plugin:${AndroidCommandLineProcessor.ANDROID_COMPILER_PLUGIN_ID}:${option.name}=$value"
- }
-
private fun processVariants(variants: DefaultDomainObjectSet, project: Project, androidExt: BaseExtension): Unit {
val logger = project.getLogger()
val kotlinOptions = getExtension(androidExt, "kotlinOptions")
@@ -320,6 +320,8 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
sourceSets.getByName("androidTest")
}
+ val subpluginEnvironment = loadSubplugins(project)
+
for (variant in variants) {
if (variant is LibraryVariant || variant is ApkVariant) {
val buildTypeSourceSetName = AndroidGradleWrapper.getVariantName(variant)
@@ -330,17 +332,6 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
val javaTask = variant.getJavaCompile()!!
val variantName = variant.getName()
- val resourceDir = AndroidGradleWrapper.getResourceDirs(mainSourceSet).firstOrNull()
- val manifestFile = AndroidGradleWrapper.getManifestFile(mainSourceSet)
-
- if (resourceDir != null) {
- val layoutDir = File(resourceDir, "layout")
- kotlinOptions.pluginOptions = array(
- makePluginOption("androidRes", layoutDir.getAbsolutePath()),
- makePluginOption("androidManifest", manifestFile.getAbsolutePath())
- )
- }
-
val kotlinTaskName = "compile${variantName.capitalize()}Kotlin"
val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName)
if (kotlinOptions != null) {
@@ -400,6 +391,8 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
}
}
+ subpluginEnvironment.addSubpluginArguments(project, kotlinTask)
+
kotlinTask doFirst {
var plugin = project.getPlugins().findPlugin("android")
if (null == plugin) {
@@ -429,9 +422,57 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
val result = (obj as HasConvention).getConvention().getPlugins()[extensionName]
return result as T
}
-
}
+private fun loadSubplugins(project: Project): SubpluginEnvironment {
+ try {
+ val subplugins = ServiceLoader.load(
+ javaClass(), project.getBuildscript().getClassLoader()).toList()
+ val subpluginDependencyNames =
+ subplugins.mapTo(hashSetOf()) { it.getGroupName() + ":" + it.getArtifactName() }
+
+ val classpath = project.getBuildscript().getConfigurations().getByName("classpath")
+ val subpluginClasspaths = hashMapOf>()
+
+ for (subplugin in subplugins) {
+ val files = classpath.getDependencies()
+ .filter { subpluginDependencyNames.contains(it.getGroup() + ":" + it.getName()) }
+ .flatMap { classpath.files(it).map { it.getAbsolutePath() } }
+ subpluginClasspaths.put(subplugin, files)
+ }
+
+ return SubpluginEnvironment(subpluginClasspaths, subplugins)
+ } catch (e: NoClassDefFoundError) {
+ // Skip plugin loading if KotlinGradleSubplugin is not defined.
+ // It is true now for tests in kotlin-gradle-plugin-core.
+ return SubpluginEnvironment(mapOf(), listOf())
+ }
+}
+
+private class SubpluginEnvironment(
+ val subpluginClasspaths: Map>,
+ val subplugins: List
+) {
+
+ fun addSubpluginArguments(project: Project, compileTask: KotlinCompile) {
+ val realPluginClasspaths = arrayListOf()
+ val pluginArguments = arrayListOf()
+
+ subplugins.forEach { subplugin ->
+ val args = subplugin.getExtraArguments(project, compileTask)
+ if (args != null) {
+ realPluginClasspaths.addAll(subpluginClasspaths[subplugin])
+ for (arg in args) {
+ val option = getPluginOptionString(subplugin.getPluginName(), arg.key, arg.value)
+ pluginArguments.add(option)
+ }
+ }
+ }
+
+ compileTask.compilerPluginClasspaths = realPluginClasspaths.copyToArray()
+ compileTask.compilerPluginArguments = pluginArguments.copyToArray()
+ }
+}
open class GradleUtils(val scriptHandler: ScriptHandler, val project: ProjectInternal) {
public fun resolveDependencies(vararg coordinates: String): Collection {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/android/AndroidGradleWrapper.groovy b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/android/AndroidGradleWrapper.groovy
index 94a93f3c115..6d061483fff 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/android/AndroidGradleWrapper.groovy
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/android/AndroidGradleWrapper.groovy
@@ -46,16 +46,6 @@ class AndroidGradleWrapper {
return androidSourceSet.getJava().getSrcDirs()
}
- @NotNull
- static def Set getResourceDirs(Object androidSourceSet) {
- return androidSourceSet.getRes().getSrcDirs()
- }
-
- @NotNull
- static def File getManifestFile(Object androidSourceSet) {
- return androidSourceSet.getManifest().getSrcFile()
- }
-
@NotNull
static def List getProductFlavorsNames(ApkVariant variant) {
return variant.getProductFlavors().iterator().collect { it.getName() }