Kotlin Facet: Use Kotlin SDK for non-JVM imported modules

This commit is contained in:
Alexey Sedunov
2018-01-18 18:47:15 +03:00
parent 70cb08bfdb
commit 737d7dcc2f
5 changed files with 47 additions and 18 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.idea.configuration.allConfigurators
import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.idea.util.projectStructure.allModules
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
@@ -499,6 +500,9 @@ compileTestKotlin {
assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind) assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind)
assertTrue(stdlib.getFiles(OrderRootType.CLASSES).isNotEmpty()) assertTrue(stdlib.getFiles(OrderRootType.CLASSES).isNotEmpty())
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_main")).sdk!!.sdkType is KotlinSdkType)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_test")).sdk!!.sdkType is KotlinSdkType)
assertAllModulesConfigured() assertAllModulesConfigured()
} }
@@ -1780,6 +1784,9 @@ compileTestKotlin {
val rootManager = ModuleRootManager.getInstance(getModule("project_main")) val rootManager = ModuleRootManager.getInstance(getModule("project_main"))
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind) assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_main")).sdk!!.sdkType is KotlinSdkType)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project_test")).sdk!!.sdkType is KotlinSdkType)
} }
private fun assertAllModulesConfigured() { private fun assertAllModulesConfigured() {
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import org.jetbrains.kotlin.idea.refactoring.toPsiFile import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.junit.Assert import org.junit.Assert
@@ -627,6 +628,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
val rootManager = ModuleRootManager.getInstance(getModule("project")) val rootManager = ModuleRootManager.getInstance(getModule("project"))
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind) assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testFacetSplitConfiguration() { fun testFacetSplitConfiguration() {
@@ -1013,6 +1016,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertImporterStatePresent() assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testJsDetectionByGoalWithJsStdlib() { fun testJsDetectionByGoalWithJsStdlib() {
@@ -1063,6 +1068,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertImporterStatePresent() assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testJsDetectionByGoalWithCommonStdlib() { fun testJsDetectionByGoalWithCommonStdlib() {
@@ -1113,6 +1120,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertImporterStatePresent() assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testJsAndCommonStdlibKinds() { fun testJsAndCommonStdlibKinds() {
@@ -1217,6 +1226,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertImporterStatePresent() assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testCommonDetectionByGoalWithJsStdlib() { fun testCommonDetectionByGoalWithJsStdlib() {
@@ -1261,6 +1272,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertImporterStatePresent() assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.Common, facetSettings.targetPlatformKind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testCommonDetectionByGoalWithCommonStdlib() { fun testCommonDetectionByGoalWithCommonStdlib() {
@@ -1309,6 +1322,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
val rootManager = ModuleRootManager.getInstance(getModule("project")) val rootManager = ModuleRootManager.getInstance(getModule("project"))
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind) assertEquals(CommonLibraryKind, (stdlib as LibraryEx).kind)
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
} }
fun testJvmDetectionByConflictingGoalsAndJvmStdlib() { fun testJvmDetectionByConflictingGoalsAndJvmStdlib() {
@@ -34,6 +34,8 @@ import java.io.File;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static java.util.Collections.emptyList;
public class SdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescriptor { public class SdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescriptor {
public static final String LIBRARY_NAME = "myKotlinLib"; public static final String LIBRARY_NAME = "myKotlinLib";
@@ -50,7 +52,7 @@ public class SdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescri
public SdkAndMockLibraryProjectDescriptor( public SdkAndMockLibraryProjectDescriptor(
String sourcesPath, boolean withSources, boolean withRuntime, boolean isJsLibrary, boolean allowKotlinPackage) { String sourcesPath, boolean withSources, boolean withRuntime, boolean isJsLibrary, boolean allowKotlinPackage) {
this(sourcesPath, withSources, withRuntime, isJsLibrary, allowKotlinPackage, Collections.emptyList()); this(sourcesPath, withSources, withRuntime, isJsLibrary, allowKotlinPackage, emptyList());
} }
public SdkAndMockLibraryProjectDescriptor( public SdkAndMockLibraryProjectDescriptor(
@@ -66,7 +68,7 @@ public class SdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescri
@Override @Override
public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model) { public void configureModule(@NotNull Module module, @NotNull ModifiableRootModel model) {
List<String> extraOptions = allowKotlinPackage ? Collections.singletonList("-Xallow-kotlin-package") : Collections.emptyList(); List<String> extraOptions = allowKotlinPackage ? Collections.singletonList("-Xallow-kotlin-package") : emptyList();
File libraryJar = File libraryJar =
isJsLibrary isJsLibrary
? MockLibraryUtil.compileJsLibraryToJar(sourcesPath, LIBRARY_NAME, withSources) ? MockLibraryUtil.compileJsLibraryToJar(sourcesPath, LIBRARY_NAME, withSources)
@@ -94,7 +96,7 @@ public class SdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescri
@Override @Override
public Sdk getSdk() { public Sdk getSdk() {
return isJsLibrary ? new KotlinSdkType().newSdk(KotlinSdkType.DEFAULT_SDK_NAME) : PluginTestCaseBase.mockJdk(); return isJsLibrary ? KotlinSdkType.INSTANCE.createSdkWithUniqueName(emptyList()) : PluginTestCaseBase.mockJdk();
} }
@NotNull @NotNull
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumen
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.versions.* import org.jetbrains.kotlin.idea.versions.*
import kotlin.reflect.KProperty1 import kotlin.reflect.KProperty1
@@ -279,12 +280,16 @@ private val CommonCompilerArguments.ignoredFields: List<String>
else -> emptyList() else -> emptyList()
} }
private fun Module.configureJdkIfPossible(compilerArguments: K2JVMCompilerArguments, modelsProvider: IdeModifiableModelsProvider) { private fun Module.configureSdkIfPossible(compilerArguments: CommonCompilerArguments, modelsProvider: IdeModifiableModelsProvider) {
val jdkHome = compilerArguments.jdkHome ?: return val allSdks = ProjectJdkTable.getInstance().allJdks
val jdk = ProjectJdkTable.getInstance().allJdks.firstOrNull { val sdk = if (compilerArguments is K2JVMCompilerArguments) {
it.sdkType is JavaSdk && FileUtil.comparePaths(it.homePath, jdkHome) == 0 val jdkHome = compilerArguments.jdkHome ?: return
} ?: return allSdks.firstOrNull { it.sdkType is JavaSdk && FileUtil.comparePaths(it.homePath, jdkHome) == 0 } ?: return
modelsProvider.getModifiableRootModel(this).sdk = jdk } else {
allSdks.firstOrNull { it.sdkType is KotlinSdkType } ?: KotlinSdkType.INSTANCE.createSdkWithUniqueName(allSdks.toList())
}
modelsProvider.getModifiableRootModel(this).sdk = sdk
} }
fun parseCompilerArgumentsToFacet( fun parseCompilerArgumentsToFacet(
@@ -307,9 +312,7 @@ fun parseCompilerArgumentsToFacet(
// Retain only fields exposed (and not explicitly ignored) in facet configuration editor. // Retain only fields exposed (and not explicitly ignored) in facet configuration editor.
// The rest is combined into string and stored in CompilerSettings.additionalArguments // The rest is combined into string and stored in CompilerSettings.additionalArguments
if (compilerArguments is K2JVMCompilerArguments) { kotlinFacet.module.configureSdkIfPossible(compilerArguments, modelsProvider)
kotlinFacet.module.configureJdkIfPossible(compilerArguments, modelsProvider)
}
val primaryFields = compilerArguments.primaryFields val primaryFields = compilerArguments.primaryFields
val ignoredFields = compilerArguments.ignoredFields val ignoredFields = compilerArguments.ignoredFields
@@ -21,10 +21,10 @@ import javax.swing.JComponent
class KotlinSdkType : SdkType("KotlinSDK") { class KotlinSdkType : SdkType("KotlinSDK") {
companion object { companion object {
const val DEFAULT_SDK_NAME = "Kotlin SDK" @JvmField val INSTANCE = KotlinSdkType()
} }
override fun getPresentableName() = DEFAULT_SDK_NAME override fun getPresentableName() = "Kotlin SDK"
override fun getIcon() = KotlinIcons.SMALL_LOGO override fun getIcon() = KotlinIcons.SMALL_LOGO
@@ -41,12 +41,14 @@ class KotlinSdkType : SdkType("KotlinSDK") {
override fun supportsCustomCreateUI() = true override fun supportsCustomCreateUI() = true
override fun showCustomCreateUI(sdkModel: SdkModel, parentComponent: JComponent, selectedSdk: Sdk?, sdkCreatedCallback: Consumer<Sdk>) { override fun showCustomCreateUI(sdkModel: SdkModel, parentComponent: JComponent, selectedSdk: Sdk?, sdkCreatedCallback: Consumer<Sdk>) {
val newSdkName = SdkConfigurationUtil.createUniqueSdkName(this, "", sdkModel.sdks.toList()) sdkCreatedCallback.consume(createSdkWithUniqueName(sdkModel.sdks.toList()))
sdkCreatedCallback.consume(newSdk(newSdkName))
} }
fun newSdk(name: String) = ProjectJdkImpl(name, this).apply { fun createSdkWithUniqueName(existingSdks: Collection<Sdk>): ProjectJdkImpl {
homePath = "not applicable" val sdkName = suggestSdkName(SdkConfigurationUtil.createUniqueSdkName(this, "", existingSdks), "")
return ProjectJdkImpl(sdkName, this).apply {
homePath = "not applicable"
}
} }
override fun createAdditionalDataConfigurable(sdkModel: SdkModel, sdkModificator: SdkModificator) = null override fun createAdditionalDataConfigurable(sdkModel: SdkModel, sdkModificator: SdkModificator) = null