Gradle configurator: handle kotlin options correctly with new-mpp plugin

#KT-27052 Fixed
This commit is contained in:
Mikhail Glukhikh
2018-10-23 16:06:10 +03:00
parent d050629589
commit b9161c5293
10 changed files with 398 additions and 7 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator.Comp
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
@@ -246,6 +247,34 @@ class GroovyBuildScriptManipulator(
)
}
private fun usesNewMultiplatform(): Boolean {
val fileText = runReadAction { scriptFile.text }
return fileText.contains("kotlin-multiplatform")
}
private fun GrClosableBlock.addParameterAssignment(
parameterName: String,
defaultValue: String,
replaceIt: GrStatement.(Boolean) -> GrStatement
) {
statements.firstOrNull { stmt ->
(stmt as? GrAssignmentExpression)?.lValue?.text == parameterName
}?.let { stmt ->
stmt.replaceIt(false)
} ?: addLastExpressionInBlockIfNeeded("$parameterName = $defaultValue")
}
private fun String.extractTextFromQuotes(quoteCharacter: Char): String? {
val quoteIndex = indexOf(quoteCharacter)
if (quoteIndex != -1) {
val lastQuoteIndex = lastIndexOf(quoteCharacter)
return if (lastQuoteIndex > quoteIndex) substring(quoteIndex + 1, lastQuoteIndex) else null
}
return null
}
private fun String.extractTextFromQuotes(): String = extractTextFromQuotes('\'') ?: extractTextFromQuotes('"') ?: this
private fun addOrReplaceKotlinTaskParameter(
gradleFile: GroovyFile,
parameterName: String,
@@ -253,6 +282,39 @@ class GroovyBuildScriptManipulator(
forTests: Boolean,
replaceIt: GrStatement.(Boolean) -> GrStatement
): PsiElement? {
if (usesNewMultiplatform()) {
val kotlinBlock = gradleFile.getBlockOrCreate("kotlin")
val kotlinTargets = kotlinBlock.getBlockOrCreate("targets")
val targetNames = mutableListOf<String>()
fun GrStatement.handleTarget(targetExpectedText: String) {
if (this is GrMethodCallExpression && invokedExpression.text == targetExpectedText) {
val targetNameArgument = argumentList.expressionArguments.getOrNull(1)?.text
if (targetNameArgument != null) {
targetNames += targetNameArgument.extractTextFromQuotes()
}
}
}
for (target in kotlinTargets.statements) {
target.handleTarget("fromPreset")
}
for (target in kotlinBlock.statements) {
target.handleTarget("targets.fromPreset")
}
val configureBlock = kotlinTargets.getBlockOrCreate("configure")
val factory = GroovyPsiElementFactory.getInstance(kotlinTargets.project)
val argumentList = factory.createArgumentListFromText(
targetNames.joinToString(prefix = "([", postfix = "])", separator = ", ")
)
configureBlock.getStrictParentOfType<GrMethodCallExpression>()!!.argumentList.replaceWithArgumentList(argumentList)
val kotlinOptions = configureBlock.getBlockOrCreate("tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions")
kotlinOptions.addParameterAssignment(parameterName, defaultValue, replaceIt)
return kotlinOptions.parent.parent
}
val kotlinBlock = gradleFile.getBlockOrCreate(if (forTests) "compileTestKotlin" else "compileKotlin")
for (stmt in kotlinBlock.statements) {
@@ -261,13 +323,7 @@ class GroovyBuildScriptManipulator(
}
}
kotlinBlock.getBlockOrCreate("kotlinOptions").apply {
statements.firstOrNull { stmt ->
(stmt as? GrAssignmentExpression)?.lValue?.text == parameterName
}?.let { stmt ->
stmt.replaceIt(false)
} ?: addLastExpressionInBlockIfNeeded("$parameterName = $defaultValue")
}
kotlinBlock.getBlockOrCreate("kotlinOptions").addParameterAssignment(parameterName, defaultValue, replaceIt)
return kotlinBlock.parent
}
@@ -581,6 +581,22 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
}
@TargetVersions("4.7+")
@Test
fun testDisableFeatureSupportMultiplatform() {
val files = importProjectFromTestData()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.changeFeatureConfiguration(
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.DISABLED, false
)
}
checkFiles(files)
}
}
@Test
fun testEnableFeatureSupport() {
val files = importProjectFromTestData()
@@ -596,6 +612,54 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
}
}
@TargetVersions("4.7+")
@Test
fun testEnableFeatureSupportMultiplatform() {
val files = importProjectFromTestData()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.changeFeatureConfiguration(
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.ENABLED, false
)
}
checkFiles(files)
}
}
@TargetVersions("4.7+")
@Test
fun testEnableFeatureSupportMultiplatformWithDots() {
val files = importProjectFromTestData()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.changeFeatureConfiguration(
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.ENABLED, false
)
}
checkFiles(files)
}
}
@TargetVersions("4.7+")
@Test
fun testEnableFeatureSupportMultiplatformToExistentArguments() {
val files = importProjectFromTestData()
runInEdtAndWait {
myTestFixture.project.executeWriteCommand("") {
KotlinWithGradleConfigurator.changeFeatureConfiguration(
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.ENABLED, false
)
}
checkFiles(files)
}
}
@Test
fun testEnableFeatureSupportToExistentArguments() {
val files = importProjectFromTestData()
@@ -0,0 +1,31 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,36 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
configure([jvm]) {
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions {
freeCompilerArgs = ["-XXLanguage:-InlineClasses"]
}
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,31 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,36 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
configure([jvm]) {
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions {
freeCompilerArgs = ["-XXLanguage:+InlineClasses"]
}
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,36 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
configure([jvm]) {
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions {
freeCompilerArgs = ["-XXLanguage:+SamConversionForKotlinFunctions"]
}
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,36 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets {
fromPreset(presets.jvm, 'jvm')
configure([jvm]) {
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions {
freeCompilerArgs = ["-XXLanguage:+SamConversionForKotlinFunctions", "-XXLanguage:+InlineClasses"]
}
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,29 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets.fromPreset(presets.jvm, 'jvm')
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
}
@@ -0,0 +1,36 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.0-rc-190"
}
}
apply plugin: "kotlin-multiplatform"
repositories {
jcenter()
mavenCentral()
}
kotlin {
targets.fromPreset(presets.jvm, 'jvm')
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
}
jvmMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}
}
}
targets {
configure([jvm]) {
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions {
freeCompilerArgs = ["-XXLanguage:+InlineClasses"]
}
}
}
}