Configure kotlin.stdlib for gradle projects (KT-19207)
#KT-19207 Fixed
This commit is contained in:
+19
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.configuration
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.projectRoots.Sdk
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.idea.versions.getDefaultJvmTarget
|
import org.jetbrains.kotlin.idea.versions.getDefaultJvmTarget
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
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 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 {
|
companion object {
|
||||||
val NAME = "gradle"
|
val NAME = "gradle"
|
||||||
val KOTLIN = "kotlin"
|
val KOTLIN = "kotlin"
|
||||||
|
|||||||
+19
-8
@@ -118,28 +118,39 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
|
|||||||
modulesToConfigure: List<Module>,
|
modulesToConfigure: List<Module>,
|
||||||
kotlinVersion: String,
|
kotlinVersion: String,
|
||||||
collector: NotificationMessageCollector): HashSet<PsiFile> {
|
collector: NotificationMessageCollector): HashSet<PsiFile> {
|
||||||
val changedFiles = HashSet<PsiFile>()
|
val filesToOpen = HashSet<PsiFile>()
|
||||||
val buildScript = project.getTopLevelBuildScriptPsiFile()
|
val buildScript = project.getTopLevelBuildScriptPsiFile()
|
||||||
if (buildScript != null && canConfigureFile(buildScript)) {
|
if (buildScript != null && canConfigureFile(buildScript)) {
|
||||||
val isModified = configureBuildScript(buildScript, true, kotlinVersion, collector)
|
val isModified = configureBuildScript(buildScript, true, kotlinVersion, collector)
|
||||||
if (isModified) {
|
if (isModified) {
|
||||||
changedFiles.add(buildScript)
|
filesToOpen.add(buildScript)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (module in modulesToConfigure) {
|
for (module in modulesToConfigure) {
|
||||||
val file = module.getBuildScriptPsiFile()
|
val file = module.getBuildScriptPsiFile()
|
||||||
if (file != null && canConfigureFile(file)) {
|
if (file != null && canConfigureFile(file)) {
|
||||||
val isModified = configureBuildScript(file, false, kotlinVersion, collector)
|
configureModule(module, file, false, kotlinVersion, collector, filesToOpen)
|
||||||
if (isModified) {
|
|
||||||
changedFiles.add(file)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
showErrorMessage(project, "Cannot find build.gradle file for module " + module.name)
|
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 {
|
protected fun configureModuleBuildScript(file: PsiFile, version: String): Boolean {
|
||||||
@@ -171,7 +182,7 @@ abstract class KotlinWithGradleConfigurator : KotlinProjectConfigurator {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun configureBuildScript(
|
private fun configureBuildScript(
|
||||||
file: PsiFile,
|
file: PsiFile,
|
||||||
isTopLevelProjectFile: Boolean,
|
isTopLevelProjectFile: Boolean,
|
||||||
version: String,
|
version: String,
|
||||||
|
|||||||
+41
-19
@@ -17,40 +17,62 @@
|
|||||||
package org.jetbrains.kotlin.idea.configuration
|
package org.jetbrains.kotlin.idea.configuration
|
||||||
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.projectRoots.Sdk
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
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 org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
|
abstract class AbstractGradleConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest<KotlinWithGradleConfigurator>() {
|
||||||
|
|
||||||
fun doTestGradle(path: String) {
|
fun doTestGradle(path: String) {
|
||||||
val testPathFile = File(testDataPath + path)
|
val (before, after) = beforeAfterFiles()
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doTest(before, after, if ("js" in path) KotlinJsGradleModuleConfigurator() else KotlinGradleModuleConfigurator())
|
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) {
|
override fun runConfigurator(module: Module, file: PsiFile, configurator: KotlinWithGradleConfigurator, version: String, collector: NotificationMessageCollector) {
|
||||||
if (file !is GroovyFile && file !is KtFile) {
|
if (file !is GroovyFile && file !is KtFile) {
|
||||||
fail("file $file is not a GroovyFile or KtFile")
|
fail("file $file is not a GroovyFile or KtFile")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configurator.configureBuildScript(file, true, version, collector)
|
configurator.configureModule(module, file, true, version, collector, ArrayList())
|
||||||
configurator.configureBuildScript(file, false, version, collector)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -79,6 +79,12 @@ public class GradleConfigureProjectByChangingFileTestGenerated extends AbstractG
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/configuration/gradle/rcVersion/");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/configuration/gradle/rcVersion/");
|
||||||
doTestGradle(fileName);
|
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")
|
@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 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.toModuleGroup() = ModuleSourceRootMap(project).toModuleGroup(this)
|
||||||
|
fun Module.getWholeModuleGroup() = ModuleSourceRootMap(project).getWholeModuleGroup(this)
|
||||||
|
|
||||||
private fun isSourceRootPrefix(externalId: String, previousModuleExternalId: String)
|
private fun isSourceRootPrefix(externalId: String, previousModuleExternalId: String)
|
||||||
= externalId.length < previousModuleExternalId.length && previousModuleExternalId.startsWith(externalId)
|
= externalId.length < previousModuleExternalId.length && previousModuleExternalId.startsWith(externalId)
|
||||||
@@ -69,6 +79,13 @@ val Module.externalProjectId: String?
|
|||||||
val Module.externalProjectPath: String?
|
val Module.externalProjectPath: String?
|
||||||
get() = ExternalSystemApiUtil.getExternalProjectPath(this)
|
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> {
|
fun List<ModuleSourceRootGroup>.exclude(excludeModules: Collection<Module>): List<ModuleSourceRootGroup> {
|
||||||
return mapNotNull {
|
return mapNotNull {
|
||||||
if (it.baseModule in excludeModules)
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user