summaryrefslogtreecommitdiff
path: root/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/platform/IdePlatformKindTooling.kt
blob: 4eb9061c2d8c118eae83b0ce0481d5fe1b5b0f55 (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
78
79
80
81
82
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package org.jetbrains.kotlin.idea.platform

import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor
import org.jetbrains.kotlin.idea.projectModel.KotlinPlatform
import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import javax.swing.Icon

abstract class IdePlatformKindTooling {
    abstract val kind: IdePlatformKind

    abstract fun compilerArgumentsForProject(project: Project): CommonCompilerArguments?

    abstract val mavenLibraryIds: List<String>
    abstract val gradlePluginId: String

    abstract val gradlePlatformIds: List<KotlinPlatform>

    abstract val libraryKind: PersistentLibraryKind<*>?
    abstract fun getLibraryDescription(project: Project): CustomLibraryDescription?
    abstract fun getLibraryVersionProvider(project: Project): (Library) -> String?

    abstract fun getTestIcon(declaration: KtNamedDeclaration, descriptorProvider: () -> DeclarationDescriptor?): Icon?

    abstract fun acceptsAsEntryPoint(function: KtFunction): Boolean

    override fun equals(other: Any?): Boolean = javaClass == other?.javaClass
    override fun hashCode(): Int = javaClass.hashCode()

    companion object : ApplicationExtensionDescriptor<IdePlatformKindTooling>(
        "org.jetbrains.kotlin.idePlatformKindTooling", IdePlatformKindTooling::class.java
    ) {
        private val ALL_TOOLING_SUPPORT by lazy { getInstances() }

        private val TOOLING_SUPPORT_BY_KIND by lazy {
            val allPlatformKinds = IdePlatformKind.ALL_KINDS
            val groupedTooling = ALL_TOOLING_SUPPORT.groupBy { it.kind }.mapValues { it.value.single() }

            for (kind in allPlatformKinds) {
                if (kind !in groupedTooling) {
                    throw IllegalStateException(
                        "Tooling support for the platform '$kind' is missing. " +
                                "Implement 'IdePlatformKindTooling' for it."
                    )
                }
            }

            groupedTooling
        }

        private val TOOLING_SUPPORT_BY_PLATFORM_ID by lazy {
            ALL_TOOLING_SUPPORT.flatMap { tooling -> tooling.gradlePlatformIds.map { it to tooling } }.toMap()
        }

        fun getTooling(kind: IdePlatformKind): IdePlatformKindTooling {
            return TOOLING_SUPPORT_BY_KIND[kind] ?: error("Unknown platform $kind")
        }

        /**
         * @return null if current IDE doesn't know given platform
         */
        fun getToolingIfAny(platformId: KotlinPlatform): IdePlatformKindTooling? {
            return TOOLING_SUPPORT_BY_PLATFORM_ID[platformId]
        }

        fun getTooling(platformId: KotlinPlatform): IdePlatformKindTooling {
            return getToolingIfAny(platformId) ?: error("Unknown Gradle platform $platformId")
        }
    }
}

val IdePlatformKind.tooling: IdePlatformKindTooling
    get() = IdePlatformKindTooling.getTooling(this)