Kotlin Facet: Extract VersionInfo class and getVersionInfo() utility function

This commit is contained in:
Alexey Sedunov
2016-10-26 14:43:10 +03:00
parent 37286d5b06
commit e0285b9955
3 changed files with 129 additions and 80 deletions
@@ -21,10 +21,8 @@ import com.intellij.facet.ui.FacetEditorContext
import com.intellij.facet.ui.FacetEditorTab
import com.intellij.facet.ui.FacetValidatorsManager
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.util.Key
import org.jdom.Element
import org.jetbrains.kotlin.idea.util.DescriptionAware
import java.util.*
class KotlinFacetConfiguration : FacetConfiguration, PersistentStateComponent<KotlinFacetConfiguration.Settings> {
enum class LanguageLevel(override val description: String) : DescriptionAware {
@@ -38,10 +36,14 @@ class KotlinFacetConfiguration : FacetConfiguration, PersistentStateComponent<Ko
JS("JavaScript")
}
data class VersionInfo(
var languageLevel: LanguageLevel? = null,
var apiLevel: LanguageLevel? = null,
var targetPlatformKind: TargetPlatform? = null
)
class Settings {
var languageLevel: LanguageLevel? = null
var apiLevel: LanguageLevel? = null
var targetPlatformKind: TargetPlatform? = null
val versionInfo = VersionInfo()
}
private var settings = Settings()
@@ -19,17 +19,11 @@ package org.jetbrains.kotlin.idea.facet
import com.intellij.facet.impl.ui.libraries.DelegatingLibrariesValidatorContext
import com.intellij.facet.ui.*
import com.intellij.facet.ui.libraries.FrameworkLibraryValidator
import com.intellij.framework.library.LibraryVersionProperties
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.libraries.LibraryPresentationProvider
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription
import com.intellij.util.text.VersionComparatorUtil
import com.intellij.util.ui.FormBuilder
import org.jetbrains.kotlin.idea.framework.*
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription
import org.jetbrains.kotlin.idea.util.DescriptionAware
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
import java.awt.BorderLayout
import java.awt.Component
import javax.swing.*
@@ -51,7 +45,8 @@ class KotlinFacetEditorTab(
override fun check(): ValidationResult {
val apiLevel = apiVersionComboBox.selectedItem as? KotlinFacetConfiguration.LanguageLevel? ?: return ValidationResult.OK
val languageLevel = languageVersionComboBox.selectedItem as? KotlinFacetConfiguration.LanguageLevel? ?: return ValidationResult.OK
val libraryLevel = getLibraryLanguageLevel()
val targetPlatform = targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform?
val libraryLevel = getLibraryLanguageLevel(editorContext.module, editorContext.rootModel, targetPlatform)
if (languageLevel < apiLevel || libraryLevel < apiLevel) {
return ValidationResult("Language version/Runtime version may not be less than API version", null)
}
@@ -87,50 +82,6 @@ class KotlinFacetEditorTab(
private val libraryValidator: FrameworkLibraryValidator
private val versionValidator = VersionValidator()
private fun getRuntimeLibraryVersions(presentationProvider: LibraryPresentationProvider<LibraryVersionProperties>): List<String> {
return editorContext
.rootModel
.orderEntries
.asSequence()
.filterIsInstance<LibraryOrderEntry>()
.mapNotNull { it.library?.let { getLibraryProperties(presentationProvider, it) } ?.versionString }
.toList()
}
private fun getDefaultTargetPlatform(): KotlinFacetConfiguration.TargetPlatform {
getRuntimeLibraryVersions(JSLibraryStdPresentationProvider.getInstance()).firstOrNull()?.let {
return KotlinFacetConfiguration.TargetPlatform.JS
}
val sdk = editorContext.rootModel.sdk
val sdkVersion = (sdk?.sdkType as? JavaSdk)?.getVersion(sdk!!)
return when {
sdkVersion != null && sdkVersion <= JavaSdkVersion.JDK_1_6 -> KotlinFacetConfiguration.TargetPlatform.JVM_1_6
else -> KotlinFacetConfiguration.TargetPlatform.JVM_1_8
}
}
private fun getDefaultLanguageLevel(libraryVersion: String? = null): KotlinFacetConfiguration.LanguageLevel {
val libVersion = libraryVersion ?: bundledRuntimeVersion()
return when {
libVersion.startsWith("1.0") -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_0
else -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_1
}
}
private fun getLibraryLanguageLevel(): KotlinFacetConfiguration.LanguageLevel {
val presentationProvider = when (targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform?) {
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdPresentationProvider.getInstance()
KotlinFacetConfiguration.TargetPlatform.JVM_1_6,
KotlinFacetConfiguration.TargetPlatform.JVM_1_8,
null ->
JavaRuntimePresentationProvider.getInstance()
}
val minVersion = getRuntimeLibraryVersions(presentationProvider).minWith(VersionComparatorUtil.COMPARATOR)
return getDefaultLanguageLevel(minVersion)
}
init {
libraryValidator = FrameworkLibraryValidatorWithDynamicDescription(
DelegatingLibrariesValidatorContext(editorContext),
@@ -145,39 +96,33 @@ class KotlinFacetEditorTab(
validatorsManager.validate()
}
with(configuration.state) {
if (targetPlatformKind == null) {
targetPlatformKind = getDefaultTargetPlatform()
}
if (languageLevel == null) {
languageLevel = getDefaultLanguageLevel()
}
if (apiLevel == null) {
apiLevel = languageLevel!!.coerceAtMost(getLibraryLanguageLevel())
}
}
configuration.state.versionInfo.initializeIfNeeded(editorContext.module, editorContext.rootModel)
reset()
}
override fun isModified(): Boolean {
return languageVersionComboBox.selectedItem != configuration.state.languageLevel
|| targetPlatformComboBox.selectedItem != configuration.state.targetPlatformKind
|| apiVersionComboBox.selectedItem != configuration.state.apiLevel
return with(configuration.state.versionInfo) {
languageVersionComboBox.selectedItem != languageLevel
|| targetPlatformComboBox.selectedItem != targetPlatformKind
|| apiVersionComboBox.selectedItem != apiLevel
}
}
override fun reset() {
languageVersionComboBox.selectedItem = configuration.state.languageLevel
targetPlatformComboBox.selectedItem = configuration.state.targetPlatformKind
apiVersionComboBox.selectedItem = configuration.state.apiLevel
with(configuration.state.versionInfo) {
languageVersionComboBox.selectedItem = languageLevel
targetPlatformComboBox.selectedItem = targetPlatformKind
apiVersionComboBox.selectedItem = apiLevel
}
}
override fun apply() {
configuration.state.languageLevel = languageVersionComboBox.selectedItem as KotlinFacetConfiguration.LanguageLevel?
configuration.state.targetPlatformKind = targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform?
configuration.state.apiLevel = apiVersionComboBox.selectedItem as KotlinFacetConfiguration.LanguageLevel?
with(configuration.state.versionInfo) {
languageLevel = languageVersionComboBox.selectedItem as KotlinFacetConfiguration.LanguageLevel?
targetPlatformKind = targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform?
apiLevel = apiVersionComboBox.selectedItem as KotlinFacetConfiguration.LanguageLevel?
}
}
override fun getDisplayName() = "General"
@@ -0,0 +1,102 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* 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.idea.facet
import com.intellij.framework.library.LibraryVersionProperties
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.openapi.roots.libraries.LibraryPresentationProvider
import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.idea.framework.JSLibraryStdPresentationProvider
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
import org.jetbrains.kotlin.idea.framework.getLibraryProperties
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
private fun getRuntimeLibraryVersions(
module: Module,
rootModel: ModuleRootModel?,
presentationProvider: LibraryPresentationProvider<LibraryVersionProperties>
): List<String> {
return (rootModel ?: ModuleRootManager.getInstance(module))
.orderEntries
.asSequence()
.filterIsInstance<LibraryOrderEntry>()
.mapNotNull { it.library?.let { getLibraryProperties(presentationProvider, it) }?.versionString }
.toList()
}
private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel?): KotlinFacetConfiguration.TargetPlatform {
getRuntimeLibraryVersions(module, rootModel, JSLibraryStdPresentationProvider.getInstance())
.firstOrNull()
?.let { return KotlinFacetConfiguration.TargetPlatform.JS }
val sdk = ((rootModel ?: ModuleRootManager.getInstance(module))).sdk
val sdkVersion = (sdk?.sdkType as? JavaSdk)?.getVersion(sdk!!)
return when {
sdkVersion != null && sdkVersion <= JavaSdkVersion.JDK_1_6 -> KotlinFacetConfiguration.TargetPlatform.JVM_1_6
else -> KotlinFacetConfiguration.TargetPlatform.JVM_1_8
}
}
private fun getDefaultLanguageLevel(explicitVersion: String? = null): KotlinFacetConfiguration.LanguageLevel {
val libVersion = explicitVersion ?: bundledRuntimeVersion()
return when {
libVersion.startsWith("1.0") -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_0
else -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_1
}
}
internal fun getLibraryLanguageLevel(
module: Module,
rootModel: ModuleRootModel?,
targetPlatform: KotlinFacetConfiguration.TargetPlatform?
): KotlinFacetConfiguration.LanguageLevel {
val presentationProvider = when (targetPlatform) {
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdPresentationProvider.getInstance()
KotlinFacetConfiguration.TargetPlatform.JVM_1_6,
KotlinFacetConfiguration.TargetPlatform.JVM_1_8,
null ->
JavaRuntimePresentationProvider.getInstance()
}
val minVersion = getRuntimeLibraryVersions(module, rootModel, presentationProvider).minWith(VersionComparatorUtil.COMPARATOR)
return getDefaultLanguageLevel(minVersion)
}
internal fun KotlinFacetConfiguration.VersionInfo.initializeIfNeeded(module: Module, rootModel: ModuleRootModel?) {
if (targetPlatformKind == null) {
targetPlatformKind = getDefaultTargetPlatform(module, rootModel)
}
if (languageLevel == null) {
languageLevel = getDefaultLanguageLevel()
}
if (apiLevel == null) {
apiLevel = languageLevel!!.coerceAtMost(getLibraryLanguageLevel(module, rootModel, targetPlatformKind!!))
}
}
internal fun Module.getKotlinVersionInfo(rootModel: ModuleRootModel? = null): KotlinFacetConfiguration.VersionInfo {
val versionInfo = KotlinFacet.get(this)?.configuration?.state?.versionInfo ?: KotlinFacetConfiguration.VersionInfo()
versionInfo.initializeIfNeeded(this, rootModel)
return versionInfo
}