From 88420311cbcce045d0c7a7ec829f4bcbe518994e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 2 Aug 2017 17:10:01 +0200 Subject: [PATCH] Look at library content to detect library kind when importing --- .../kotlin/idea/framework/LibraryKinds.kt | 41 +++++++++++++ .../KotlinAndroidGradleLibraryDataService.kt | 5 +- .../kotlin/idea/maven/KotlinMavenImporter.kt | 3 +- .../idea/maven/KotlinMavenImporterTest.kt | 58 +++++++++++++++++++ .../KotlinGradleSourceSetDataService.kt | 4 +- .../gradle/GradleFacetImportTest.kt | 25 +++++++- 6 files changed, 130 insertions(+), 6 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt index e6ae32493d0..e678de75c97 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt @@ -36,9 +36,14 @@ import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.PersistentLibraryKind +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileVisitor import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform +import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment object JSLibraryKind : PersistentLibraryKind("kotlin.js") { override fun createDefaultProperties() = DummyLibraryProperties.INSTANCE!! @@ -58,3 +63,39 @@ fun getLibraryPlatform(library: Library): TargetPlatform { else -> JvmPlatform } } + +fun detectLibraryKind(roots: Array): PersistentLibraryKind<*>? { + val jarFile = roots.firstOrNull() ?: return null + if (jarFile.fileSystem is JarFileSystem) { + return detectLibraryKindFromJarContents(jarFile) + } + + return when (jarFile.extension) { + "js", "kjsm" -> JSLibraryKind + MetadataPackageFragment.METADATA_FILE_EXTENSION -> CommonLibraryKind + else -> null + } +} + +private fun detectLibraryKindFromJarContents(jarRoot: VirtualFile): PersistentLibraryKind<*>? { + var result: PersistentLibraryKind<*>? = null + VfsUtil.visitChildrenRecursively(jarRoot, object : VirtualFileVisitor>() { + override fun visitFile(file: VirtualFile): Boolean = + when (file.extension) { + "class" -> false + + "js", "kjsm" -> { + result = JSLibraryKind + false + } + + MetadataPackageFragment.METADATA_FILE_EXTENSION -> { + result = CommonLibraryKind + false + } + + else -> true + } + }) + return result +} diff --git a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleLibraryDataService.kt b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleLibraryDataService.kt index dc065637ac8..69443112a18 100644 --- a/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleLibraryDataService.kt +++ b/idea/idea-android/src/org/jetbrains/kotlin/android/configure/KotlinAndroidGradleLibraryDataService.kt @@ -24,8 +24,10 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import org.jetbrains.kotlin.idea.configuration.detectPlatformByPlugin +import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.framework.libraryKind class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService() { @@ -43,7 +45,8 @@ class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService if ((library as LibraryEx).kind == null) { val model = modifiableModelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx - model.kind = targetLibraryKind + detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it } } true } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt index 3baeb7cc179..48d89f6458a 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt @@ -1011,6 +1011,64 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) } + fun testJsAndCommonStdlibKinds() { + createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") + + importProject(""" + test + project + 1.0.0 + + + + org.jetbrains.kotlin + kotlin-stdlib-common + 1.1.0 + + + org.jetbrains.kotlin + kotlin-stdlib-js + 1.1.0 + + + + + src/main/kotlin + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + compile + + js + + + + test-compile + + test-js + + + + + + + """) + + assertModules("project") + assertImporterStatePresent() + + Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) + + val rootManager = ModuleRootManager.getInstance(getModule("project")) + val libraries = rootManager.orderEntries.filterIsInstance().mapNotNull { it.library as LibraryEx } + assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind) + assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind) + } + fun testCommonDetectionByGoalWithJvmStdlib() { createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt index 8c7b2d58236..b6cb6769dbd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt @@ -27,6 +27,7 @@ import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjec import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.util.PathUtil import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments @@ -36,6 +37,7 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.TargetPlatformKind import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.idea.facet.* +import org.jetbrains.kotlin.idea.framework.detectLibraryKind import org.jetbrains.kotlin.idea.framework.libraryKind import org.jetbrains.kotlin.idea.inspections.gradle.findAll import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion @@ -113,7 +115,7 @@ class KotlinGradleLibraryDataService : AbstractProjectDataService().mapNotNull { it.library as LibraryEx } + assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind) + assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind) } @Test @@ -676,6 +691,10 @@ compileTestKotlin { apply plugin: 'kotlin-platform-common' + repositories { + mavenCentral() + } + dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-common:1.1.0" }