aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2016-12-02 23:46:16 +0300
committerSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2016-12-02 23:46:16 +0300
commit13bda7371cc60beaa4cc8302239efd21695b9e1f (patch)
tree1673a8ff05e3398a9826af09ece88f05fd4c56ae
parent039bb97123fd8a74b9954598d7a102e235fd108d (diff)
downloaddokka-13bda7371cc60beaa4cc8302239efd21695b9e1f.tar.gz
dokka-13bda7371cc60beaa4cc8302239efd21695b9e1f.tar.bz2
dokka-13bda7371cc60beaa4cc8302239efd21695b9e1f.zip
Now dokka-fatjar complete isolated from poisonous Gradle environment
-rw-r--r--core/build.gradle2
-rw-r--r--core/src/main/kotlin/DokkaBootstrapImpl.kt55
-rw-r--r--core/src/main/kotlin/Utilities/DokkaLogging.kt6
-rw-r--r--integration/build.gradle13
-rw-r--r--integration/src/main/kotlin/org/jetbrains/dokka/DokkaBootstrap.kt22
-rw-r--r--integration/src/main/kotlin/org/jetbrains/dokka/DokkaLogger.kt8
-rw-r--r--integration/src/main/kotlin/org/jetbrains/dokka/ProxyUtils.kt76
-rw-r--r--runners/android-gradle-plugin/build.gradle3
-rw-r--r--runners/cli/src/main/kotlin/cli/main.kt7
-rw-r--r--runners/fatjar/build.gradle23
-rw-r--r--runners/gradle-plugin/build.gradle19
-rw-r--r--runners/gradle-plugin/src/main/kotlin/main.kt76
-rw-r--r--runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties3
-rw-r--r--settings.gradle2
14 files changed, 260 insertions, 55 deletions
diff --git a/core/build.gradle b/core/build.gradle
index 72eb6baf..08be76c0 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -47,7 +47,7 @@ dependencies {
//tools.jar
provided files(((URLClassLoader) ToolProvider.getSystemToolClassLoader()).getURLs().findAll { it.path.endsWith("jar") })
-
+ compile project(":integration")
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.jetbrains.kotlin', name: 'kotlin-test-junit', version: kotlin_version
diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt
new file mode 100644
index 00000000..cbec4985
--- /dev/null
+++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt
@@ -0,0 +1,55 @@
+package org.jetbrains.dokka
+
+import java.io.File
+
+fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinition {
+ val (path, urlAndLine) = srcLink.split('=')
+ return SourceLinkDefinition(File(path).absolutePath,
+ urlAndLine.substringBefore("#"),
+ urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#" + it })
+}
+
+
+class DokkaBootstrapImpl : DokkaBootstrap {
+
+ lateinit var generator: DokkaGenerator
+
+ override fun configure(logger: DokkaLogger,
+ moduleName: String,
+ classpath: List<String>,
+ sources: List<String>,
+ samples: List<String>,
+ includes: List<String>,
+ outputDir: String,
+ format: String,
+ includeNonPublic: Boolean,
+ reportUndocumented: Boolean,
+ skipEmptyPackages: Boolean,
+ skipDeprecated: Boolean,
+ jdkVersion: Int,
+ generateIndexPages: Boolean,
+ sourceLinks: List<String>) {
+ generator = DokkaGenerator(
+ logger,
+ classpath,
+ sources,
+ samples,
+ includes,
+ moduleName,
+ DocumentationOptions(
+ outputDir,
+ format,
+ includeNonPublic,
+ reportUndocumented,
+ skipEmptyPackages,
+ skipDeprecated,
+ jdkVersion,
+ generateIndexPages,
+ sourceLinks.map(::parseSourceLinkDefinition)
+ )
+ )
+
+ }
+
+ override fun generate() = generator.generate()
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/Utilities/DokkaLogging.kt b/core/src/main/kotlin/Utilities/DokkaLogging.kt
index 1ef52837..2e0fb395 100644
--- a/core/src/main/kotlin/Utilities/DokkaLogging.kt
+++ b/core/src/main/kotlin/Utilities/DokkaLogging.kt
@@ -1,11 +1,5 @@
package org.jetbrains.dokka
-interface DokkaLogger {
- fun info(message: String)
- fun warn(message: String)
- fun error(message: String)
-}
-
object DokkaConsoleLogger : DokkaLogger {
var warningCount: Int = 0
diff --git a/integration/build.gradle b/integration/build.gradle
new file mode 100644
index 00000000..db2d6d78
--- /dev/null
+++ b/integration/build.gradle
@@ -0,0 +1,13 @@
+buildscript {
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+apply plugin: 'kotlin'
+
+
+dependencies {
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version
+} \ No newline at end of file
diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/DokkaBootstrap.kt b/integration/src/main/kotlin/org/jetbrains/dokka/DokkaBootstrap.kt
new file mode 100644
index 00000000..548aceb0
--- /dev/null
+++ b/integration/src/main/kotlin/org/jetbrains/dokka/DokkaBootstrap.kt
@@ -0,0 +1,22 @@
+package org.jetbrains.dokka
+
+interface DokkaBootstrap {
+
+ fun configure(logger: DokkaLogger,
+ moduleName: String,
+ classpath: List<String>,
+ sources: List<String>,
+ samples: List<String>,
+ includes: List<String>,
+ outputDir: String,
+ format: String,
+ includeNonPublic: Boolean,
+ reportUndocumented: Boolean,
+ skipEmptyPackages: Boolean,
+ skipDeprecated: Boolean,
+ jdkVersion: Int,
+ generateIndexPages: Boolean,
+ sourceLinks: List<String>)
+
+ fun generate()
+} \ No newline at end of file
diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/DokkaLogger.kt b/integration/src/main/kotlin/org/jetbrains/dokka/DokkaLogger.kt
new file mode 100644
index 00000000..fc1fac22
--- /dev/null
+++ b/integration/src/main/kotlin/org/jetbrains/dokka/DokkaLogger.kt
@@ -0,0 +1,8 @@
+package org.jetbrains.dokka
+
+interface DokkaLogger {
+ fun info(message: String)
+ fun warn(message: String)
+ fun error(message: String)
+}
+
diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/ProxyUtils.kt b/integration/src/main/kotlin/org/jetbrains/dokka/ProxyUtils.kt
new file mode 100644
index 00000000..66356f66
--- /dev/null
+++ b/integration/src/main/kotlin/org/jetbrains/dokka/ProxyUtils.kt
@@ -0,0 +1,76 @@
+package org.jetbrains.dokka
+
+import java.lang.reflect.InvocationHandler
+import java.lang.reflect.InvocationTargetException
+import java.lang.reflect.Method
+import java.lang.reflect.Proxy
+import java.util.function.Predicate
+
+
+/**
+ * Warning! Hard reflection magic used here.
+ *
+ * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
+ * to create access proxy for [delegate] from [targetClassLoader] to [delegateClassLoader].
+ *
+ * Every object type contained in method calls will be translated to proxy, if [filter.test] will success for it's class
+ *
+ */
+@Suppress("UNCHECKED_CAST")
+fun <T> automagicTypedProxy(targetClassLoader: ClassLoader, targetType: Class<T>,
+ delegateClassLoader: ClassLoader, delegate: Any,
+ filter: Predicate<Class<*>>): T =
+ automagicProxy(targetClassLoader, targetType, delegateClassLoader, delegate, filter) as T
+
+
+/**
+ * Warning! Hard reflection magic used here.
+ *
+ * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
+ * to create access proxy for [delegate] from [targetClassLoader] to [delegateClassLoader].
+ *
+ * Every object type contained in method calls will be translated to proxy, if [filter.test] will success for it's class
+ *
+ */
+fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>,
+ delegateClassLoader: ClassLoader, delegate: Any,
+ filter: Predicate<Class<*>>): Any =
+ Proxy.newProxyInstance(
+ targetClassLoader,
+ arrayOf(targetType),
+ DelegatedInvocationHandler(
+ delegate,
+ delegateClassLoader,
+ filter
+ )
+ )
+
+class DelegatedInvocationHandler(private val delegate: Any,
+ private val delegateClassLoader: ClassLoader,
+ private val filter: Predicate<Class<*>>)
+ : InvocationHandler {
+
+ @Throws(Throwable::class)
+ override fun invoke(proxy: Any, method: Method, args: Array<Any?>?): Any? {
+ val (argTypes, argValues) = method.parameterTypes.zip(args ?: emptyArray()).map { typeAndValue ->
+ val (type, value) = typeAndValue
+ if (filter.test(type)) {
+ val newType = delegateClassLoader.loadClass(type.name)
+ val newValue = value?.let {
+ automagicProxy(delegateClassLoader, newType, type.classLoader, value, filter)
+ }
+ newType to newValue
+ } else
+ typeAndValue
+ }.unzip()
+
+ val delegateMethod = delegate.javaClass.getMethod(method.name, *argTypes.toTypedArray())
+ try {
+ delegateMethod.isAccessible = true
+ return delegateMethod.invoke(delegate, *argValues.toTypedArray())
+ } catch (ex: InvocationTargetException) {
+ throw ex.targetException
+ }
+
+ }
+}
diff --git a/runners/android-gradle-plugin/build.gradle b/runners/android-gradle-plugin/build.gradle
index 6e8da695..4ea12edb 100644
--- a/runners/android-gradle-plugin/build.gradle
+++ b/runners/android-gradle-plugin/build.gradle
@@ -19,7 +19,7 @@ repositories {
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
- shadow project(':runners:fatjar')
+
shadow project(':runners:gradle-plugin')
provided gradleApi()
@@ -35,7 +35,6 @@ task sourceJar(type: Jar) {
shadowJar {
baseName = 'dokka-android-gradle-plugin'
classifier = ''
- relocate('kotlin.', 'dokkakotlin.')
}
apply plugin: 'maven-publish'
diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt
index 68192dc7..b31894eb 100644
--- a/runners/cli/src/main/kotlin/cli/main.kt
+++ b/runners/cli/src/main/kotlin/cli/main.kt
@@ -45,13 +45,6 @@ class DokkaArguments {
var jdkVersion: Int = 6
}
-private fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinition {
- val (path, urlAndLine) = srcLink.split('=')
- return SourceLinkDefinition(File(path).absolutePath,
- urlAndLine.substringBefore("#"),
- urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#" + it })
-}
-
fun main(args: Array<String>) {
val arguments = DokkaArguments()
val freeArgs: List<String> = Args.parse(arguments, args, false) ?: listOf()
diff --git a/runners/fatjar/build.gradle b/runners/fatjar/build.gradle
index d888a1ac..a9f0c721 100644
--- a/runners/fatjar/build.gradle
+++ b/runners/fatjar/build.gradle
@@ -22,29 +22,6 @@ shadowJar {
exclude provided
}
- relocate('com.', 'dokkacom.') {
- exclude 'com.sun.**'
- }
-
- relocate('org.', 'dokkaorg.') {
- exclude 'org.jetbrains.dokka.**'
- exclude 'org.xml.**'
- exclude 'org.w3c.**'
- exclude 'org.jaxen.**'
- exclude 'org.apache.xerces.**'
- exclude 'org.apache.xml.**'
- exclude 'org.fusesource.jansi.**'
- exclude 'org.apache.tools.ant.**'
- }
-
-
- relocate('kotlin.', 'dokkakotlin.') {
- exclude '**.*kotlin_builtins' //For kotlin_builtins, still not sure that we should relocate kotlin stdlib
- exclude 'kotlin.reflect' /* WAT? Ok, ok. Relocate works as Ctrl + Shift + R for ALL class files, so,
- if you have string "kotlin.reflect", it will be rewritten to not relevant "dokkakotlin.reflect" and you will got
- builtins crash in runtime, cause could not find dokkakotlin/reflect/reflect.kotlin_builtins */
- }
-
transform(ServiceFileTransformer)
transform(PluginXmlTransformer)
diff --git a/runners/gradle-plugin/build.gradle b/runners/gradle-plugin/build.gradle
index 3c330d18..8e6f11df 100644
--- a/runners/gradle-plugin/build.gradle
+++ b/runners/gradle-plugin/build.gradle
@@ -14,12 +14,13 @@ tasks.withType(AbstractCompile) {
}
dependencies {
-
- shadow project(':runners:fatjar')
testCompile group: 'junit', name: 'junit', version: '4.12'
- provided group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: kotlin_version
- provided group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-runtime', version: kotlin_version
+ compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: kotlin_version
+
+ compile project(":integration")
+
provided gradleApi()
provided localGroovy()
}
@@ -28,11 +29,19 @@ task sourceJar(type: Jar) {
from sourceSets.main.allSource
}
+processResources {
+ eachFile {
+ if (it.name == "org.jetbrains.dokka.properties") {
+ it.filter { line ->
+ line.replace("<version>", dokka_version)
+ }
+ }
+ }
+}
shadowJar {
baseName = 'dokka-gradle-plugin'
classifier = ''
- relocate('kotlin.', 'dokkakotlin.')
}
apply plugin: 'maven-publish'
diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt
index 49c3b8ba..f3e46c4d 100644
--- a/runners/gradle-plugin/src/main/kotlin/main.kt
+++ b/runners/gradle-plugin/src/main/kotlin/main.kt
@@ -8,15 +8,24 @@ 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.jetbrains.dokka.DocumentationOptions
-import org.jetbrains.dokka.DokkaGenerator
-import org.jetbrains.dokka.SourceLinkDefinition
+import org.jetbrains.dokka.DokkaBootstrap
+import org.jetbrains.dokka.automagicTypedProxy
+import org.jetbrains.dokka.gradle.ClassloaderContainer.fatJarClassLoader
import java.io.File
import java.io.Serializable
+import java.net.URLClassLoader
import java.util.*
+import java.util.function.Predicate
open class DokkaPlugin : Plugin<Project> {
+
+ val properties = Properties()
+
+ init {
+ properties.load(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties"))
+ }
override fun apply(project: Project) {
+ version = properties.getProperty("dokka-version")
project.tasks.create("dokka", DokkaTask::class.java).apply {
moduleName = project.name
outputDirectory = File(project.buildDir, "dokka").absolutePath
@@ -24,6 +33,13 @@ open class DokkaPlugin : Plugin<Project> {
}
}
+var version: String? = null
+
+object ClassloaderContainer {
+ @JvmField
+ var fatJarClassLoader: ClassLoader? = null
+}
+
open class DokkaTask : DefaultTask() {
init {
group = JavaBasePlugin.DOCUMENTATION_GROUP
@@ -47,6 +63,8 @@ open class DokkaTask : DefaultTask() {
var jdkVersion: Int = 6
@Input
var sourceDirs: Iterable<File> = emptyList()
+ @Input
+ var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:$version"
protected open val sdkProvider: SdkProvider? = null
@@ -65,8 +83,27 @@ open class DokkaTask : DefaultTask() {
linkMappings.add(mapping)
}
+
+ fun loadFatJar() {
+ if (fatJarClassLoader == null) {
+ val fatjar = if (dokkaFatJar is File)
+ dokkaFatJar as File
+ else {
+ val dependency = project.buildscript.dependencies.create(dokkaFatJar)
+ val configuration = project.buildscript.configurations.detachedConfiguration(dependency)
+ configuration.description = "Dokka main jar"
+ configuration.resolve().first()
+ }
+
+ fatJarClassLoader = URLClassLoader(arrayOf(fatjar.toURI().toURL()))
+ }
+ }
+
+
@TaskAction
fun generate() {
+ loadFatJar()
+
val project = project
val sdkProvider = sdkProvider
val sourceDirectories = getSourceDirectories()
@@ -83,17 +120,38 @@ open class DokkaTask : DefaultTask() {
return
}
- DokkaGenerator(
+ val bootstrapClass = fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl")
+
+ val bootstrapInstance = bootstrapClass.constructors.first().newInstance()
+
+ val bootstrapProxy = automagicTypedProxy(javaClass.classLoader,
+ DokkaBootstrap::class.java,
+ fatJarClassLoader!!,
+ bootstrapInstance,
+ Predicate { it.name.startsWith("org.jetbrains.dokka") }
+ )
+
+ bootstrapProxy.configure(
DokkaGradleLogger(logger),
+ moduleName,
classpath.map { it.absolutePath },
sourceDirectories.map { it.absolutePath },
samples.filterNotNull().map { project.file(it).absolutePath },
includes.filterNotNull().map { project.file(it).absolutePath },
- moduleName,
- DocumentationOptions(outputDirectory, outputFormat,
- sourceLinks = linkMappings.map { SourceLinkDefinition(project.file(it.dir).absolutePath, it.url, it.suffix) },
- jdkVersion = jdkVersion)
- ).generate()
+ outputDirectory,
+ outputFormat,
+ false,
+ false,
+ false,
+ false,
+ 6,
+ true,
+ linkMappings.map {
+ val path = project.file(it.dir).absolutePath
+ return@map "$path=${it.url}${it.suffix}"
+ })
+
+ bootstrapProxy.generate()
}
fun getSourceDirectories(): Collection<File> {
diff --git a/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties b/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
index b42cfe9f..068bd352 100644
--- a/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
+++ b/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
@@ -1 +1,2 @@
-implementation-class=org.jetbrains.dokka.gradle.DokkaPlugin \ No newline at end of file
+implementation-class=org.jetbrains.dokka.gradle.DokkaPlugin
+dokka-version=<version> \ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 4ffd0211..9da9e303 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include 'core', 'runners:fatjar', 'runners:ant', 'runners:cli', 'runners:maven-plugin', 'runners:gradle-plugin', 'runners:android-gradle-plugin'
+include 'core', 'runners:fatjar', 'runners:ant', 'runners:cli', 'runners:maven-plugin', 'runners:gradle-plugin', 'runners:android-gradle-plugin', 'integration'