From 811b8978c21e412101049d19c237317a45c1d52d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 7 Mar 2017 21:21:51 +0300 Subject: [PATCH] Kotlin Facet: Escape additional compiler arguments when converting them to string and unescape before parsing #KT-16700 Fixed --- .../kotlin/config/CompilerSettings.kt | 7 ++++ .../idea/maven/KotlinMavenImporterTest.kt | 7 ++++ .../jetbrains/kotlin/idea/facet/facetUtils.kt | 7 +++- .../gradle/GradleFacetImportTest.kt | 40 +++++++++++++++++-- .../compilerRunner/JpsKotlinCompilerRunner.kt | 3 +- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/CompilerSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/CompilerSettings.kt index 89af21eee09..67326926e1c 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/CompilerSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/CompilerSettings.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.config +import com.intellij.openapi.util.text.StringUtil + class CompilerSettings { @JvmField var additionalArguments: String = DEFAULT_ADDITIONAL_ARGUMENTS @JvmField var scriptTemplates: String = "" @@ -28,3 +30,8 @@ class CompilerSettings { private val DEFAULT_OUTPUT_DIRECTORY = "lib" } } + +val CompilerSettings.additionalArgumentsAsList: List + get() = StringUtil.splitHonorQuotes(additionalArguments, ' ').map { + if (it.startsWith('"')) StringUtil.unescapeChar(StringUtil.unquoteString(it), '"') else it + } \ No newline at end of file diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt index 482e4674aa6..2a3fe835cd6 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.TargetPlatformKind +import org.jetbrains.kotlin.config.additionalArgumentsAsList import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.junit.Assert import java.io.File @@ -635,6 +636,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { -jvm-target 1.8 -Xcoroutines=enable + -jdk-home + c:\program files\jdk1.8 @@ -649,6 +652,10 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("enable", coroutineSupport.compilerArgument) + Assert.assertEquals( + listOf("-jdk-home", "c:\\program files\\jdk1.8"), + compilerSettings!!.additionalArgumentsAsList + ) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 9d4ac220413..bf9cdeb4636 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -23,6 +23,7 @@ import com.intellij.openapi.projectRoots.JavaSdk import com.intellij.openapi.projectRoots.JavaSdkVersion import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModel +import com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.config.* @@ -180,7 +181,11 @@ fun parseCompilerArgumentsToFacet(arguments: List, defaultArguments: Lis val additionalArgumentsString = with(compilerArguments.javaClass.newInstance()) { copyFieldsSatisfying(compilerArguments, this, ::exposeAsAdditionalArgument) - ArgumentUtils.convertArgumentsToStringList(this).joinToString(separator = " ") + ArgumentUtils.convertArgumentsToStringList(this).joinToString(separator = " ") { + if (StringUtil.containsWhitespaces(it) || it.startsWith('"')) { + StringUtil.wrapWithDoubleQuote(StringUtil.escapeQuotes(it)) + } else it + } } compilerSettings?.additionalArguments = if (additionalArgumentsString.isNotEmpty()) additionalArgumentsString else CompilerSettings.DEFAULT_ADDITIONAL_ARGUMENTS diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt index c62d91bfb47..a2b5524f9d8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt @@ -18,10 +18,7 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.config.CoroutineSupport -import org.jetbrains.kotlin.config.JvmTarget -import org.jetbrains.kotlin.config.KotlinFacetSettings -import org.jetbrains.kotlin.config.TargetPlatformKind +import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.junit.Assert import org.junit.Test @@ -571,4 +568,39 @@ class GradleFacetImportTest : GradleImportingTestCase() { Assert.assertEquals(TargetPlatformKind.Common, targetPlatformKind) } } + + @Test + fun testArgumentEscaping() { + createProjectSubFile("build.gradle", """ + group 'Again' + version '1.0-SNAPSHOT' + + buildscript { + repositories { + mavenCentral() + maven { + url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' + } + } + + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.0") + } + } + + apply plugin: 'kotlin-platform-jvm' + + compileKotlin { + kotlinOptions.jdkHome = "c:\\program files\\jdk1.8" + } + """) + importProject() + + with (facetSettings) { + Assert.assertEquals( + listOf("-jdk-home", "c:\\program files\\jdk1.8", "-Xmulti-platform"), + compilerSettings!!.additionalArgumentsAsList + ) + } + } } diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index 485f72aee0b..447b226c316 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.cli.common.arguments.mergeBeans import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CompilerSettings +import org.jetbrains.kotlin.config.additionalArgumentsAsList import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.jps.build.KotlinBuilder import java.io.ByteArrayOutputStream @@ -129,7 +130,7 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { private fun withAdditionalCompilerArgs(compilerArgs: CommonCompilerArguments): Array { val allArgs = ArgumentUtils.convertArgumentsToStringList(compilerArgs) + - (compilerSettings?.additionalArguments?.split(" ") ?: emptyList()) + (compilerSettings?.additionalArgumentsAsList ?: emptyList()) return allArgs.toTypedArray() }