Configure kotlin.stdlib for gradle projects (KT-19207)

#KT-19207 Fixed
This commit is contained in:
Nikolay Krasko
2017-10-03 16:08:37 +03:00
parent 023067aaf2
commit 6664b7759b
9 changed files with 154 additions and 27 deletions
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.versions.getDefaultJvmTarget
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
@@ -37,6 +39,23 @@ class KotlinGradleModuleConfigurator : KotlinWithGradleConfigurator() {
override fun getJvmTarget(sdk: Sdk?, version: String) = getDefaultJvmTarget(sdk, version)?.description
override fun configureModule(
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String, collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
) {
super.configureModule(module, file, isTopLevelProjectFile, version, collector, filesToOpen)
val moduleGroup = module.getWholeModuleGroup()
for (sourceModule in moduleGroup.allModules()) {
if (addStdlibToJavaModuleInfo(sourceModule, collector)) {
break
}
}
}
companion object {
val NAME = "gradle"
val KOTLIN = "kotlin"
@@ -118,28 +118,39 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
modulesToConfigure: List<Module>,
kotlinVersion: String,
collector: NotificationMessageCollector): HashSet<PsiFile> {
val changedFiles = HashSet<PsiFile>()
val filesToOpen = HashSet<PsiFile>()
val buildScript = project.getTopLevelBuildScriptPsiFile()
if (buildScript != null && canConfigureFile(buildScript)) {
val isModified = configureBuildScript(buildScript, true, kotlinVersion, collector)
if (isModified) {
changedFiles.add(buildScript)
filesToOpen.add(buildScript)
}
}
for (module in modulesToConfigure) {
val file = module.getBuildScriptPsiFile()
if (file != null && canConfigureFile(file)) {
val isModified = configureBuildScript(file, false, kotlinVersion, collector)
if (isModified) {
changedFiles.add(file)
}
configureModule(module, file, false, kotlinVersion, collector, filesToOpen)
}
else {
showErrorMessage(project, "Cannot find build.gradle file for module " + module.name)
}
}
return changedFiles
return filesToOpen
}
open fun configureModule(
module: Module,
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
collector: NotificationMessageCollector,
filesToOpen: MutableCollection<PsiFile>
) {
val isModified = configureBuildScript(file, isTopLevelProjectFile, version, collector)
if (isModified) {
filesToOpen.add(file)
}
}
protected fun configureModuleBuildScript(file: PsiFile, version: String): Boolean {
@@ -171,7 +182,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
return false
}
fun configureBuildScript(
private fun configureBuildScript(
file: PsiFile,
isTopLevelProjectFile: Boolean,
version: String,
@@ -17,40 +17,62 @@
package org.jetbrains.kotlin.idea.configuration
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.KotlinTestUtils.isAllFilesPresentTest
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import java.io.File
abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
fun doTestGradle(path: String) {
val testPathFile = File(testDataPath + path)
val (before, after) = if (testPathFile.isFile) {
path to path.replace("before", "after")
}
else {
when {
File(testPathFile, "build_before.gradle").exists() ->
"$path/build_before.gradle" to "$path/build_after.gradle"
File(testPathFile, "build_before.gradle.kts").exists() ->
"$path/build_before.gradle.kts" to "$path/build_after.gradle.kts"
else -> error("Can't find test data files")
}
}
val (before, after) = beforeAfterFiles()
doTest(before, after, if ("js" in path) KotlinJsGradleModuleConfigurator() else KotlinGradleModuleConfigurator())
}
private fun beforeAfterFiles(): Pair<String, String> {
val root = KotlinTestUtils.getTestsRoot(this::class.java)
val test = KotlinTestUtils.getTestDataFileName(this::class.java, name)
val path = "$root/$test"
val testFile = File(path)
if (testFile.isFile) {
return path to path.replace("before", "after")
}
return when {
File(path, "build_before.gradle").exists() ->
"$path/build_before.gradle" to "$path/build_after.gradle"
File(path, "build_before.gradle.kts").exists() ->
"$path/build_before.gradle.kts" to "$path/build_after.gradle.kts"
else -> error("Can't find test data files")
}
}
override fun runConfigurator(module: Module, file: PsiFile, configurator: KotlinWithGradleConfigurator, version: String, collector: NotificationMessageCollector) {
if (file !is GroovyFile && file !is KtFile) {
fail("file $file is not a GroovyFile or KtFile")
return
}
configurator.configureBuildScript(file, true, version, collector)
configurator.configureBuildScript(file, false, version, collector)
configurator.configureModule(module, file, true, version, collector, ArrayList())
configurator.configureModule(module, file, false, version, collector, ArrayList())
}
override fun getProjectJDK(): Sdk {
if (!isAllFilesPresentTest(getTestName(false))) {
val beforeAfterFiles = beforeAfterFiles()
val (before, _) = beforeAfterFiles
val gradleFile = File(before)
if (gradleFile.readText().contains("1.9")) {
return PluginTestCaseBase.mockJdk9()
}
}
return super.getProjectJDK()
}
}
@@ -79,6 +79,12 @@ public class GradleConfigureProjectByChangingFileTestGenerated extends AbstractG
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/configuration/gradle/rcVersion/");
doTestGradle(fileName);
}
@TestMetadata("withJava9ModuleInfo")
public void testWithJava9ModuleInfo() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/configuration/gradle/withJava9ModuleInfo/");
doTestGradle(fileName);
}
}
@TestMetadata("idea/testData/configuration/gsk")
@@ -56,9 +56,19 @@ class ModuleSourceRootMap(val modules: Collection<Module>) {
}
fun toModuleGroup(module: Module): ModuleSourceRootGroup = groupByBaseModules(listOf(module)).single()
fun getWholeModuleGroup(module: Module): ModuleSourceRootGroup {
val externalPath = module.externalProjectPath
val baseModule = (if (externalPath != null) baseModuleByExternalPath[externalPath] else null) ?:
return ModuleSourceRootGroup(module, listOf(module))
val externalPathModules = allModulesByExternalPath[externalPath] ?: listOf()
return ModuleSourceRootGroup(baseModule, if (externalPathModules.size > 1) externalPathModules - module else externalPathModules)
}
}
fun Module.toModuleGroup() = ModuleSourceRootMap(project).toModuleGroup(this)
fun Module.getWholeModuleGroup() = ModuleSourceRootMap(project).getWholeModuleGroup(this)
private fun isSourceRootPrefix(externalId: String, previousModuleExternalId: String)
= externalId.length < previousModuleExternalId.length && previousModuleExternalId.startsWith(externalId)
@@ -69,6 +79,13 @@ val Module.externalProjectId: String?
val Module.externalProjectPath: String?
get() = ExternalSystemApiUtil.getExternalProjectPath(this)
fun ModuleSourceRootGroup.allModules(): Set<Module> {
val result = LinkedHashSet<Module>()
result.add(baseModule)
result.addAll(sourceRootModules)
return result
}
fun List<ModuleSourceRootGroup>.exclude(excludeModules: Collection<Module>): List<ModuleSourceRootGroup> {
return mapNotNull {
if (it.baseModule in excludeModules)
@@ -0,0 +1,33 @@
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.9
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
}
buildscript {
ext.kotlin_version = '$VERSION$'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
@@ -0,0 +1,12 @@
apply plugin: 'java'
sourceCompatibility = 1.9
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
}
@@ -0,0 +1,3 @@
module TestModule {
}
@@ -0,0 +1,4 @@
module TestModule {
requires kotlin.stdlib;
}