Look at library content to detect library kind when importing

This commit is contained in:
Dmitry Jemerov
2017-08-02 17:10:01 +02:00
parent b423d58a14
commit 88420311cb
6 changed files with 130 additions and 6 deletions
@@ -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<DummyLibraryProperties>("kotlin.js") {
override fun createDefaultProperties() = DummyLibraryProperties.INSTANCE!!
@@ -58,3 +63,39 @@ fun getLibraryPlatform(library: Library): TargetPlatform {
else -> JvmPlatform
}
}
fun detectLibraryKind(roots: Array<VirtualFile>): 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<PersistentLibraryKind<*>>() {
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
}
@@ -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<JavaProject, Void>() {
@@ -43,7 +45,8 @@ class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaPro
for (dep in dataNode.data.jarLibraryDependencies) {
val library = modelsProvider.getLibraryByName(dep.name) as LibraryEx? ?: continue
if (library.kind == null) {
(modelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx).kind = targetLibraryKind
val model = modelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx
detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it }
}
}
}
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.config.LanguageVersion
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.maven.configuration.KotlinMavenConfigurator
import java.io.File
@@ -95,7 +96,7 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
modifiableModelsProvider.getModifiableRootModel(module).orderEntries().forEachLibrary { library ->
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
}
@@ -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("""
<groupId>test</groupId>
<artifactId>project</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-common</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-js</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>js</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-js</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
""")
assertModules("project")
assertImporterStatePresent()
Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind)
val rootManager = ModuleRootManager.getInstance(getModule("project"))
val libraries = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().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")
@@ -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<LibraryData, V
val targetLibraryKind = detectPlatformByPlugin(ownerModule)?.libraryKind
if (targetLibraryKind != null) {
val modifiableModel = modelsProvider.getModifiableLibraryModel(ideLibrary) as LibraryEx.ModifiableModelEx
modifiableModel.kind = targetLibraryKind
detectLibraryKind(modifiableModel.getFiles(OrderRootType.CLASSES))?.let { modifiableModel.kind = it }
}
}
}
@@ -439,6 +439,10 @@ compileTestKotlin {
apply plugin: 'kotlin2js'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:1.1.0"
}
@@ -634,9 +638,6 @@ compileTestKotlin {
buildscript {
repositories {
mavenCentral()
maven {
url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1'
}
}
dependencies {
@@ -645,6 +646,15 @@ compileTestKotlin {
}
apply plugin: 'kotlin-platform-js'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-common:1.1.0"
compile "org.jetbrains.kotlin:kotlin-stdlib-js:1.1.0"
}
""")
importProject()
@@ -653,6 +663,11 @@ compileTestKotlin {
Assert.assertEquals("1.1", apiLevel!!.versionString)
Assert.assertEquals(TargetPlatformKind.JavaScript, targetPlatformKind)
}
val rootManager = ModuleRootManager.getInstance(getModule("project_main"))
val libraries = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().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"
}