summaryrefslogtreecommitdiff
path: root/plugins/kotlin/gradle/gradle-tooling/src/org/jetbrains/kotlin/idea/gradleTooling/reflect/KotlinArtifactReflection.kt
blob: 2035db8307f7b5828f97e9c322b7a1a23aea8812 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.gradleTooling.reflect

import org.gradle.api.Task
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Exec
import org.jetbrains.kotlin.idea.gradleTooling.loadClassOrNull
import java.io.File

fun KonanArtifactReflection(konanArtifact: Any): KonanArtifactReflection = KonanArtifactReflectionImpl(konanArtifact)

interface KonanArtifactReflection {
    val executableName: String?
    val compilationTargetName: String?
    val outputKindType: String?
    val konanTargetName: String?
    val outputFile: File?
    val linkTaskPath: String?
    val runTask: Exec?
    val isTests: Boolean?
    val freeCompilerArgs: Collection<String>?
}

private class KonanArtifactReflectionImpl(private val instance: Any) : KonanArtifactReflection {
    override val executableName: String? by lazy {
        instance.callReflectiveGetter("getBaseName", logger)
    }
    private val linkTask: Task? by lazy {
        instance.callReflectiveGetter("getLinkTask", logger)
    }
    override val linkTaskPath: String? by lazy {
        linkTask?.path
    }
    override val runTask: Exec? by lazy {
        if (instance.javaClass.classLoader.loadClassOrNull(NATIVE_EXECUTABLE_CLASS)?.isInstance(instance) == true)
            instance.callReflectiveGetter("getRunTask", logger)
        else null
    }

    override val compilationTargetName: String? by lazy {
        val compilation = linkTask?.callReflectiveAnyGetter("getCompilation", logger)?.let {
            when (it) {
                is Provider<*> -> it.get()
                else -> it
            }
        }
        compilation?.callReflectiveAnyGetter("getTarget", logger)
            ?.callReflectiveGetter("getName", logger)
    }
    override val outputKindType: String? by lazy {
        linkTask?.callReflectiveAnyGetter("getOutputKind", logger)
            ?.callReflectiveGetter("name", logger)
    }
    override val konanTargetName: String? by lazy {
        linkTask?.callReflectiveGetter("getTarget", logger)
    }
    override val outputFile: File? by lazy {
        when (val outputFile = instance.callReflective("getOutputFile", parameters(), returnType<Any>(), logger)) {
            is Provider<*> -> outputFile.orNull as? File
            is File -> outputFile
            else -> null
        }
    }
    override val isTests: Boolean? by lazy {
        linkTask?.callReflectiveGetter("getProcessTests", logger)
    }

    override val freeCompilerArgs: Collection<String>? by lazy {
        linkTask?.callReflectiveAnyGetter("getKotlinOptions", logger)
            ?.callReflectiveGetter("getFreeCompilerArgs", logger)
    }

    companion object {
        private val logger: ReflectionLogger = ReflectionLogger(KonanArtifactReflection::class.java)
        private const val NATIVE_EXECUTABLE_CLASS = "org.jetbrains.kotlin.gradle.plugin.mpp.Executable"
    }
}