G2K: Rewrite AndroidGradleWrapper in Kotlin
This commit is contained in:
+3
-1
@@ -128,7 +128,9 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
|
|
||||||
addVariant(mainSourceSet)
|
addVariant(mainSourceSet)
|
||||||
|
|
||||||
val flavorSourceSets = AndroidGradleWrapper.getProductFlavorsSourceSets(androidExtension).filterNotNull()
|
val flavorSourceSets = androidExtension.productFlavors
|
||||||
|
.mapNotNull { androidExtension.sourceSets.findByName(it.name) }
|
||||||
|
|
||||||
for (sourceSet in flavorSourceSets) {
|
for (sourceSet in flavorSourceSets) {
|
||||||
addVariant(sourceSet)
|
addVariant(sourceSet)
|
||||||
}
|
}
|
||||||
|
|||||||
+173
-244
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.android
|
package org.jetbrains.kotlin.gradle.plugin.android
|
||||||
@@ -19,259 +8,199 @@ package org.jetbrains.kotlin.gradle.plugin.android
|
|||||||
import com.android.build.gradle.BaseExtension
|
import com.android.build.gradle.BaseExtension
|
||||||
import com.android.build.gradle.BasePlugin
|
import com.android.build.gradle.BasePlugin
|
||||||
import com.android.build.gradle.api.AndroidSourceSet
|
import com.android.build.gradle.api.AndroidSourceSet
|
||||||
import com.android.build.gradle.api.ApkVariant
|
|
||||||
import com.android.build.gradle.api.BaseVariant
|
|
||||||
import com.android.build.gradle.api.TestVariant
|
|
||||||
import com.android.build.gradle.internal.VariantManager
|
import com.android.build.gradle.internal.VariantManager
|
||||||
import com.android.build.gradle.internal.variant.BaseVariantData
|
import com.android.build.gradle.internal.variant.BaseVariantData
|
||||||
import com.android.builder.model.SourceProvider
|
|
||||||
import org.gradle.api.file.ConfigurableFileTree
|
import org.gradle.api.file.ConfigurableFileTree
|
||||||
import org.gradle.api.internal.DefaultDomainObjectSet
|
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.gradle.api.tasks.util.PatternFilterable
|
import java.io.File
|
||||||
import org.jetbrains.annotations.NotNull
|
import java.lang.reflect.Field
|
||||||
import org.jetbrains.annotations.Nullable
|
import java.lang.reflect.InvocationTargetException
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
|
|
||||||
class AndroidGradleWrapper {
|
object AndroidGradleWrapper {
|
||||||
static def getRuntimeJars(BasePlugin basePlugin, BaseExtension baseExtension) {
|
fun getRuntimeJars(basePlugin: BasePlugin, baseExtension: BaseExtension): Any? {
|
||||||
if (basePlugin.getMetaClass().getMetaMethod("getRuntimeJarList")) {
|
return basePlugin("getRuntimeJarList") ?: baseExtension("getBootClasspath") ?: basePlugin("getBootClasspath")
|
||||||
return basePlugin.getRuntimeJarList()
|
|
||||||
}
|
|
||||||
else if (baseExtension.getMetaClass().getMetaMethod("getBootClasspath")) {
|
|
||||||
return baseExtension.getBootClasspath()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return basePlugin.getBootClasspath()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static def srcDir(Object androidSourceSet, Object kotlinDirSet) {
|
|
||||||
androidSourceSet.getJava().srcDir(kotlinDirSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
static PatternFilterable getResourceFilter(Object androidSourceSet) {
|
|
||||||
def resources = androidSourceSet.getResources()
|
|
||||||
if (resources != null) {
|
|
||||||
return resources.getFilter()
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static String getVariantName(Object variant) {
|
|
||||||
return variant.getBuildType().getName()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static getJackOptions(@NotNull Object variantData) {
|
|
||||||
def variantConfiguration = variantData.variantConfiguration
|
|
||||||
if (variantConfiguration.getMetaClass().getMetaMethod("getJackOptions")) {
|
|
||||||
return variantConfiguration.getJackOptions()
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isJackEnabled(@NotNull Object variantData) {
|
|
||||||
return getJackOptions(variantData)?.enabled ?: false
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
static AbstractCompile getJavaTask(@NotNull Object variantData) {
|
|
||||||
return getJavaCompile(variantData)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static AbstractCompile getJavacTask(@NotNull Object baseVariantData) {
|
|
||||||
if (baseVariantData.getMetaClass().getMetaProperty("javacTask")) {
|
|
||||||
return baseVariantData.javacTask
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static AbstractCompile getJavaCompile(@NotNull Object baseVariantData) {
|
|
||||||
if (baseVariantData.getMetaClass().getMetaProperty("javaCompileTask")) {
|
|
||||||
return baseVariantData.javaCompileTask
|
|
||||||
}
|
|
||||||
else if (baseVariantData.getMetaClass().getMetaProperty("javaCompilerTask")) {
|
|
||||||
return baseVariantData.javaCompilerTask
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static Set<File> getJavaSrcDirs(Object androidSourceSet) {
|
|
||||||
return androidSourceSet.getJava().getSrcDirs()
|
|
||||||
}
|
|
||||||
|
|
||||||
static def setNoJdk(Object kotlinOptionsExtension) {
|
|
||||||
kotlinOptionsExtension.noJdk = true
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static List<String> getProductFlavorsNames(ApkVariant variant) {
|
|
||||||
return variant.getProductFlavors().iterator().collect { it.getName() }
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static List<AndroidSourceSet> getProductFlavorsSourceSets(BaseExtension extension) {
|
|
||||||
return extension.productFlavors.iterator().collect { extension.sourceSets.findByName(it.name) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
static Map<String, String> getAnnotationProcessorOptionsFromAndroidVariant(@Nullable Object variantData) {
|
|
||||||
if (!(variantData instanceof BaseVariantData)) {
|
|
||||||
throw new IllegalArgumentException("BaseVariantData instance expected")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def variantConfiguration = variantData.variantConfiguration
|
fun isJackEnabled(variantData: Any): Boolean {
|
||||||
if (variantConfiguration.getMetaClass().getMetaMethod("getJavaCompileOptions")) {
|
val variantConfiguration = variantData("getVariantConfiguration")
|
||||||
def javaCompileOptions = variantConfiguration.getJavaCompileOptions()
|
return (variantConfiguration("getUseJack") ?: variantConfiguration("getJackOptions")("isEnabled")) as? Boolean ?: false
|
||||||
|
|
||||||
if (javaCompileOptions.getMetaClass().getMetaMethod("getAnnotationProcessorOptions")) {
|
|
||||||
return javaCompileOptions.getAnnotationProcessorOptions().getArguments()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
fun getJavaTask(variantData: Any): AbstractCompile? {
|
||||||
}
|
return getJavaCompile(variantData)
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static DefaultDomainObjectSet<TestVariant> getTestVariants(BaseExtension extension) {
|
|
||||||
if (extension.getMetaClass().getMetaMethod("getTestVariants")) {
|
|
||||||
return extension.getTestVariants()
|
|
||||||
}
|
|
||||||
return Collections.emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static List<File> getRClassFolder(BaseVariant variant) {
|
|
||||||
def list = new ArrayList<File>()
|
|
||||||
if (variant.getMetaClass().getMetaMethod("getProcessResources")) {
|
|
||||||
list.add(variant.getProcessResources().getSourceOutputDir())
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (Object variantOutput : variant.getOutputs()) {
|
|
||||||
list.add(variantOutput.processResources.sourceOutputDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
static VariantManager getVariantDataManager(BasePlugin plugin) {
|
|
||||||
return plugin.getVariantManager()
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<File> getJavaSources(BaseVariantData variantData) {
|
|
||||||
def result = new LinkedHashSet<File>()
|
|
||||||
|
|
||||||
// user sources
|
|
||||||
List<SourceProvider> providers = variantData.variantConfiguration.getSortedSourceProviders()
|
|
||||||
for (SourceProvider provider : providers) {
|
|
||||||
result.addAll((provider as AndroidSourceSet).getJava().getSrcDirs())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generated sources
|
private fun getJavaCompile(baseVariantData: Any): AbstractCompile? {
|
||||||
def getJavaSourcesMethod = variantData.getMetaClass().getMetaMethod("getJavaSources")
|
return (baseVariantData["javaCompileTask"] ?: baseVariantData["javaCompilerTask"]) as? AbstractCompile
|
||||||
if (getJavaSourcesMethod.returnType.metaClass == Object[].metaClass) {
|
|
||||||
result.addAll(variantData.getJavaSources().findAll { it instanceof File })
|
|
||||||
}
|
|
||||||
else if (getJavaSourcesMethod.returnType.metaClass == List.metaClass) {
|
|
||||||
def fileTrees = variantData.getJavaSources().findAll { it instanceof ConfigurableFileTree }
|
|
||||||
result.addAll(fileTrees.collect { it.getDir() })
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (variantData.scope.getGenerateRClassTask() != null) {
|
|
||||||
result.add(variantData.scope.getRClassSourceOutputDir())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (variantData.scope.getGenerateBuildConfigTask() != null) {
|
|
||||||
result.add(variantData.scope.getBuildConfigSourceOutputDir())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (variantData.scope.getAidlCompileTask() != null) {
|
|
||||||
result.add(variantData.scope.getAidlSourceOutputDir())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (variantData.scope.getGlobalScope().getExtension().getDataBinding().isEnabled()) {
|
|
||||||
result.add(variantData.scope.getClassOutputForDataBinding())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!variantData.variantConfiguration.getRenderscriptNdkModeEnabled()
|
|
||||||
&& variantData.scope.getRenderscriptCompileTask() != null) {
|
|
||||||
result.add(variantData.scope.getRenderscriptSourceOutputDir())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def getExtraSourcesMethod = variantData.getMetaClass().getMetaMethod("getExtraGeneratedSourceFolders")
|
fun getAnnotationProcessorOptionsFromAndroidVariant(variantData: Any?): Map<String, String>? {
|
||||||
if (getExtraSourcesMethod.returnType.metaClass == List.metaClass) {
|
if (variantData !is BaseVariantData<*>) {
|
||||||
def folders = variantData.getExtraGeneratedSourceFolders()
|
throw IllegalArgumentException("BaseVariantData instance expected")
|
||||||
if (folders != null) {
|
|
||||||
result.addAll(folders)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static Map<File, File> getJarToAarMapping(BaseVariantData variantData) {
|
|
||||||
def jarToLibraryArtifactMap = new HashMap<File, File>()
|
|
||||||
|
|
||||||
def libraries = getVariantLibraryDependencies(variantData)
|
|
||||||
if (libraries == null) return jarToLibraryArtifactMap
|
|
||||||
|
|
||||||
for (lib in libraries) {
|
|
||||||
Object bundle = getLibraryArtifactFile(lib)
|
|
||||||
jarToLibraryArtifactMap[lib.jarFile] = bundle
|
|
||||||
|
|
||||||
// local dependencies are detected as changed by gradle, because they are seem to be
|
|
||||||
// rewritten every time when bundle changes
|
|
||||||
// when local dep will actually change, record for bundle will be removed from registry
|
|
||||||
for (localDep in lib.localJars) {
|
|
||||||
if (localDep instanceof File) {
|
|
||||||
// android tools 2.2
|
|
||||||
jarToLibraryArtifactMap[localDep] = bundle
|
|
||||||
}
|
}
|
||||||
else if (localDep.metaClass.getMetaMethod("jarFile") != null) {
|
|
||||||
// android tools < 2.2
|
val compileOptions = variantData("getVariantConfiguration")("getJavaCompileOptions") ?: return null
|
||||||
jarToLibraryArtifactMap[localDep.jarFile] = bundle
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return compileOptions("getAnnotationProcessorOptions")("getArguments") as? Map<String, String>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getVariantDataManager(plugin: BasePlugin): VariantManager {
|
||||||
|
return plugin("getVariantManager") as VariantManager
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getJavaSources(variantData: BaseVariantData<*>): List<File> {
|
||||||
|
val result = LinkedHashSet<File>()
|
||||||
|
|
||||||
|
// user sources
|
||||||
|
for (provider in variantData.variantConfiguration.sortedSourceProviders) {
|
||||||
|
result.addAll((provider as AndroidSourceSet).java.srcDirs)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// generated sources
|
||||||
|
val javaSources = variantData("getJavaSources")
|
||||||
|
if (javaSources is Array<*>) {
|
||||||
|
result += javaSources.filterIsInstance<File>()
|
||||||
|
} else if (javaSources is List<*>) {
|
||||||
|
val fileTrees = javaSources.filterIsInstance<ConfigurableFileTree>()
|
||||||
|
result += fileTrees.map { it.dir }
|
||||||
|
} else {
|
||||||
|
if (variantData.scope.generateRClassTask != null) {
|
||||||
|
result += variantData.scope.rClassSourceOutputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantData.scope.generateBuildConfigTask != null) {
|
||||||
|
result += variantData.scope.buildConfigSourceOutputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantData.scope.aidlCompileTask != null) {
|
||||||
|
result += variantData.scope.aidlSourceOutputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variantData.scope.globalScope.extension.dataBinding.isEnabled) {
|
||||||
|
result += variantData.scope.classOutputForDataBinding
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!variantData.variantConfiguration.renderscriptNdkModeEnabled && variantData.scope.renderscriptCompileTask != null) {
|
||||||
|
result += variantData.scope.renderscriptSourceOutputDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val extraSources = variantData("getExtraGeneratedSourceFolders") as? List<*>
|
||||||
|
if (extraSources != null) {
|
||||||
|
result += extraSources.filterIsInstance<File>()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
return jarToLibraryArtifactMap
|
fun getJarToAarMapping(variantData: BaseVariantData<*>): Map<File, File> {
|
||||||
}
|
val jarToLibraryArtifactMap = hashMapOf<File, File>()
|
||||||
|
|
||||||
private static def getLibraryArtifactFile(Object lib) {
|
val libraries = getVariantLibraryDependencies(variantData) ?: return jarToLibraryArtifactMap
|
||||||
if (lib.class.name == "com.android.builder.dependency.level2.AndroidDependency") {
|
|
||||||
// android tools >= 2.3
|
|
||||||
return lib.artifactFile
|
|
||||||
} else {
|
|
||||||
// android tools <= 2.2
|
|
||||||
return lib.bundle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
for (lib in libraries) {
|
||||||
private static Iterable<Object> getVariantLibraryDependencies(BaseVariantData variantData) {
|
lib ?: continue
|
||||||
def variantDependency = variantData.variantDependency
|
val bundle = getLibraryArtifactFile(lib) ?: continue
|
||||||
|
val libJarFile = lib("getJarFile") as? File ?: continue
|
||||||
|
|
||||||
if (variantDependency.metaClass.getMetaMethod("getAndroidDependencies") != null) {
|
jarToLibraryArtifactMap[libJarFile] = bundle
|
||||||
// android tools < 2.2
|
|
||||||
return variantDependency.getAndroidDependencies() as Iterable<Object>
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val localJarsForLib = lib("getLocalJars") as? List<*> ?: emptyList<Any>()
|
||||||
|
|
||||||
|
// local dependencies are detected as changed by gradle, because they are seem to be
|
||||||
|
// rewritten every time when bundle changes
|
||||||
|
// when local dep will actually change, record for bundle will be removed from registry
|
||||||
|
for (localDep in localJarsForLib) {
|
||||||
|
if (localDep is File) {
|
||||||
|
// android tools 2.2
|
||||||
|
jarToLibraryArtifactMap[localDep] = bundle
|
||||||
|
} else {
|
||||||
|
// android tools < 2.2
|
||||||
|
val jarFile = localDep("getJarFile") as? File ?: continue
|
||||||
|
jarToLibraryArtifactMap[jarFile] = bundle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jarToLibraryArtifactMap
|
||||||
}
|
}
|
||||||
|
|
||||||
def getCompileDependencies = variantDependency.metaClass.getMetaMethod("getCompileDependencies")
|
private fun getLibraryArtifactFile(lib: Any): File? {
|
||||||
if (getCompileDependencies != null) {
|
return if (lib.javaClass.name == "com.android.builder.dependency.level2.AndroidDependency") {
|
||||||
def compileDependencies = variantDependency.getCompileDependencies()
|
// android tools >= 2.3
|
||||||
if (compileDependencies.metaClass.getMetaMethod("getDirectAndroidDependencies") != null) {
|
lib("getArtifactFile") as? File
|
||||||
return compileDependencies.getDirectAndroidDependencies() // android >= 2.3
|
} else {
|
||||||
} else if (compileDependencies.metaClass.getMetaMethod("getAndroidDependencies")) {
|
// android tools <= 2.2
|
||||||
return compileDependencies.getAndroidDependencies() // android 2.2
|
lib("getBundle") as? File
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
private fun getVariantLibraryDependencies(variantData: BaseVariantData<*>): Iterable<*>? {
|
||||||
}
|
val variantDependency = variantData.variantDependency
|
||||||
|
|
||||||
|
variantDependency("getAndroidDependencies")?.let {
|
||||||
|
// android tools < 2.2
|
||||||
|
return it as Iterable<*>
|
||||||
|
}
|
||||||
|
|
||||||
|
val compileDependencies = variantDependency("getCompileDependencies") ?: return null
|
||||||
|
val result = compileDependencies("getDirectAndroidDependencies") // android >= 2.3
|
||||||
|
?: compileDependencies("getAndroidDependencies") // android 2.2
|
||||||
|
|
||||||
|
return result as? Iterable<*>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private operator fun Any?.invoke(methodName: String): Any? {
|
||||||
|
if (this == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Array<Method>.findMethod() =
|
||||||
|
singleOrNull { it.name == methodName && it.parameterCount == 0 && !Modifier.isStatic(it.modifiers) }
|
||||||
|
|
||||||
|
val clazz = this::class.java
|
||||||
|
val methodToInvoke = clazz.declaredMethods.findMethod() ?: clazz.methods.findMethod() ?: return null
|
||||||
|
val oldIsAccessible = methodToInvoke.isAccessible
|
||||||
|
|
||||||
|
try {
|
||||||
|
methodToInvoke.isAccessible = true
|
||||||
|
return methodToInvoke.invoke(this)
|
||||||
|
} catch (e: InvocationTargetException) {
|
||||||
|
throw e.targetException
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw RuntimeException("Can't invoke method '$methodName()' on $this", e)
|
||||||
|
} finally {
|
||||||
|
methodToInvoke.isAccessible = oldIsAccessible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private operator fun Any?.get(name: String): Any? {
|
||||||
|
if (this == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.invoke("get" + name.capitalize())?.let { return it }
|
||||||
|
|
||||||
|
fun Array<Field>.findField() = singleOrNull { it.name == name && !Modifier.isStatic(it.modifiers) }
|
||||||
|
|
||||||
|
val clazz = this::class.java
|
||||||
|
val fieldToInvoke = clazz.declaredFields.findField() ?: clazz.fields.findField() ?: return null
|
||||||
|
val oldIsAccessible = fieldToInvoke.isAccessible
|
||||||
|
|
||||||
|
try {
|
||||||
|
fieldToInvoke.isAccessible = true
|
||||||
|
return fieldToInvoke.get(this)
|
||||||
|
} catch (e: InvocationTargetException) {
|
||||||
|
throw e.targetException
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
throw RuntimeException("Couldn't get value of field '$name' in $this", e)
|
||||||
|
} finally {
|
||||||
|
fieldToInvoke.isAccessible = oldIsAccessible
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user