aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.idea/compiler.xml15
-rw-r--r--.idea/modules.xml3
-rw-r--r--.idea/runConfigurations/All_tests.xml7
-rw-r--r--.idea/runConfigurations/Core_tests.xml26
-rw-r--r--.idea/runConfigurations/Gradle_integration_tests.xml26
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt70
-rw-r--r--runners/android-gradle-plugin/build.gradle3
-rw-r--r--runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt54
-rw-r--r--runners/build.gradle2
-rw-r--r--runners/gradle-integration-tests/build.gradle45
-rw-r--r--runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java39
-rw-r--r--runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java6
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt108
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt66
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt58
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt51
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt54
-rw-r--r--runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt59
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/build.gradle50
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml26
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java34
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt28
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 9397 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 5237 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 14383 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml24
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml24
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml6
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml6
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml5
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml10
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml20
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/build.gradle21
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/fileTree.txt19
-rw-r--r--runners/gradle-integration-tests/testData/androidApp/settings.gradle3
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle75
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml9
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt14
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml24
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml3
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml26
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java34
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt28
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 9397 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 5237 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 14383 bytes
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml24
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml24
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml6
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml6
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml5
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml10
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml20
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle21
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt45
-rw-r--r--runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle3
-rw-r--r--runners/gradle-integration-tests/testData/basic/build.gradle39
-rw-r--r--runners/gradle-integration-tests/testData/basic/fileTree.txt30
-rw-r--r--runners/gradle-integration-tests/testData/basic/settings.gradle1
-rw-r--r--runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt41
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle32
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt33
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle3
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle6
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt31
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle7
-rw-r--r--runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt31
-rw-r--r--runners/gradle-plugin/src/main/kotlin/main.kt183
-rw-r--r--runners/maven-plugin/build.gradle3
-rw-r--r--runners/maven-plugin/pom.tpl.xml2
-rw-r--r--settings.gradle10
73 files changed, 1677 insertions, 127 deletions
diff --git a/.gitignore b/.gitignore
index fd10801e..a4f7f56b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,4 +86,7 @@ gradle-app.setting
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
-!lib/*.jar \ No newline at end of file
+!lib/*.jar
+
+local.properties
+android.local.properties \ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 3826f563..634de1d7 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -20,10 +20,6 @@
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
- <module name="__main" target="1.8" />
- <module name="__test" target="1.8" />
- <module name="all_main" target="1.8" />
- <module name="all_test" target="1.8" />
<module name="android-gradle-plugin_main" target="1.6" />
<module name="android-gradle-plugin_test" target="1.6" />
<module name="ant_main" target="1.5" />
@@ -34,15 +30,10 @@
<module name="cli_test" target="1.5" />
<module name="core_main" target="1.5" />
<module name="core_test" target="1.5" />
- <module name="dokka-android-gradle-plugin_main" target="1.6" />
- <module name="dokka-android-gradle-plugin_test" target="1.6" />
- <module name="dokka-gradle-plugin_main" target="1.6" />
- <module name="dokka-gradle-plugin_test" target="1.6" />
- <module name="dokka-maven-plugin" target="1.5" />
- <module name="farjar_main" target="1.8" />
- <module name="farjar_test" target="1.8" />
<module name="fatjar_main" target="1.8" />
<module name="fatjar_test" target="1.8" />
+ <module name="gradle-integration-tests_main" target="1.8" />
+ <module name="gradle-integration-tests_test" target="1.8" />
<module name="gradle-plugin_main" target="1.6" />
<module name="gradle-plugin_test" target="1.6" />
<module name="integration_main" target="1.8" />
@@ -50,8 +41,6 @@
<module name="maven-plugin" target="1.5" />
<module name="maven-plugin_main" target="1.8" />
<module name="maven-plugin_test" target="1.8" />
- <module name="runners_main" target="1.8" />
- <module name="runners_test" target="1.8" />
</bytecodeTargetLevel>
</component>
</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index eaa3a486..7e6aaef5 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -21,6 +21,9 @@
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar.iml" group="runners/fatjar" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_main.iml" group="runners/fatjar" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/fatjar/fatjar_test.iml" group="runners/fatjar" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests.iml" group="runners/gradle-integration-tests" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_main.iml" group="runners/gradle-integration-tests" />
+ <module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-integration-tests/gradle-integration-tests_test.iml" group="runners/gradle-integration-tests" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin.iml" group="runners/gradle-plugin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_main.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_main.iml" group="runners/gradle-plugin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_test.iml" filepath="$PROJECT_DIR$/.idea/modules/runners/gradle-plugin/gradle-plugin_test.iml" group="runners/gradle-plugin" />
diff --git a/.idea/runConfigurations/All_tests.xml b/.idea/runConfigurations/All_tests.xml
new file mode 100644
index 00000000..d0d60ec9
--- /dev/null
+++ b/.idea/runConfigurations/All_tests.xml
@@ -0,0 +1,7 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="All tests" type="CompoundRunConfigurationType" factoryName="Compound Run Configuration">
+ <toRun type="JUnit" name="Core tests" />
+ <toRun type="JUnit" name="Gradle integration tests" />
+ <method />
+ </configuration>
+</component> \ No newline at end of file
diff --git a/.idea/runConfigurations/Core_tests.xml b/.idea/runConfigurations/Core_tests.xml
new file mode 100644
index 00000000..6f76e23f
--- /dev/null
+++ b/.idea/runConfigurations/Core_tests.xml
@@ -0,0 +1,26 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="Core tests" type="JUnit" factoryName="JUnit">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <module name="core_test" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" value="" />
+ <option name="METHOD_NAME" value="" />
+ <option name="TEST_OBJECT" value="directory" />
+ <option name="VM_PARAMETERS" value="" />
+ <option name="PARAMETERS" value="" />
+ <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/core/" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="singleModule" />
+ </option>
+ <envs />
+ <dir value="$PROJECT_DIR$/core/src/test/kotlin" />
+ <patterns>
+ <pattern testClass="org.jetbrains.dokka.gradle.*" />
+ </patterns>
+ <method />
+ </configuration>
+</component> \ No newline at end of file
diff --git a/.idea/runConfigurations/Gradle_integration_tests.xml b/.idea/runConfigurations/Gradle_integration_tests.xml
new file mode 100644
index 00000000..20af8f96
--- /dev/null
+++ b/.idea/runConfigurations/Gradle_integration_tests.xml
@@ -0,0 +1,26 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="Gradle integration tests" type="JUnit" factoryName="JUnit">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <module name="gradle-integration-tests_test" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" value="" />
+ <option name="METHOD_NAME" value="" />
+ <option name="TEST_OBJECT" value="pattern" />
+ <option name="VM_PARAMETERS" value="" />
+ <option name="PARAMETERS" value="" />
+ <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/runners/gradle-integration-tests" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="singleModule" />
+ </option>
+ <envs />
+ <dir value="$PROJECT_DIR$/core/src/test/kotlin" />
+ <patterns>
+ <pattern testClass="org.jetbrains.dokka.gradle.*" />
+ </patterns>
+ <method />
+ </configuration>
+</component> \ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index bb730356..8e2efd2b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip \ No newline at end of file
diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt b/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt
new file mode 100644
index 00000000..3c9bf156
--- /dev/null
+++ b/integration/src/main/kotlin/org/jetbrains/dokka/ReflectDsl.kt
@@ -0,0 +1,70 @@
+package org.jetbrains.dokka
+
+import kotlin.reflect.*
+import kotlin.reflect.jvm.isAccessible
+
+object ReflectDsl {
+
+ class CallOrPropAccess(private val receiver: Any?,
+ private val clz: KClass<*>,
+ private val selector: String) {
+
+ @Suppress("UNCHECKED_CAST")
+ operator fun <T : Any?> invoke(vararg a: Any?): T {
+ return func!!.call(receiver, *a) as T
+ }
+
+ operator fun get(s: String): CallOrPropAccess {
+ return v<Any?>()!![s]
+ }
+
+ val func: KFunction<*>? by lazy { clz.memberFunctions.find { it.name == selector } }
+ val prop: KProperty<*>? by lazy { clz.memberProperties.find { it.name == selector } }
+
+ fun takeIfIsFunc(): CallOrPropAccess? = if (func != null) this else null
+
+ fun takeIfIsProp(): CallOrPropAccess? = if (prop != null) this else null
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : Any?> v(): T {
+ val prop = prop!!
+ return try {
+ prop.getter.apply { isAccessible = true }.call(receiver) as T
+ } catch (e: KotlinNullPointerException) {
+ // Hack around kotlin-reflect bug KT-18480
+ val jclass = clz.java
+ val customGetterName = prop.getter.name
+ val getterName = if (customGetterName.startsWith("<")) "get" + prop.name.capitalize() else customGetterName
+ val getter = jclass.getDeclaredMethod(getterName)
+ getter.isAccessible = true
+
+ getter.invoke(receiver) as T
+
+ }
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun v(x: Any?) {
+ (prop as KMutableProperty).setter.apply { isAccessible = true }.call(receiver, x)
+ }
+
+
+ }
+
+ operator fun Any.get(s: String): CallOrPropAccess {
+ val clz = this.javaClass.kotlin
+ return CallOrPropAccess(this, clz, s)
+ }
+
+ operator fun Any.get(s: String, clz: Class<*>): CallOrPropAccess {
+ val kclz = clz.kotlin
+ return CallOrPropAccess(this, kclz, s)
+ }
+
+ operator fun Any.get(s: String, clz: KClass<*>): CallOrPropAccess {
+ return CallOrPropAccess(this, clz, s)
+ }
+
+ inline infix fun Any.isInstance(clz: Class<*>?): Boolean = clz != null && clz.isAssignableFrom(this.javaClass)
+ inline infix fun Any.isNotInstance(clz: Class<*>?): Boolean = !(this isInstance clz)
+} \ No newline at end of file
diff --git a/runners/android-gradle-plugin/build.gradle b/runners/android-gradle-plugin/build.gradle
index 01b9d3f0..a1747619 100644
--- a/runners/android-gradle-plugin/build.gradle
+++ b/runners/android-gradle-plugin/build.gradle
@@ -23,11 +23,10 @@ dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
shadow project(path: ':runners:gradle-plugin', configuration: 'shadow')
+ compileOnly project(':integration')
provided gradleApi()
provided localGroovy()
-
- provided 'com.android.tools.build:gradle:2.3.0'
}
task sourceJar(type: Jar) {
diff --git a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt
index 5db2ad2f..f392f1ab 100644
--- a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt
+++ b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt
@@ -1,13 +1,10 @@
package org.jetbrains.dokka.gradle
-import com.android.build.gradle.*
-import com.android.build.gradle.internal.VariantManager
import org.gradle.api.Plugin
import org.gradle.api.Project
-import org.gradle.api.tasks.SourceSet
+import org.gradle.api.tasks.Input
+import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder
import java.io.File
-import kotlin.reflect.jvm.isAccessible
-import kotlin.reflect.memberProperties
open class DokkaAndroidPlugin : Plugin<Project> {
override fun apply(project: Project) {
@@ -19,50 +16,15 @@ open class DokkaAndroidPlugin : Plugin<Project> {
}
}
-open class DokkaAndroidTask : DokkaTask() {
- override val sdkProvider: SdkProvider? = AndroidSdkProvider(project)
-}
-
-private class AndroidSdkProvider(private val project: Project) : SdkProvider {
- private val ext: BaseExtension? by lazy {
- project.extensions.findByType(LibraryExtension::class.java)
- ?: project.extensions.findByType(AppExtension::class.java)
- ?: project.extensions.findByType(TestExtension::class.java)
- }
+private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build()
- private val isAndroidProject: Boolean get() = ext != null
+open class DokkaAndroidTask : DokkaTask() {
- private val variantManager: VariantManager? by lazy {
- val plugin = (project.plugins.findPlugin("android")
- ?: project.plugins.findPlugin("android-library")
- ?: project.plugins.findPlugin("com.android.test")
- ?: throw Exception("Android plugin not found, please use dokka-android with android or android-library plugin.")) as BasePlugin
- plugin.javaClass.kotlin.memberProperties
- .find { it.name == "variantManager" }
- ?.apply { isAccessible = true }
- ?.let { it.get(plugin) as VariantManager }
- ?: plugin.variantManager
- }
+ @Input var noAndroidSdkLink: Boolean = false
- private val allVariantsClassPath by lazy {
- try {
- variantManager?.variantDataList?.flatMap { it.variantConfiguration.compileClasspath }!!
- } catch(e: Exception) {
- throw Exception("Unsupported version of android build tools, could not access variant manager.", e)
+ init {
+ project.afterEvaluate {
+ if (!noAndroidSdkLink) externalDocumentationLinks.add(ANDROID_REFERENCE_URL)
}
}
-
- override val name: String = "android"
-
- override val isValid: Boolean
- get() = isAndroidProject
-
- override val classpath: List<File>
- get() = ext?.bootClasspath.orEmpty() + allVariantsClassPath
-
- override val sourceDirs: Set<File>?
- get() {
- val sourceSet = ext?.sourceSets?.findByName(SourceSet.MAIN_SOURCE_SET_NAME)
- return sourceSet?.java?.srcDirs
- }
}
diff --git a/runners/build.gradle b/runners/build.gradle
index e171800b..f1d2873c 100644
--- a/runners/build.gradle
+++ b/runners/build.gradle
@@ -6,7 +6,7 @@ configure([project("ant"), project("cli"), project("fatjar"), project("maven-plu
}
}
-configure([project("gradle-plugin"), project("android-gradle-plugin")]) {
+configure([project("gradle-plugin"), project("android-gradle-plugin"), project("gradle-integration-tests")]) {
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_for_gradle_version"
diff --git a/runners/gradle-integration-tests/build.gradle b/runners/gradle-integration-tests/build.gradle
new file mode 100644
index 00000000..179b6455
--- /dev/null
+++ b/runners/gradle-integration-tests/build.gradle
@@ -0,0 +1,45 @@
+
+
+apply plugin: 'kotlin'
+
+
+configurations {
+ dokkaPlugin
+ dokkaAndroidPlugin
+ dokkaFatJar
+}
+
+dependencies {
+
+ testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: kotlin_for_gradle_version
+ testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_for_gradle_version
+ testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-test', version: kotlin_for_gradle_version
+
+ dokkaPlugin project(path: ':runners:gradle-plugin', configuration: 'shadow')
+ dokkaAndroidPlugin project(path: ':runners:android-gradle-plugin', configuration: 'shadow')
+ dokkaFatJar project(path: ":runners:fatjar", configuration: 'shadow')
+
+ testCompile group: 'junit', name: 'junit', version: '4.12'
+ testCompile gradleTestKit()
+}
+
+
+
+task createClasspathManifest {
+ def outputDir = file("$buildDir/$name")
+
+ inputs.files(configurations.dokkaPlugin + configurations.dokkaAndroidPlugin + configurations.dokkaFatJar)
+ outputs.dir outputDir
+
+ doLast {
+ outputDir.mkdirs()
+ file("$outputDir/dokka-plugin-classpath.txt").text = configurations.dokkaPlugin.join("\n")
+ file("$outputDir/android-dokka-plugin-classpath.txt").text = configurations.dokkaAndroidPlugin.join("\n")
+ file("$outputDir/fatjar.txt").text = configurations.dokkaFatJar.join("\n")
+ }
+}
+
+
+createClasspathManifest.mustRunAfter project(":runners:fatjar").shadowJar
+testClasses.dependsOn project(":runners:fatjar").shadowJar
+testClasses.dependsOn createClasspathManifest \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java
new file mode 100644
index 00000000..cbb1cc3c
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/FileComparisonFailure.java
@@ -0,0 +1,39 @@
+
+package com.intellij.rt.execution.junit;
+
+import junit.framework.ComparisonFailure;
+
+public class FileComparisonFailure extends ComparisonFailure implements KnownException {
+ private final String myExpected;
+ private final String myActual;
+ private final String myFilePath;
+ private final String myActualFilePath;
+
+ public FileComparisonFailure(String message, String expected, String actual, String filePath) {
+ this(message, expected, actual, filePath, (String)null);
+ }
+
+ public FileComparisonFailure(String message, String expected, String actual, String expectedFilePath, String actualFilePath) {
+ super(message, expected, actual);
+ this.myExpected = expected;
+ this.myActual = actual;
+ this.myFilePath = expectedFilePath;
+ this.myActualFilePath = actualFilePath;
+ }
+
+ public String getFilePath() {
+ return this.myFilePath;
+ }
+
+ public String getActualFilePath() {
+ return this.myActualFilePath;
+ }
+
+ public String getExpected() {
+ return this.myExpected;
+ }
+
+ public String getActual() {
+ return this.myActual;
+ }
+}
diff --git a/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java
new file mode 100644
index 00000000..c24653ea
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/java/com/intellij/rt/execution/junit/KnownException.java
@@ -0,0 +1,6 @@
+
+package com.intellij.rt.execution.junit;
+
+interface KnownException {
+
+}
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt
new file mode 100644
index 00000000..255138a9
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt
@@ -0,0 +1,108 @@
+package org.jetbrains.dokka.gradle
+
+
+import com.intellij.rt.execution.junit.FileComparisonFailure
+import org.gradle.testkit.runner.GradleRunner
+import org.junit.Rule
+import org.junit.rules.TemporaryFolder
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.Paths
+
+
+val testDataFolder = Paths.get("testData")
+
+val pluginClasspathData = Paths.get("build", "createClasspathManifest", "dokka-plugin-classpath.txt")
+val androidPluginClasspathData = pluginClasspathData.resolveSibling("android-dokka-plugin-classpath.txt")
+
+val dokkaFatJarPathData = pluginClasspathData.resolveSibling("fatjar.txt")
+
+val androidLocalProperties = testDataFolder.resolve("android.local.properties").let { if (Files.exists(it)) it else null }
+
+abstract class AbstractDokkaGradleTest {
+ @get:Rule val testProjectDir = TemporaryFolder()
+
+ open val pluginClasspath: List<File> = pluginClasspathData.toFile().readLines().map { File(it) }
+
+ fun checkOutputStructure(expected: String, actualSubpath: String) {
+ val expectedPath = testDataFolder.resolve(expected)
+ val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize()
+
+ assertEqualsIgnoringSeparators(expectedPath.toFile(), buildString {
+ actualPath.toFile().writeStructure(this, File(actualPath.toFile(), "."))
+ })
+ }
+
+ fun checkNoErrorClasses(actualSubpath: String, extension: String = "html", errorClassMarker: String = "ERROR CLASS") {
+ val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize()
+ var checked = 0
+ Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach {
+ val text = it.toFile().readText()
+
+ val noErrorClasses = text.replace(errorClassMarker, "?!")
+
+ if (noErrorClasses != text) {
+ throw FileComparisonFailure("", noErrorClasses, text, null)
+ }
+
+ checked++
+ }
+ println("$checked files checked for error classes")
+ }
+
+ fun checkNoUnresolvedLinks(actualSubpath: String, extension: String = "html", marker: Regex = "[\"']#[\"']".toRegex()) {
+ val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize()
+ var checked = 0
+ Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach {
+ val text = it.toFile().readText()
+
+ val noErrorClasses = text.replace(marker, "?!")
+
+ if (noErrorClasses != text) {
+ throw FileComparisonFailure("", noErrorClasses, text, null)
+ }
+
+ checked++
+ }
+ println("$checked files checked for unresolved links")
+ }
+
+ fun checkExternalLink(actualSubpath: String, linkBody: String, fullLink: String, extension: String = "html") {
+ val match = "!!match!!"
+ val notMatch = "!!not-match!!"
+
+ val actualPath = testProjectDir.root.toPath().resolve(actualSubpath).normalize()
+ var checked = 0
+ var totalEntries = 0
+ Files.walk(actualPath).filter { Files.isRegularFile(it) && it.fileName.toString().endsWith(".$extension") }.forEach {
+ val text = it.toFile().readText()
+
+ val textWithoutMatches = text.replace(fullLink, match)
+
+ val textWithoutNonMatches = textWithoutMatches.replace(linkBody, notMatch)
+
+ if (textWithoutNonMatches != textWithoutMatches) {
+
+ val expected = textWithoutNonMatches.replace(notMatch, fullLink).replace(match, fullLink)
+ val actual = textWithoutMatches.replace(match, fullLink)
+
+ throw FileComparisonFailure("", expected, actual, null)
+ }
+ if (text != textWithoutMatches)
+ totalEntries++
+
+ checked++
+ }
+ println("$checked files checked for valid external links '$linkBody', found $totalEntries links")
+ }
+
+ fun configure(gradleVersion: String = "3.5", kotlinVersion: String = "1.1.2", arguments: Array<String>): GradleRunner {
+ val fatjar = dokkaFatJarPathData.toFile().readText()
+
+ return GradleRunner.create().withProjectDir(testProjectDir.root)
+ .withArguments("-Pdokka_fatjar=$fatjar", "-Ptest_kotlin_version=$kotlinVersion", *arguments)
+ .withPluginClasspath(pluginClasspath)
+ .withGradleVersion(gradleVersion)
+ .withDebug(true)
+ }
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt
new file mode 100644
index 00000000..de22a980
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidAppTest.kt
@@ -0,0 +1,66 @@
+package org.jetbrains.dokka.gradle
+
+import org.gradle.testkit.runner.TaskOutcome
+import org.junit.Test
+import java.io.File
+import java.nio.file.Files
+import kotlin.test.assertEquals
+
+class AndroidAppTest : AbstractDokkaGradleTest() {
+ override val pluginClasspath: List<File> = androidPluginClasspathData.toFile().readLines().map { File(it) }
+
+ fun prepareTestData(testDataRootPath: String) {
+ val testDataRoot = testDataFolder.resolve(testDataRootPath)
+ val tmpRoot = testProjectDir.root.toPath()
+
+ testDataRoot.resolve("app").copy(tmpRoot.resolve("app"))
+ testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle"))
+ testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle"))
+
+ androidLocalProperties?.copy(tmpRoot.resolve("local.properties"))
+ }
+
+
+ data class AndroidPluginParams(val pluginVersion: String, val buildToolsVersion: String, val compileSdk: Int) {
+ fun asArguments(): List<String> = listOf(
+ "-Pabt_plugin_version=$pluginVersion",
+ "-Pabt_version=$buildToolsVersion",
+ "-Psdk_version=$compileSdk"
+ )
+ }
+
+
+ private fun doTest(gradleVersion: String, kotlinVersion: String, androidPluginParams: AndroidPluginParams) {
+ prepareTestData("androidApp")
+
+ val result = configure(gradleVersion, kotlinVersion,
+ arguments = arrayOf("dokka", "--stacktrace") + androidPluginParams.asArguments())
+ .build()
+
+ println(result.output)
+
+ assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokka")?.outcome)
+
+ val docsOutput = "app/build/dokka"
+
+ checkOutputStructure("androidApp/fileTree.txt", docsOutput)
+
+ checkNoErrorClasses(docsOutput)
+ checkNoUnresolvedLinks(docsOutput)
+
+ checkExternalLink(docsOutput, "<span class=\"identifier\">Activity</span>",
+ """<a href="https://developer.android.com/reference/android/app/Activity.html"><span class="identifier">Activity</span></a>""")
+ }
+
+ @Test fun `test kotlin 1_1_2-5 and gradle 4_0 and abt 3_0_0-alpha3`() {
+ doTest("4.0", "1.1.2-5", AndroidPluginParams("3.0.0-alpha3", "25.0.2", 25))
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 3_5 and abt 2_3_0`() {
+ doTest("3.5", "1.1.2", AndroidPluginParams("2.3.0", "25.0.0", 24))
+ }
+
+ @Test fun `test kotlin 1_0_7 and gradle 2_14_1 and abt 2_2_3`() {
+ doTest("2.14.1", "1.0.7", AndroidPluginParams("2.2.3", "25.0.0", 24))
+ }
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt
new file mode 100644
index 00000000..aee0e14c
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AndroidMultiFlavourAppTest.kt
@@ -0,0 +1,58 @@
+package org.jetbrains.dokka.gradle
+
+import org.gradle.testkit.runner.TaskOutcome
+import org.jetbrains.dokka.gradle.AndroidAppTest.AndroidPluginParams
+import org.junit.Test
+import java.io.File
+import kotlin.test.assertEquals
+
+class AndroidMultiFlavourAppTest : AbstractDokkaGradleTest() {
+ override val pluginClasspath: List<File> = androidPluginClasspathData.toFile().readLines().map { File(it) }
+
+ fun prepareTestData(testDataRootPath: String) {
+ val testDataRoot = testDataFolder.resolve(testDataRootPath)
+ val tmpRoot = testProjectDir.root.toPath()
+
+ testDataRoot.resolve("app").copy(tmpRoot.resolve("app"))
+ testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle"))
+ testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle"))
+
+ androidLocalProperties?.copy(tmpRoot.resolve("local.properties"))
+ }
+
+ private fun doTest(gradleVersion: String, kotlinVersion: String, androidPluginParams: AndroidPluginParams) {
+ prepareTestData("androidMultiFlavourApp")
+
+ val result = configure(gradleVersion, kotlinVersion,
+ arguments = arrayOf("dokka", "dokkaFullFlavourOnly", "--stacktrace") + androidPluginParams.asArguments())
+ .build()
+
+ println(result.output)
+
+ assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokka")?.outcome)
+ assertEquals(TaskOutcome.SUCCESS, result.task(":app:dokkaFullFlavourOnly")?.outcome)
+
+ val docsOutput = "app/build/dokka"
+
+ checkOutputStructure("androidMultiFlavourApp/fileTree.txt", docsOutput)
+
+ checkNoErrorClasses(docsOutput)
+ checkNoUnresolvedLinks(docsOutput)
+
+ checkExternalLink(docsOutput, "<span class=\"identifier\">Activity</span>",
+ """<a href="https://developer.android.com/reference/android/app/Activity.html"><span class="identifier">Activity</span></a>""")
+ }
+
+ @Test fun `test kotlin 1_1_2-5 and gradle 4_0 and abt 3_0_0-alpha3`() {
+ doTest("4.0", "1.1.2-5", AndroidPluginParams("3.0.0-alpha3", "25.0.2", 25))
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 3_5 and abt 2_3_0`() {
+ doTest("3.5", "1.1.2", AndroidPluginParams("2.3.0", "25.0.0", 24))
+ }
+
+ @Test fun `test kotlin 1_0_7 and gradle 2_14_1 and abt 2_2_3`() {
+ doTest("2.14.1", "1.0.7", AndroidPluginParams("2.2.3", "25.0.0", 24))
+ }
+
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt
new file mode 100644
index 00000000..f9801c82
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/BasicTest.kt
@@ -0,0 +1,51 @@
+package org.jetbrains.dokka.gradle
+
+import org.gradle.testkit.runner.TaskOutcome
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class BasicTest : AbstractDokkaGradleTest() {
+
+ fun prepareTestData(testDataRootPath: String) {
+ val testDataRoot = testDataFolder.resolve(testDataRootPath)
+ val tmpRoot = testProjectDir.root.toPath()
+
+ testDataRoot.resolve("src").copy(tmpRoot.resolve("src"))
+ testDataRoot.resolve("build.gradle").copy(tmpRoot.resolve("build.gradle"))
+ testDataRoot.resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle"))
+ }
+
+ private fun doTest(gradleVersion: String, kotlinVersion: String) {
+
+ prepareTestData("basic")
+
+ val result = configure(gradleVersion, kotlinVersion, arguments = arrayOf("dokka", "--stacktrace")).build()
+
+ println(result.output)
+
+ assertEquals(TaskOutcome.SUCCESS, result.task(":dokka")?.outcome)
+
+ val docsOutput = "build/dokka"
+
+ checkOutputStructure("basic/fileTree.txt", docsOutput)
+
+ checkNoErrorClasses(docsOutput)
+ checkNoUnresolvedLinks(docsOutput)
+
+ checkExternalLink(docsOutput, "<span class=\"identifier\">String</span>",
+ """<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html"><span class="identifier">String</span></a>""")
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 3_5`() {
+ doTest("3.5", "1.1.2")
+ }
+
+ @Test fun `test kotlin 1_0_7 and gradle 2_14_1`() {
+ doTest("2.14.1", "1.0.7")
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 4_0`() {
+ doTest("4.0", "1.1.2")
+ }
+
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt
new file mode 100644
index 00000000..13c7c37e
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/MultiProjectSingleOutTest.kt
@@ -0,0 +1,54 @@
+package org.jetbrains.dokka.gradle
+
+import org.gradle.testkit.runner.TaskOutcome
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class MultiProjectSingleOutTest : AbstractDokkaGradleTest() {
+
+ fun prepareTestData(testDataRootPath: String) {
+ val testDataRoot = testDataFolder.resolve(testDataRootPath)
+ val tmpRoot = testProjectDir.root.toPath()
+
+ testDataRoot.apply {
+ resolve("build.gradle").copy(tmpRoot.resolve("build.gradle"))
+ resolve("settings.gradle").copy(tmpRoot.resolve("settings.gradle"))
+ resolve("subA").copy(tmpRoot.resolve("subA"))
+ resolve("subB").copy(tmpRoot.resolve("subB"))
+ }
+ }
+
+ private fun doTest(gradleVersion: String, kotlinVersion: String) {
+
+ prepareTestData("multiProjectSingleOut")
+
+ val result = configure(gradleVersion, kotlinVersion, arguments = arrayOf("dokka", "--stacktrace")).build()
+
+ println(result.output)
+
+ assertEquals(TaskOutcome.SUCCESS, result.task(":dokka")?.outcome)
+
+ val docsOutput = "build/dokka"
+
+ checkOutputStructure("multiProjectSingleOut/fileTree.txt", docsOutput)
+
+ checkNoErrorClasses(docsOutput)
+ checkNoUnresolvedLinks(docsOutput)
+
+ checkExternalLink(docsOutput, "<span class=\"identifier\">String</span>",
+ """<a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html"><span class="identifier">String</span></a>""")
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 3_5`() {
+ doTest("3.5", "1.1.2")
+ }
+
+ @Test fun `test kotlin 1_0_7 and gradle 2_14_1`() {
+ doTest("2.14.1", "1.0.7")
+ }
+
+ @Test fun `test kotlin 1_1_2 and gradle 4_0`() {
+ doTest("4.0", "1.1.2")
+ }
+
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt
new file mode 100644
index 00000000..d44459b1
--- /dev/null
+++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/Utils.kt
@@ -0,0 +1,59 @@
+package org.jetbrains.dokka.gradle
+
+import com.intellij.rt.execution.junit.FileComparisonFailure
+import java.io.File
+import java.io.IOException
+import java.nio.file.FileVisitResult
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.SimpleFileVisitor
+import java.nio.file.attribute.BasicFileAttributes
+
+
+fun File.writeStructure(builder: StringBuilder, relativeTo: File = this, spaces: Int = 0) {
+ builder.append(" ".repeat(spaces))
+ val out = if (this != relativeTo) this.relativeTo(relativeTo) else this
+
+ builder.append(out)
+ if (this.isDirectory) {
+ builder.appendln("/")
+ this.listFiles().sortedBy { it.name }.forEach { it.writeStructure(builder, this, spaces + 4) }
+ } else {
+ builder.appendln()
+ }
+}
+
+fun assertEqualsIgnoringSeparators(expectedFile: File, output: String) {
+ if (!expectedFile.exists()) expectedFile.createNewFile()
+ val expectedText = expectedFile.readText().replace("\r\n", "\n")
+ val actualText = output.replace("\r\n", "\n")
+
+ if (expectedText != actualText)
+ throw FileComparisonFailure("", expectedText, actualText, expectedFile.canonicalPath)
+}
+
+class CopyFileVisitor(private var sourcePath: Path?, private val targetPath: Path) : SimpleFileVisitor<Path>() {
+
+ @Throws(IOException::class)
+ override fun preVisitDirectory(dir: Path,
+ attrs: BasicFileAttributes): FileVisitResult {
+ if (sourcePath == null) {
+ sourcePath = dir
+ } else {
+ Files.createDirectories(targetPath.resolve(sourcePath?.relativize(dir)))
+ }
+ return FileVisitResult.CONTINUE
+ }
+
+ @Throws(IOException::class)
+ override fun visitFile(file: Path,
+ attrs: BasicFileAttributes): FileVisitResult {
+ Files.copy(file, targetPath.resolve(sourcePath?.relativize(file)))
+ return FileVisitResult.CONTINUE
+ }
+}
+
+fun Path.copy(to: Path) {
+ Files.walkFileTree(this, CopyFileVisitor(this, to))
+}
+
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle
new file mode 100644
index 00000000..1555de9f
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle
@@ -0,0 +1,50 @@
+buildscript {
+ repositories {
+ jcenter()
+ mavenLocal()
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version"
+ }
+}
+
+plugins {
+ id 'org.jetbrains.dokka-android'
+}
+
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'org.jetbrains.dokka-android'
+
+android {
+ compileSdkVersion Integer.parseInt(sdk_version)
+ buildToolsVersion abt_version
+
+ defaultConfig {
+ applicationId "org.example.kotlin.mixed"
+ minSdkVersion 14
+ targetSdkVersion Integer.parseInt(sdk_version)
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt')
+ }
+ }
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+}
+
+dependencies {
+ compile "org.jetbrains.kotlin:kotlin-stdlib:$test_kotlin_version"
+}
+
+
+dokka {
+ dokkaFatJar = new File(dokka_fatjar)
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..b4e1a892
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.example.kotlin.mixed" >
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+
+ <activity
+ android:name=".JavaActivity"
+ android:label="@string/title_activity_main_activity1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".KotlinActivity"
+ android:label="@string/title_activity_main_activity2" />
+
+ </application>
+
+</manifest>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java b/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java
new file mode 100644
index 00000000..3668c594
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java
@@ -0,0 +1,34 @@
+package org.example.kotlin.mixed;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.app.Activity;
+import android.view.Menu;
+import android.view.View;
+import android.widget.Button;
+
+public class JavaActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ Button next = (Button) findViewById(R.id.Button01);
+ next.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ Intent myIntent = new Intent(view.getContext(), KotlinActivity.class);
+ startActivityForResult(myIntent, 0);
+ }
+ });
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+}
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt b/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt
new file mode 100644
index 00000000..ca2f27b0
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt
@@ -0,0 +1,28 @@
+package org.example.kotlin.mixed
+
+import android.content.Intent
+import android.os.Bundle
+import android.app.Activity
+import android.view.Menu
+import android.widget.Button
+
+class KotlinActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main2)
+
+ val next = findViewById(R.id.Button02) as Button
+ next.setOnClickListener {
+ val intent: Intent = Intent()
+ setResult(RESULT_OK, intent)
+ finish()
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ menuInflater.inflate(R.menu.main_activity2, menu)
+ return true
+ }
+}
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..96a442e5
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..359047df
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..71c6d760
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..ede57c39
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Activity 1" />
+
+ <Button android:text="Next"
+ android:id="@+id/Button01"
+ android:layout_width="250px"
+ android:textSize="18px"
+ android:layout_height="55px">
+ </Button>
+
+</LinearLayout>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml
new file mode 100644
index 00000000..d707536a
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/layout/activity_main2.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Activity 2" />
+
+ <Button android:text="Next"
+ android:id="@+id/Button02"
+ android:layout_width="250px"
+ android:textSize="18px"
+ android:layout_height="55px">
+ </Button>
+
+</LinearLayout>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml
new file mode 100644
index 00000000..f3b10b6c
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml
new file mode 100644
index 00000000..f3b10b6c
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/menu/main_activity2.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..47c82246
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..d8f08bc2
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/strings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">AndroidSample</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="title_activity_main_activity1">JavaActivity</string>
+ <string name="title_activity_main_activity2">KotlinActivity</string>
+
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..6ce89c7b
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidApp/build.gradle b/runners/gradle-integration-tests/testData/androidApp/build.gradle
new file mode 100644
index 00000000..59477b52
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url 'https://maven.google.com' }
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:$abt_plugin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+}
diff --git a/runners/gradle-integration-tests/testData/androidApp/fileTree.txt b/runners/gradle-integration-tests/testData/androidApp/fileTree.txt
new file mode 100644
index 00000000..3827b69e
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/fileTree.txt
@@ -0,0 +1,19 @@
+/
+ app/
+ alltypes/
+ index.html
+ index-outline.html
+ index.html
+ org.example.kotlin.mixed/
+ -java-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ -kotlin-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ on-create.html
+ index.html
+ package-list
+ style.css
diff --git a/runners/gradle-integration-tests/testData/androidApp/settings.gradle b/runners/gradle-integration-tests/testData/androidApp/settings.gradle
new file mode 100644
index 00000000..1feb2867
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidApp/settings.gradle
@@ -0,0 +1,3 @@
+rootProject.name = "androidApp"
+
+include ':app' \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle
new file mode 100644
index 00000000..ee68ba6d
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle
@@ -0,0 +1,75 @@
+buildscript {
+ repositories {
+ jcenter()
+ mavenLocal()
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version"
+ }
+}
+
+plugins {
+ id 'org.jetbrains.dokka-android'
+}
+
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'org.jetbrains.dokka-android'
+
+android {
+ compileSdkVersion Integer.parseInt(sdk_version)
+ buildToolsVersion abt_version
+
+ defaultConfig {
+ applicationId "org.example.kotlin.mixed"
+ minSdkVersion 14
+ targetSdkVersion Integer.parseInt(sdk_version)
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt')
+ }
+ }
+
+ flavorDimensions "mode"
+ productFlavors {
+ free {
+ dimension "mode"
+ applicationIdSuffix ".free"
+ versionNameSuffix "-free"
+ }
+ full {
+ dimension "mode"
+ applicationIdSuffix ".full"
+ versionNameSuffix "-full"
+ }
+ }
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ free.java.srcDirs += 'src/free/kotlin'
+ }
+}
+
+dependencies {
+ compile "org.jetbrains.kotlin:kotlin-stdlib:$test_kotlin_version"
+}
+
+
+dokka {
+ outputDirectory = "$buildDir/dokka/all"
+ dokkaFatJar = new File(dokka_fatjar)
+}
+
+task dokkaFullFlavourOnly(type: org.jetbrains.dokka.gradle.DokkaAndroidTask) {
+ kotlinTasks {
+ ["compileFullReleaseKotlin"]
+ }
+ dokkaFatJar = new File(dokka_fatjar)
+ outputDirectory = "$buildDir/dokka/fullOnly"
+ moduleName = "full"
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml
new file mode 100644
index 00000000..3ecbcd3a
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <application>
+ <activity
+ android:name="org.example.kotlin.mixed.free.AdActivity"
+ android:label="@string/title_activity_ad"
+ android:theme="@style/AppTheme"></activity>
+ </application>
+</manifest>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt
new file mode 100644
index 00000000..b0b980fd
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/kotlin/org/example/kotlin/mixed/free/AdActivity.kt
@@ -0,0 +1,14 @@
+package org.example.kotlin.mixed.free
+
+import android.os.Bundle
+import android.app.Activity
+import org.example.kotlin.mixed.R
+
+class AdActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_ad)
+ }
+
+}
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml
new file mode 100644
index 00000000..e6443d05
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/layout/activity_ad.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".free.AdActivity">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Advertisment" />
+
+ <Button android:text="Next"
+ android:id="@+id/Button02"
+ android:layout_width="250px"
+ android:textSize="18px"
+ android:layout_height="55px">
+ </Button>
+
+</LinearLayout>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml
new file mode 100644
index 00000000..bbdf2d06
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/free/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="title_activity_ad">AdActivity</string>
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..b4e1a892
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.example.kotlin.mixed" >
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+
+ <activity
+ android:name=".JavaActivity"
+ android:label="@string/title_activity_main_activity1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".KotlinActivity"
+ android:label="@string/title_activity_main_activity2" />
+
+ </application>
+
+</manifest>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java
new file mode 100644
index 00000000..3668c594
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/java/org/example/kotlin/mixed/JavaActivity.java
@@ -0,0 +1,34 @@
+package org.example.kotlin.mixed;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.app.Activity;
+import android.view.Menu;
+import android.view.View;
+import android.widget.Button;
+
+public class JavaActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ Button next = (Button) findViewById(R.id.Button01);
+ next.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ Intent myIntent = new Intent(view.getContext(), KotlinActivity.class);
+ startActivityForResult(myIntent, 0);
+ }
+ });
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+}
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt
new file mode 100644
index 00000000..ca2f27b0
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/kotlin/org/example/kotlin/mixed/KotlinActivity.kt
@@ -0,0 +1,28 @@
+package org.example.kotlin.mixed
+
+import android.content.Intent
+import android.os.Bundle
+import android.app.Activity
+import android.view.Menu
+import android.widget.Button
+
+class KotlinActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main2)
+
+ val next = findViewById(R.id.Button02) as Button
+ next.setOnClickListener {
+ val intent: Intent = Intent()
+ setResult(RESULT_OK, intent)
+ finish()
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ menuInflater.inflate(R.menu.main_activity2, menu)
+ return true
+ }
+}
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..96a442e5
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..359047df
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..71c6d760
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..ede57c39
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Activity 1" />
+
+ <Button android:text="Next"
+ android:id="@+id/Button01"
+ android:layout_width="250px"
+ android:textSize="18px"
+ android:layout_height="55px">
+ </Button>
+
+</LinearLayout>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml
new file mode 100644
index 00000000..d707536a
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/layout/activity_main2.xml
@@ -0,0 +1,24 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Activity 2" />
+
+ <Button android:text="Next"
+ android:id="@+id/Button02"
+ android:layout_width="250px"
+ android:textSize="18px"
+ android:layout_height="55px">
+ </Button>
+
+</LinearLayout>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml
new file mode 100644
index 00000000..f3b10b6c
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml
new file mode 100644
index 00000000..f3b10b6c
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/menu/main_activity2.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/action_settings"
+ android:title="@string/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..47c82246
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..d8f08bc2
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/strings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">AndroidSample</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="title_activity_main_activity1">JavaActivity</string>
+ <string name="title_activity_main_activity2">KotlinActivity</string>
+
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..6ce89c7b
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle
new file mode 100644
index 00000000..59477b52
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url 'https://maven.google.com' }
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:$abt_plugin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+}
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt
new file mode 100644
index 00000000..5e969d8b
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/fileTree.txt
@@ -0,0 +1,45 @@
+/
+ all/
+ app/
+ alltypes/
+ index.html
+ index-outline.html
+ index.html
+ org.example.kotlin.mixed/
+ -java-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ -kotlin-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ on-create.html
+ index.html
+ org.example.kotlin.mixed.free/
+ -ad-activity/
+ -init-.html
+ index.html
+ on-create.html
+ index.html
+ package-list
+ style.css
+ fullOnly/
+ full/
+ alltypes/
+ index.html
+ index-outline.html
+ index.html
+ org.example.kotlin.mixed/
+ -java-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ -kotlin-activity/
+ -init-.html
+ index.html
+ on-create-options-menu.html
+ on-create.html
+ index.html
+ package-list
+ style.css
diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle
new file mode 100644
index 00000000..1feb2867
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/settings.gradle
@@ -0,0 +1,3 @@
+rootProject.name = "androidApp"
+
+include ':app' \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/basic/build.gradle b/runners/gradle-integration-tests/testData/basic/build.gradle
new file mode 100644
index 00000000..bc20e1cf
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/basic/build.gradle
@@ -0,0 +1,39 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version"
+ }
+}
+
+plugins {
+ id 'org.jetbrains.dokka'
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'org.jetbrains.dokka'
+
+repositories {
+ mavenCentral()
+ jcenter()
+ maven {
+ url "http://dl.bintray.com/kotlin/kotlin-eap-1.1"
+ }
+ maven {
+ url "https://dl.bintray.com/kotlin/kotlin-dev"
+ }
+}
+
+dependencies {
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version
+}
+
+
+dokka {
+ dokkaFatJar = new File(dokka_fatjar)
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/basic/fileTree.txt b/runners/gradle-integration-tests/testData/basic/fileTree.txt
new file mode 100644
index 00000000..1a483d4e
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/basic/fileTree.txt
@@ -0,0 +1,30 @@
+/
+ basic/
+ alltypes/
+ index.html
+ demo/
+ -a/
+ -init-.html
+ index.html
+ p.html
+ -greeter/
+ -init-.html
+ greet.html
+ index.html
+ name.html
+ -some-interface.html
+ -some-sub-type/
+ -init-.html
+ index.html
+ -some-type/
+ -init-.html
+ index.html
+ constructor.html
+ index.html
+ main.html
+ str.html
+ x.html
+ index-outline.html
+ index.html
+ package-list
+ style.css
diff --git a/runners/gradle-integration-tests/testData/basic/settings.gradle b/runners/gradle-integration-tests/testData/basic/settings.gradle
new file mode 100644
index 00000000..c36a146c
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/basic/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = "basic" \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt b/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt
new file mode 100644
index 00000000..7492e2a8
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/basic/src/main/kotlin/demo/HelloWorld.kt
@@ -0,0 +1,41 @@
+package demo
+
+/**
+ * This class supports greeting people by name.
+ *
+ * @property name The name of the person to be greeted.
+ */
+class Greeter(val name: String) {
+
+ /**
+ * Prints the greeting to the standard output.
+ */
+ fun greet() {
+ println("Hello $name!")
+ }
+}
+
+fun main(args: Array<String>) {
+ Greeter(args[0]).greet()
+}
+
+val str = "Hello! ".repeat(4)
+val x: (a: String, b: Int) -> Int = { a, b -> 0 }
+
+interface SomeInterface
+private class SomeImpl : SomeInterface
+
+fun SomeInterface.constructor(): SomeInterface {
+ return SomeImpl()
+}
+
+open class SomeType
+class SomeSubType : SomeType()
+
+fun SomeType.constructor(): SomeType {
+ return SomeSubType()
+}
+
+
+annotation class A(val p: String)
+
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle
new file mode 100644
index 00000000..68d93e30
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/build.gradle
@@ -0,0 +1,32 @@
+plugins {
+ id 'org.jetbrains.dokka'
+}
+
+subprojects {
+ buildscript {
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$test_kotlin_version"
+ }
+ }
+ repositories {
+ mavenCentral()
+ jcenter()
+ maven { url "http://dl.bintray.com/kotlin/kotlin-eap-1.1" }
+ maven { url "https://dl.bintray.com/kotlin/kotlin-dev" }
+ }
+}
+
+apply plugin: 'org.jetbrains.dokka'
+
+dokka {
+ kotlinTasks {
+ [":subA:compileKotlin", ":subB:compileKotlin"]
+ }
+ dokkaFatJar = new File(dokka_fatjar)
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt
new file mode 100644
index 00000000..5624fca6
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/fileTree.txt
@@ -0,0 +1,33 @@
+/
+ multi-project-root/
+ alltypes/
+ index.html
+ index-outline.html
+ index.html
+ package-list
+ s1/
+ -my-class/
+ -init-.html
+ index.html
+ otherworks.html
+ -super/
+ -init-.html
+ bar.html
+ foo.html
+ index.html
+ index.html
+ some-cool-thing.html
+ s2/
+ -cooler/
+ -init-.html
+ a.html
+ coolest.html
+ index.html
+ my-class.html
+ -superful/
+ -init-.html
+ bar.html
+ index.html
+ index.html
+ main.html
+ style.css
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle
new file mode 100644
index 00000000..283cc526
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/settings.gradle
@@ -0,0 +1,3 @@
+rootProject.name = "multiProjectRoot"
+
+include 'subA', 'subB' \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle
new file mode 100644
index 00000000..0600411e
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/build.gradle
@@ -0,0 +1,6 @@
+apply plugin: 'kotlin'
+
+dependencies {
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version
+}
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt
new file mode 100644
index 00000000..126d7f3e
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subA/src/main/kotlin/module.kt
@@ -0,0 +1,31 @@
+package s1
+
+/**
+ * Coolest one
+ */
+fun someCoolThing(s: String) = s.repeat(2)
+
+/**
+ * Just a class
+ */
+class MyClass {
+ /**
+ * Ultimate answer to all questions
+ */
+ fun otherworks(): Int = 42
+}
+
+/**
+ * Just a SUPER class
+ */
+open class Super {
+ /**
+ * Same as [MyClass.otherworks]
+ */
+ fun foo(i: Int = 21) = i * 2
+
+ /**
+ * magic
+ */
+ open fun bar() = foo()
+} \ No newline at end of file
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle
new file mode 100644
index 00000000..7b8ff9f3
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/build.gradle
@@ -0,0 +1,7 @@
+apply plugin: 'kotlin'
+
+dependencies {
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: test_kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: test_kotlin_version
+ compile project(":subA")
+}
diff --git a/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt
new file mode 100644
index 00000000..8a87590a
--- /dev/null
+++ b/runners/gradle-integration-tests/testData/multiProjectSingleOut/subB/src/main/kotlin/module.kt
@@ -0,0 +1,31 @@
+package s2
+
+import s1.Super
+import s1.MyClass
+import s1.someCoolThing
+
+/**
+ * Just an entry-point
+ */
+fun main(args: Array<String>) {
+
+}
+
+/**
+ * Take a glass of hot water
+ */
+class Cooler {
+ val myClass = MyClass()
+ val a = myClass.otherworks()
+ val coolest = someCoolThing()
+}
+
+/**
+ * Powerful
+ */
+class Superful : Super() {
+ /**
+ * Overriden magic
+ */
+ override fun bar() = foo(20) * 2
+} \ No newline at end of file
diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt
index 61c83de4..fd4053ee 100644
--- a/runners/gradle-plugin/src/main/kotlin/main.kt
+++ b/runners/gradle-plugin/src/main/kotlin/main.kt
@@ -4,15 +4,14 @@ import groovy.lang.Closure
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
+import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.*
import org.gradle.api.tasks.Optional
-import org.jetbrains.dokka.DokkaBootstrap
-import org.jetbrains.dokka.DokkaConfiguration
-import org.jetbrains.dokka.SerializeOnlyDokkaConfiguration
-import org.jetbrains.dokka.automagicTypedProxy
+import org.jetbrains.dokka.*
+import org.jetbrains.dokka.ReflectDsl.isNotInstance
import org.jetbrains.dokka.gradle.ClassloaderContainer.fatJarClassLoader
import org.jetbrains.dokka.gradle.DokkaVersion.version
import ru.yole.jkid.JsonExclude
@@ -22,6 +21,7 @@ import java.io.InputStream
import java.io.Serializable
import java.net.URLClassLoader
import java.util.*
+import java.util.concurrent.Callable
import java.util.function.BiConsumer
open class DokkaPlugin : Plugin<Project> {
@@ -52,9 +52,24 @@ object ClassloaderContainer {
}
open class DokkaTask : DefaultTask() {
+
+ fun defaultKotlinTasks() = with(ReflectDsl) {
+ val abstractKotlinCompileClz = try {
+ project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE)
+ } catch (cnfe: ClassNotFoundException) {
+ logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored")
+ return@with emptyList<Task>()
+ }
+
+ return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name }
+ }
+
init {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Generates dokka documentation for Kotlin"
+
+ @Suppress("LeakingThis")
+ dependsOn(Callable { kotlinTasks.flatMap { it.dependsOn } })
}
@Input
@@ -62,8 +77,13 @@ open class DokkaTask : DefaultTask() {
@Input
var outputFormat: String = "html"
var outputDirectory: String = ""
- @Input
- var processConfigurations: List<Any?> = arrayListOf("compile")
+
+
+ @Deprecated("Going to be removed in 0.9.16, use classpath + sourceDirs instead if kotlinTasks is not suitable for you")
+ @Input var processConfigurations: List<Any?> = emptyList()
+
+ @Input var classpath: List<File> = arrayListOf()
+
@Input
var includes: List<Any?> = arrayListOf()
@Input
@@ -92,7 +112,16 @@ open class DokkaTask : DefaultTask() {
@Optional @Input var cacheRoot: String? = null
- protected open val sdkProvider: SdkProvider? = null
+ @get:Input
+ internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() }
+
+
+ private var kotlinTasksConfigurator: () -> List<Any?>? = { defaultKotlinTasks() }
+ private val kotlinTasks: List<Task> by lazy { extractKotlinCompileTasks() }
+
+ fun kotlinTasks(closure: Closure<Any?>) {
+ kotlinTasksConfigurator = { closure.call() as? List<Any?> }
+ }
fun linkMapping(closure: Closure<Any?>) {
val mapping = LinkMapping()
@@ -151,6 +180,56 @@ open class DokkaTask : DefaultTask() {
}
}
+ internal data class ClasspathAndSourceRoots(val classpath: List<File>, val sourceRoots: List<File>) : Serializable
+
+ private fun extractKotlinCompileTasks(): List<Task> {
+ val inputList = (kotlinTasksConfigurator.invoke() ?: emptyList()).filterNotNull()
+ val (paths, other) = inputList.partition { it is String }
+
+ val taskContainer = project.tasks
+
+ val tasksByPath = paths.map { taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found") }
+
+ other
+ .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) }
+ .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") }
+
+ tasksByPath
+ .filter { it == null || it isNotInstance getAbstractKotlinCompileFor(it) }
+ .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") }
+
+
+ return (tasksByPath + other) as List<Task>
+ }
+
+ private fun extractClasspathAndSourceRootsFromKotlinTasks(): ClasspathAndSourceRoots {
+
+ val allTasks = kotlinTasks
+
+ val allClasspath = mutableSetOf<File>()
+ val allSourceRoots = mutableSetOf<File>()
+
+ allTasks.forEach {
+
+ logger.debug("Dokka found AbstractKotlinCompile task: $it")
+ with(ReflectDsl) {
+ val taskSourceRoots: List<File> = it["sourceRootsContainer"]["sourceRoots"].v()
+
+ val abstractKotlinCompileClz = getAbstractKotlinCompileFor(it)!!
+
+ val taskClasspath: Iterable<File> =
+ (it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() ?:
+ it["getClasspath", abstractKotlinCompileClz]())
+
+ allClasspath += taskClasspath.filter { it.exists() }
+ allSourceRoots += taskSourceRoots.filter { it.exists() }
+ }
+ }
+
+ return ClasspathAndSourceRoots(allClasspath.toList(), allSourceRoots.toList())
+ }
+
+ private fun Iterable<File>.toSourceRoots(): List<SourceRoot> = this.filter { it.exists() }.map { SourceRoot().apply { path = it.path } }
@TaskAction
fun generate() {
@@ -159,22 +238,18 @@ open class DokkaTask : DefaultTask() {
try {
loadFatJar()
- val project = project
- val sdkProvider = sdkProvider
- val sourceRoots = collectSourceRoots()
- val allConfigurations = project.configurations
+ val (tasksClasspath, tasksSourceRoots) = kotlinCompileBasedClasspathAndSourceRoots
- val classpath =
- if (sdkProvider != null && sdkProvider.isValid) sdkProvider.classpath else emptyList<File>() +
- processConfigurations
- .map { allConfigurations?.getByName(it.toString()) ?: throw IllegalArgumentException("No configuration $it found") }
- .flatMap { it }
+ val project = project
+ val sourceRoots = collectSourceRoots() + tasksSourceRoots.toSourceRoots()
if (sourceRoots.isEmpty()) {
logger.warn("No source directories found: skipping dokka generation")
return
}
+ val fullClasspath = collectClasspathFromOldSources() + tasksClasspath + classpath
+
val bootstrapClass = fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl")
val bootstrapInstance = bootstrapClass.constructors.first().newInstance()
@@ -183,7 +258,7 @@ open class DokkaTask : DefaultTask() {
val configuration = SerializeOnlyDokkaConfiguration(
moduleName,
- classpath.map { it.absolutePath },
+ fullClasspath.map { it.absolutePath },
sourceRoots,
samples.filterNotNull().map { project.file(it).absolutePath },
includes.filterNotNull().map { project.file(it).absolutePath },
@@ -222,28 +297,40 @@ open class DokkaTask : DefaultTask() {
}
}
- fun collectSourceRoots(): List<SourceRoot> {
- val provider = sdkProvider
+ private fun collectClasspathFromOldSources(): List<File> {
+
+ val allConfigurations = project.configurations
+
+ val fromConfigurations =
+ processConfigurations.map {
+ allConfigurations?.getByName(it.toString()) ?: throw IllegalArgumentException("No configuration $it found")
+ }.flatten()
+
+ return fromConfigurations
+ }
+
+ private fun collectSourceRoots(): List<SourceRoot> {
val sourceDirs = if (sourceDirs.any()) {
logger.info("Dokka: Taking source directories provided by the user")
sourceDirs.toSet()
- } else if (provider != null && provider.isValid) {
- logger.info("Dokka: Taking source directories from ${provider.name} sdk provider")
- provider.sourceDirs
- } else {
+ } else if (kotlinTasks.isEmpty()) {
logger.info("Dokka: Taking source directories from default java plugin")
val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
val sourceSets = javaPluginConvention.sourceSets?.findByName(SourceSet.MAIN_SOURCE_SET_NAME)
sourceSets?.allSource?.srcDirs
+ } else {
+ emptySet()
}
- return sourceRoots + (sourceDirs?.filter { it.exists() }?.map { SourceRoot().apply { path = it.path } } ?: emptyList())
+ return sourceRoots + (sourceDirs?.toSourceRoots() ?: emptyList())
}
- @InputFiles
+
@SkipWhenEmpty
+ @InputFiles
fun getInputFiles(): FileCollection =
- project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) +
+ project.files(kotlinCompileBasedClasspathAndSourceRoots.sourceRoots.map { project.fileTree(File(it.path)) }) +
+ project.files(collectSourceRoots().map { project.fileTree(File(it.path)) }) +
project.files(includes) +
project.files(samples.map { project.fileTree(it) })
@@ -252,6 +339,13 @@ open class DokkaTask : DefaultTask() {
companion object {
const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled"
+ const val ABSTRACT_KOTLIN_COMPILE = "org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile"
+
+ private fun getAbstractKotlinCompileFor(task: Task) = try {
+ task.project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE)
+ } catch (e: ClassNotFoundException) {
+ null
+ }
}
}
@@ -262,6 +356,10 @@ class SourceRoot : DokkaConfiguration.SourceRoot {
}
override var platforms: List<String> = arrayListOf()
+
+ override fun toString(): String {
+ return "${platforms.joinToString()}::$path"
+ }
}
open class LinkMapping : Serializable, DokkaConfiguration.SourceLinkDefinition {
@@ -315,36 +413,3 @@ class PackageOptions : DokkaConfiguration.PackageOptions {
override var reportUndocumented: Boolean = true
override var skipDeprecated: Boolean = false
}
-/**
- * A provider for SDKs that can be used if a project uses classes that live outside the JDK or uses a
- * different method to determine the source directories.
- *
- * For example an Android library project configures its sources through the Android extension instead
- * of the basic java convention. Also it has its custom classes located in the SDK installation directory.
- */
-interface SdkProvider {
- /**
- * The name of this provider. Only used for logging purposes.
- */
- val name: String
-
- /**
- * Checks whether this provider has everything it needs to provide the source directories.
- */
- val isValid: Boolean
-
- /**
- * Provides additional classpath files where Dokka should search for external classes.
- * The file list is injected **after** JDK Jars and **before** project dependencies.
- *
- * This is only called if [isValid] returns `true`.
- */
- val classpath: List<File>
-
- /**
- * Provides a list of directories where Dokka should search for source files.
- *
- * This is only called if [isValid] returns `true`.
- */
- val sourceDirs: Set<File>?
-}
diff --git a/runners/maven-plugin/build.gradle b/runners/maven-plugin/build.gradle
index 3f80ba4a..e1a3af1a 100644
--- a/runners/maven-plugin/build.gradle
+++ b/runners/maven-plugin/build.gradle
@@ -25,7 +25,7 @@ dependencies {
shadow "org.apache.maven.plugin-tools:maven-plugin-annotations:$maven_plugin_tools_version"
}
-task generatePom << {
+task ("generatePom") doLast {
final pomTemplate = new File(projectDir, "pom.tpl.xml")
final pom = new File(buildDir, "pom.xml")
pom.text = pomTemplate.text.replace("<version>dokka_version</version>", "<version>$dokka_version</version>")
@@ -43,7 +43,6 @@ task helpMojo(type: CrossPlatformExec) {
commandLine mvn, '-e', '-B', 'org.apache.maven.plugins:maven-plugin-plugin:helpmojo'
}
-
helpMojo.dependsOn generatePom
sourceSets.main.java.srcDir("$buildDir/generated-sources/plugin")
compileJava.dependsOn helpMojo
diff --git a/runners/maven-plugin/pom.tpl.xml b/runners/maven-plugin/pom.tpl.xml
index 3b5afd74..c5883c6a 100644
--- a/runners/maven-plugin/pom.tpl.xml
+++ b/runners/maven-plugin/pom.tpl.xml
@@ -21,6 +21,6 @@
</plugin>
</plugins>
<directory>./</directory>
- <outputDirectory>classes/main</outputDirectory>
+ <outputDirectory>./classes/java/main</outputDirectory>
</build>
</project>
diff --git a/settings.gradle b/settings.gradle
index 9da9e303..4dcfd255 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,9 @@
-include 'core', 'runners:fatjar', 'runners:ant', 'runners:cli', 'runners:maven-plugin', 'runners:gradle-plugin', 'runners:android-gradle-plugin', 'integration'
+include 'core',
+ 'integration',
+ 'runners:fatjar',
+ 'runners:ant',
+ 'runners:cli',
+ 'runners:maven-plugin',
+ 'runners:gradle-plugin',
+ 'runners:android-gradle-plugin',
+ 'runners:gradle-integration-tests'