Set library kind when importing projects from Gradle

This commit is contained in:
Dmitry Jemerov
2017-07-12 14:31:19 +02:00
parent 902fe1f5ce
commit 608f5892f9
6 changed files with 109 additions and 2 deletions
@@ -0,0 +1,53 @@
/*
* Copyright 2010-2017 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.android.configure
import com.android.tools.idea.gradle.AndroidProjectKeys
import com.android.tools.idea.gradle.JavaProject
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ModuleData
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.impl.libraries.LibraryEx
import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.idea.configuration.detectPlatformByPlugin
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaProject, Void>() {
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_PROJECT
override fun postProcess(
toImport: MutableCollection<DataNode<JavaProject>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (dataNode in toImport) {
val platform = detectPlatformByPlugin(dataNode.parent as DataNode<ModuleData>)
if (platform == TargetPlatformKind.JavaScript) {
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 = JSLibraryKind
}
}
}
}
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
<orderEntry type="library" scope="PROVIDED" name="copyright-plugin" level="project" />
<orderEntry type="module" module-name="j2k" />
<orderEntry type="module" module-name="cli" scope="TEST" />
<orderEntry type="module" module-name="idea-jps-common" />
<orderEntry type="module" module-name="idea-jps-common" exported="" />
<orderEntry type="library" scope="PROVIDED" name="properties" level="project" />
<orderEntry type="library" scope="PROVIDED" name="java-i18n" level="project" />
<orderEntry type="library" scope="PROVIDED" name="gradle-and-groovy-plugin" level="project" />
+1
View File
@@ -63,6 +63,7 @@
<referencesSearch implementation="org.jetbrains.kotlin.AndroidExtensionsReferenceSearchExecutor"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.android.configure.KotlinAndroidGradleLibraryDataService"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
+1
View File
@@ -14,6 +14,7 @@
<extensions defaultExtensionNs="com.intellij">
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleLibraryDataService"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection"
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.LibraryData
import com.intellij.openapi.externalSystem.model.project.LibraryDependencyData
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
@@ -25,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.impl.libraries.LibraryEx
import com.intellij.util.PathUtil
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.CoroutineSupport
@@ -33,6 +36,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.JSLibraryKind
import org.jetbrains.kotlin.idea.inspections.gradle.findAll
import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion
import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedKotlinStdlibVersionByModuleData
@@ -92,7 +96,44 @@ class KotlinGradleProjectDataService : AbstractProjectDataService<ModuleData, Vo
}
}
private fun detectPlatformByPlugin(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
class KotlinGradleLibraryDataService : AbstractProjectDataService<LibraryData, Void>() {
override fun getTargetDataKey() = ProjectKeys.LIBRARY
override fun postProcess(
toImport: MutableCollection<DataNode<LibraryData>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (libraryDataNode in toImport) {
val ideLibrary = modelsProvider.findIdeLibrary(libraryDataNode.data) ?: continue
val projectDataNode = libraryDataNode.parent!! as DataNode<ProjectData>
val ownerModule = findOwnerModule(libraryDataNode.data, projectDataNode) ?: continue
val targetPlatform = detectPlatformByPlugin(ownerModule)
if (targetPlatform == TargetPlatformKind.JavaScript) {
val modifiableModel = modelsProvider.getModifiableLibraryModel(ideLibrary) as LibraryEx.ModifiableModelEx
modifiableModel.kind = JSLibraryKind
}
}
}
}
private fun findOwnerModule(libraryData: LibraryData,
projectDataNode: DataNode<ProjectData>): DataNode<ModuleData>? {
return projectDataNode.children.firstOrNull { dataNode ->
if (dataNode.data !is ModuleData) return@firstOrNull false
val sourceSetDataNodes = dataNode.children.filter { it.data is GradleSourceSetData }
sourceSetDataNodes.any { it.hasDependency(libraryData) }
} as DataNode<ModuleData>?
}
private fun DataNode<*>.hasDependency(libraryData: LibraryData): Boolean =
children.any {
(it.data as? LibraryDependencyData)?.target == libraryData
}
fun detectPlatformByPlugin(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
return when (moduleNode.platformPluginId) {
"kotlin-platform-jvm" -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]
"kotlin-platform-js" -> TargetPlatformKind.JavaScript
@@ -20,12 +20,15 @@ import com.intellij.openapi.application.Result
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.junit.Assert
import org.junit.Test
import java.io.File
@@ -428,6 +431,10 @@ class GradleFacetImportTest : GradleImportingTestCase() {
Assert.assertEquals("-main callTest",
compilerSettings!!.additionalArguments)
}
val rootManager = ModuleRootManager.getInstance(getModule("project_main"))
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind)
}
@Test
@@ -885,6 +892,10 @@ class GradleFacetImportTest : GradleImportingTestCase() {
with (facetSettings("js-module")) {
Assert.assertEquals(TargetPlatformKind.JavaScript, targetPlatformKind)
}
val rootManager = ModuleRootManager.getInstance(getModule("js-module"))
val stdlib = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().single().library
assertEquals(JSLibraryKind, (stdlib as LibraryEx).kind)
}
@Test