diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt index 6d352f27f35..8c86006bd29 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt @@ -24,7 +24,6 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ModifiableModelsProvider import com.intellij.openapi.roots.ModifiableRootModel -import com.intellij.psi.PsiFile import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.versions.* import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder @@ -78,7 +77,7 @@ abstract class GradleKotlinFrameworkSupportProvider( if (additionalRepository != null) { val oneLineRepository = additionalRepository.toGroovyRepositorySnippet().replace('\n', ' ') updateSettingsScript(module) { - with(KotlinWithGradleConfigurator.getManipulator(it)) { + with(it) { addPluginRepository(additionalRepository) addMavenCentralPluginRepository() } @@ -126,7 +125,7 @@ abstract class GradleKotlinFrameworkSupportProvider( } } - protected open fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { } + protected open fun updateSettingsScript(settingsBuilder: SettingsScriptBuilder, specifyPluginVersionIfNeeded: Boolean) { } protected abstract fun getDependencies(sdk: Sdk?): List protected open fun getTestDependencies(): List = listOf() @@ -172,9 +171,9 @@ open class GradleKotlinJSFrameworkSupportProvider( override fun getTestDependencies() = listOf(MAVEN_JS_TEST_ID) - override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + override fun updateSettingsScript(settingsBuilder: SettingsScriptBuilder, specifyPluginVersionIfNeeded: Boolean) { if (specifyPluginVersionIfNeeded) { - KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin2js") + settingsBuilder.addResolutionStrategy("kotlin2js") } } @@ -189,9 +188,9 @@ open class GradleKotlinMPPCommonFrameworkSupportProvider : override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_COMMON_STDLIB_ID) override fun getTestDependencies() = listOf(MAVEN_COMMON_TEST_ID, MAVEN_COMMON_TEST_ANNOTATIONS_ID) - override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + override fun updateSettingsScript(settingsBuilder: SettingsScriptBuilder, specifyPluginVersionIfNeeded: Boolean) { if (specifyPluginVersionIfNeeded) { - KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-common") + settingsBuilder.addResolutionStrategy("kotlin-platform-common") } } @@ -216,9 +215,9 @@ class GradleKotlinMPPJavaFrameworkSupportProvider } } - override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + override fun updateSettingsScript(settingsBuilder: SettingsScriptBuilder, specifyPluginVersionIfNeeded: Boolean) { if (specifyPluginVersionIfNeeded) { - KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-jvm") + settingsBuilder.addResolutionStrategy("kotlin-platform-jvm") } } } @@ -229,9 +228,9 @@ class GradleKotlinMPPJSFrameworkSupportProvider override fun getPluginId() = "kotlin-platform-js" override fun getPluginExpression() = "id 'kotlin-platform-js'" - override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + override fun updateSettingsScript(settingsBuilder: SettingsScriptBuilder, specifyPluginVersionIfNeeded: Boolean) { if (specifyPluginVersionIfNeeded) { - KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-js") + settingsBuilder.addResolutionStrategy("kotlin-platform-js") } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt.172 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt.172 new file mode 100644 index 00000000000..6d352f27f35 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleKotlinFrameworkSupportProvider.kt.172 @@ -0,0 +1,239 @@ +/* + * 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.idea.configuration + +import com.intellij.framework.FrameworkTypeEx +import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable +import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider +import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel +import com.intellij.openapi.module.Module +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.ModifiableModelsProvider +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.idea.KotlinIcons +import org.jetbrains.kotlin.idea.versions.* +import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder +import org.jetbrains.plugins.gradle.frameworkSupport.GradleFrameworkSupportProvider +import javax.swing.Icon +import javax.swing.JComponent +import javax.swing.JLabel + +abstract class GradleKotlinFrameworkSupportProvider( + val frameworkTypeId: String, + val displayName: String, + val frameworkIcon: Icon +) : GradleFrameworkSupportProvider() { + override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) { + override fun getIcon(): Icon = frameworkIcon + + override fun getPresentableName(): String = displayName + + override fun createProvider(): FrameworkSupportInModuleProvider = this@GradleKotlinFrameworkSupportProvider + } + + override fun createConfigurable(model: FrameworkSupportModel): FrameworkSupportInModuleConfigurable { + val configurable = KotlinGradleFrameworkSupportInModuleConfigurable(model, this) + return object : FrameworkSupportInModuleConfigurable() { + override fun addSupport(module: Module, rootModel: ModifiableRootModel, modifiableModelsProvider: ModifiableModelsProvider) { + configurable.addSupport(module, rootModel, modifiableModelsProvider) + } + + override fun createComponent(): JComponent = JLabel(getDescription()) + } + } + + override fun addSupport( + module: Module, + rootModel: ModifiableRootModel, + modifiableModelsProvider: ModifiableModelsProvider, + buildScriptData: BuildScriptDataBuilder + ) { + addSupport(buildScriptData, module, rootModel.sdk, true) + } + + open fun addSupport(buildScriptData: BuildScriptDataBuilder, module: Module, sdk: Sdk?, specifyPluginVersionIfNeeded: Boolean) { + var kotlinVersion = bundledRuntimeVersion() + val additionalRepository = getRepositoryForVersion(kotlinVersion) + if (isSnapshot(bundledRuntimeVersion())) { + kotlinVersion = LAST_SNAPSHOT_VERSION + } + + val useNewSyntax = buildScriptData.gradleVersion >= MIN_GRADLE_VERSION_FOR_NEW_PLUGIN_SYNTAX + if (useNewSyntax) { + if (additionalRepository != null) { + val oneLineRepository = additionalRepository.toGroovyRepositorySnippet().replace('\n', ' ') + updateSettingsScript(module) { + with(KotlinWithGradleConfigurator.getManipulator(it)) { + addPluginRepository(additionalRepository) + addMavenCentralPluginRepository() + } + } + buildScriptData.addRepositoriesDefinition("mavenCentral()") + buildScriptData.addRepositoriesDefinition(oneLineRepository) + } + + buildScriptData.addPluginDefinitionInPluginsGroup( + getPluginExpression() + if (specifyPluginVersionIfNeeded) " version '$kotlinVersion'" else "" + ) + } else { + if (additionalRepository != null) { + val oneLineRepository = additionalRepository.toGroovyRepositorySnippet().replace('\n', ' ') + buildScriptData.addBuildscriptRepositoriesDefinition(oneLineRepository) + + buildScriptData.addRepositoriesDefinition("mavenCentral()") + buildScriptData.addRepositoriesDefinition(oneLineRepository) + } + + buildScriptData + .addPluginDefinition(KotlinWithGradleConfigurator.getGroovyApplyPluginDirective(getPluginId())) + .addBuildscriptRepositoriesDefinition("mavenCentral()") + .addBuildscriptPropertyDefinition("ext.kotlin_version = '$kotlinVersion'") + } + + buildScriptData.addRepositoriesDefinition("mavenCentral()") + + for (dependency in getDependencies(sdk)) { + buildScriptData.addDependencyNotation(KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "compile", !useNewSyntax)) + } + for (dependency in getTestDependencies()) { + buildScriptData.addDependencyNotation( + if (":" in dependency) + "testCompile \"$dependency\"" + else + KotlinWithGradleConfigurator.getGroovyDependencySnippet(dependency, "testCompile", !useNewSyntax) + ) + } + + if (useNewSyntax) { + updateSettingsScript(module) { updateSettingsScript(it, specifyPluginVersionIfNeeded) } + } else { + buildScriptData.addBuildscriptDependencyNotation(KotlinWithGradleConfigurator.CLASSPATH) + } + } + + protected open fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { } + + protected abstract fun getDependencies(sdk: Sdk?): List + protected open fun getTestDependencies(): List = listOf() + + protected abstract fun getPluginId(): String + protected abstract fun getPluginExpression(): String + + protected abstract fun getDescription(): String +} + +open class GradleKotlinJavaFrameworkSupportProvider( + frameworkTypeId: String = "KOTLIN", + displayName: String = "Kotlin (Java)" +) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.SMALL_LOGO) { + + override fun getPluginId() = KotlinGradleModuleConfigurator.KOTLIN + override fun getPluginExpression() = "id 'org.jetbrains.kotlin.jvm'" + + override fun getDependencies(sdk: Sdk?) = listOf(getStdlibArtifactId(sdk, bundledRuntimeVersion())) + + override fun addSupport(buildScriptData: BuildScriptDataBuilder, module: Module, sdk: Sdk?, specifyPluginVersionIfNeeded: Boolean) { + super.addSupport(buildScriptData, module, sdk, specifyPluginVersionIfNeeded) + val jvmTarget = getDefaultJvmTarget(sdk, bundledRuntimeVersion()) + if (jvmTarget != null) { + val description = jvmTarget.description + buildScriptData.addOther("compileKotlin {\n kotlinOptions.jvmTarget = \"$description\"\n}\n\n") + buildScriptData.addOther("compileTestKotlin {\n kotlinOptions.jvmTarget = \"$description\"\n}\n") + } + } + + override fun getDescription() = "A Kotlin library or application targeting the JVM" +} + +open class GradleKotlinJSFrameworkSupportProvider( + frameworkTypeId: String = "KOTLIN_JS", + displayName: String = "Kotlin (JavaScript)" +) : GradleKotlinFrameworkSupportProvider(frameworkTypeId, displayName, KotlinIcons.JS) { + + override fun getPluginId() = KotlinJsGradleModuleConfigurator.KOTLIN_JS + override fun getPluginExpression() = "id 'kotlin2js'" + + override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_JS_STDLIB_ID) + + override fun getTestDependencies() = listOf(MAVEN_JS_TEST_ID) + + override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + if (specifyPluginVersionIfNeeded) { + KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin2js") + } + } + + override fun getDescription() = "A Kotlin library or application targeting JavaScript" +} + +open class GradleKotlinMPPCommonFrameworkSupportProvider : + GradleKotlinFrameworkSupportProvider("KOTLIN_MPP_COMMON", "Kotlin (Multiplatform Common - Experimental)", KotlinIcons.MPP) { + override fun getPluginId() = "kotlin-platform-common" + override fun getPluginExpression() = "id 'kotlin-platform-common'" + + override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_COMMON_STDLIB_ID) + override fun getTestDependencies() = listOf(MAVEN_COMMON_TEST_ID, MAVEN_COMMON_TEST_ANNOTATIONS_ID) + + override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + if (specifyPluginVersionIfNeeded) { + KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-common") + } + } + + override fun getDescription() = "Shared code for a Kotlin multiplatform project (targeting JVM and JS)" +} + +class GradleKotlinMPPJavaFrameworkSupportProvider + : GradleKotlinJavaFrameworkSupportProvider("KOTLIN_MPP_JVM", "Kotlin (Multiplatform JVM - Experimental)") { + + override fun getPluginId() = "kotlin-platform-jvm" + override fun getPluginExpression() = "id 'kotlin-platform-jvm'" + + override fun getDescription() = "JVM-specific code for a Kotlin multiplatform project" + override fun getTestDependencies() = listOf(MAVEN_TEST_ID, MAVEN_TEST_JUNIT_ID, "junit:junit:4.12") + + override fun addSupport(buildScriptData: BuildScriptDataBuilder, module: Module, sdk: Sdk?, specifyPluginVersionIfNeeded: Boolean) { + super.addSupport(buildScriptData, module, sdk, specifyPluginVersionIfNeeded) + val jvmTarget = getDefaultJvmTarget(sdk, bundledRuntimeVersion()) + if (jvmTarget != null) { + val description = jvmTarget.description + buildScriptData.addOther("sourceCompatibility = \"$description\"\n\n") + } + } + + override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + if (specifyPluginVersionIfNeeded) { + KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-jvm") + } + } +} + +class GradleKotlinMPPJSFrameworkSupportProvider + : GradleKotlinJSFrameworkSupportProvider("KOTLIN_MPP_JS", "Kotlin (Multiplatform JS - Experimental)") { + + override fun getPluginId() = "kotlin-platform-js" + override fun getPluginExpression() = "id 'kotlin-platform-js'" + + override fun updateSettingsScript(settingsScript: PsiFile, specifyPluginVersionIfNeeded: Boolean) { + if (specifyPluginVersionIfNeeded) { + KotlinWithGradleConfigurator.getManipulator(settingsScript).addResolutionStrategy("kotlin-platform-js") + } + } + + override fun getDescription() = "JavaScript-specific code for a Kotlin multiplatform project" +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt index 07eb89e483e..ef0c80532e1 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinDslGradleKotlinFrameworkSupportProvider.kt @@ -63,7 +63,7 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider( if (additionalRepository != null) { val repository = additionalRepository.toKotlinRepositorySnippet() updateSettingsScript(module) { - with(KotlinWithGradleConfigurator.getManipulator(it)) { + with(it) { addPluginRepository(additionalRepository) addMavenCentralPluginRepository() } @@ -148,7 +148,7 @@ class KotlinDslGradleKotlinJSFrameworkSupportProvider : ) { super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData) updateSettingsScript(module) { - KotlinWithGradleConfigurator.getManipulator(it).addResolutionStrategy("kotlin2js") + it.addResolutionStrategy("kotlin2js") } } } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleMultiplatformModuleBuilder.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleMultiplatformModuleBuilder.kt index 2ef1daf1f58..34e749d799a 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleMultiplatformModuleBuilder.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleMultiplatformModuleBuilder.kt @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.idea.util.rootManager import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder import org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory import javax.swing.Icon class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() { @@ -82,9 +81,7 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() { updateSettingsScript(module) { val includedModules = listOfNotNull(commonModuleName, jvmModuleName, jsModuleName).filter { it.isNotEmpty() } if (includedModules.isNotEmpty()) { - val includeCall = GroovyPsiElementFactory.getInstance(module.project) - .createExpressionFromText(includedModules.joinToString(prefix = "include ") { "'$it'" }) - it.add(includeCall) + it.addIncludedModules(includedModules) } } } finally { diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/gradleModuleBuilderUtils.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/gradleModuleBuilderUtils.kt index 44d1b7dee57..73a70b99d02 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/gradleModuleBuilderUtils.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/gradleModuleBuilderUtils.kt @@ -9,25 +9,24 @@ import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel import com.intellij.openapi.externalSystem.model.project.ProjectId import com.intellij.openapi.module.Module -import com.intellij.openapi.project.DumbService import com.intellij.openapi.roots.ModifiableModelsProvider import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiFile import com.intellij.psi.codeStyle.CodeStyleManager -import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.refactoring.toPsiFile import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.plugins.gradle.frameworkSupport.GradleFrameworkSupportProvider import org.jetbrains.plugins.gradle.service.project.wizard.GradleModuleBuilder import org.jetbrains.plugins.gradle.util.GradleConstants +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory import java.io.File internal var Module.gradleModuleBuilder: GradleModuleBuilder? by UserDataProperty(Key.create("GRADLE_MODULE_BUILDER")) -private var Module.editableSettingsPsiFileCopy: PsiFile? by UserDataProperty(Key.create("EDITABLE_SETTINGS_PSI_FILE_COPY")) +private var Module.settingsScriptBuilder: SettingsScriptBuilder? by UserDataProperty(Key.create("SETTINGS_SCRIPT_BUILDER")) internal fun findSettingsGradleFile(module: Module): VirtualFile? { val contentEntryPath = module.gradleModuleBuilder?.contentEntryPath ?: return null @@ -38,28 +37,112 @@ internal fun findSettingsGradleFile(module: Module): VirtualFile? { ?: module.project.baseDir.findChild(GradleConstants.SETTINGS_FILE_NAME) } +class SettingsScriptBuilder(scriptFile: GroovyFile) { + private val builder = StringBuilder(scriptFile.text) + + private fun findBlockBody(blockName: String, startFrom: Int = 0): Int { + val blockOffset = builder.indexOf(blockName, startFrom) + if (blockOffset < 0) return -1 + return builder.indexOf('{', blockOffset + 1) + 1 + } + + private fun getOrPrependTopLevelBlockBody(blockName: String): Int { + val blockBody = findBlockBody(blockName) + if (blockBody >= 0) return blockBody + builder.insert(0, "$blockName {}\n") + return findBlockBody(blockName) + } + + private fun getOrAppendInnerBlockBody(blockName: String, offset: Int): Int { + val repositoriesBody = findBlockBody(blockName, offset) + if (repositoriesBody >= 0) return repositoriesBody + builder.insert(offset, "\n$blockName {}\n") + return findBlockBody(blockName, offset) + } + + private fun appendExpressionToBlockIfAbsent(expression: String, offset: Int) { + var braceCount = 1 + var blockEnd = offset + for (i in offset..builder.lastIndex) { + when (builder[i]) { + '{' -> braceCount++ + '}' -> braceCount-- + } + if (braceCount == 0) { + blockEnd = i + break + } + } + if (!builder.substring(offset, blockEnd).contains(expression.trim())) { + builder.insert(blockEnd, "\n$expression\n") + } + } + + private fun getOrCreatePluginManagementBody() = getOrPrependTopLevelBlockBody("pluginManagement") + + private fun addPluginRepositoryExpression(expression: String) { + val repositoriesBody = getOrAppendInnerBlockBody("repositories", getOrCreatePluginManagementBody()) + appendExpressionToBlockIfAbsent(expression, repositoriesBody) + } + + fun addMavenCentralPluginRepository() { + addPluginRepositoryExpression("mavenCentral()") + } + + fun addPluginRepository(repository: RepositoryDescription) { + addPluginRepositoryExpression(repository.toGroovyRepositorySnippet()) + } + + fun addResolutionStrategy(pluginId: String) { + val resolutionStrategyBody = getOrAppendInnerBlockBody("resolutionStrategy", getOrCreatePluginManagementBody()) + val eachPluginBody = getOrAppendInnerBlockBody("eachPlugin", resolutionStrategyBody) + appendExpressionToBlockIfAbsent( + """ + if (requested.id.id == "$pluginId") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}{requested.version}") + } + """.trimIndent(), + eachPluginBody + ) + } + + fun addIncludedModules(modules: List) { + builder.append(modules.joinToString(prefix = "include ", postfix = "\n") { "'$it'" }) + } + + fun build() = builder.toString() +} + // Circumvent write actions and modify the file directly // TODO: Get rid of this hack when IDEA API allows manipulation of settings script similarly to the main script itself -internal fun updateSettingsScript(module: Module, updater: (PsiFile) -> Unit) { - val storedCopy = module.editableSettingsPsiFileCopy - val settingsPsiCopy = storedCopy ?: findSettingsGradleFile(module)?.toPsiFile(module.project)?.copied() ?: return - if (storedCopy == null) { - module.editableSettingsPsiFileCopy = settingsPsiCopy +internal fun updateSettingsScript(module: Module, updater: (SettingsScriptBuilder) -> Unit) { + val storedSettingsBuilder = module.settingsScriptBuilder + val settingsBuilder = + storedSettingsBuilder + ?: (findSettingsGradleFile(module)?.toPsiFile(module.project) as? GroovyFile)?.let { SettingsScriptBuilder(it) } + ?: return + if (storedSettingsBuilder == null) { + module.settingsScriptBuilder = settingsBuilder } - DumbService.getInstance(module.project).runWithAlternativeResolveEnabled { updater(settingsPsiCopy) } + updater(settingsBuilder) } internal fun flushSettingsGradleCopy(module: Module) { try { val settingsFile = findSettingsGradleFile(module) - val settingsPsiCopy = module.editableSettingsPsiFileCopy - if (settingsPsiCopy != null && settingsFile != null) { - CodeStyleManager.getInstance(module.project).reformat(settingsPsiCopy) - VfsUtil.saveText(settingsFile, settingsPsiCopy.text) + val settingsScriptBuilder = module.settingsScriptBuilder + if (settingsScriptBuilder != null && settingsFile != null) { + val project = module.project + val tmpFile = + GroovyPsiElementFactory + .getInstance(project) + .createGroovyFile(settingsScriptBuilder.build(), false, null) + CodeStyleManager.getInstance(project).reformat(tmpFile) + VfsUtil.saveText(settingsFile, tmpFile.text) } } finally { module.gradleModuleBuilder = null - module.editableSettingsPsiFileCopy = null + module.settingsScriptBuilder = null } }