Remove usages of com.intellij.* utils from kotlin-build-common, KT-31106
As Gradle may under certain conditions reorder the buildscript classpath artifacts, we need to ensure that the `kotlin-build-common` module, which duplicates some of the classes that are shaded and packed into `kotlin-compiler-embeddable`, does not call `com.intellij.*` classes. Replace the `com.intellij.*` utils that were called on the execution path with our own implementations. Issue #KT-31106 Fixed
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner;
|
package org.jetbrains.kotlin.compilerRunner;
|
||||||
|
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
|
||||||
import kotlin.collections.CollectionsKt;
|
import kotlin.collections.CollectionsKt;
|
||||||
import kotlin.jvm.JvmClassMappingKt;
|
import kotlin.jvm.JvmClassMappingKt;
|
||||||
import kotlin.reflect.KClass;
|
import kotlin.reflect.KClass;
|
||||||
@@ -25,6 +24,7 @@ import kotlin.reflect.KVisibility;
|
|||||||
import kotlin.reflect.full.KClasses;
|
import kotlin.reflect.full.KClasses;
|
||||||
import kotlin.reflect.jvm.ReflectJvmMapping;
|
import kotlin.reflect.jvm.ReflectJvmMapping;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
|
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.InternalArgument;
|
import org.jetbrains.kotlin.cli.common.arguments.InternalArgument;
|
||||||
@@ -60,7 +60,7 @@ public class ArgumentUtils {
|
|||||||
@NotNull List<String> result
|
@NotNull List<String> result
|
||||||
) throws IllegalAccessException, InstantiationException, InvocationTargetException {
|
) throws IllegalAccessException, InstantiationException, InvocationTargetException {
|
||||||
for (KProperty1 property : KClasses.getMemberProperties(clazz)) {
|
for (KProperty1 property : KClasses.getMemberProperties(clazz)) {
|
||||||
Argument argument = ContainerUtil.findInstance(property.getAnnotations(), Argument.class);
|
Argument argument = findInstance(property.getAnnotations(), Argument.class);
|
||||||
if (argument == null) continue;
|
if (argument == null) continue;
|
||||||
|
|
||||||
if (property.getVisibility() != KVisibility.PUBLIC) continue;
|
if (property.getVisibility() != KVisibility.PUBLIC) continue;
|
||||||
@@ -90,4 +90,14 @@ public class ArgumentUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static <T> T findInstance(Iterable<? super T> iterable, Class<T> clazz) {
|
||||||
|
for (Object item : iterable) {
|
||||||
|
if (clazz.isInstance(item)) {
|
||||||
|
return clazz.cast(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.compilerRunner;
|
package org.jetbrains.kotlin.compilerRunner;
|
||||||
|
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OutputItemsCollectorImpl implements OutputItemsCollector {
|
public class OutputItemsCollectorImpl implements OutputItemsCollector {
|
||||||
private final List<SimpleOutputItem> outputs = ContainerUtil.newArrayList();
|
private final List<SimpleOutputItem> outputs = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(Collection<File> sourceFiles, File outputFile) {
|
public void add(Collection<File> sourceFiles, File outputFile) {
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.incremental
|
package org.jetbrains.kotlin.incremental
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
|
||||||
import org.jetbrains.kotlin.build.GeneratedFile
|
import org.jetbrains.kotlin.build.GeneratedFile
|
||||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||||
@@ -67,11 +65,23 @@ fun makeModuleFile(
|
|||||||
friendDirs
|
friendDirs
|
||||||
)
|
)
|
||||||
|
|
||||||
val scriptFile = File.createTempFile("kjps", StringUtil.sanitizeJavaIdentifier(name) + ".script.xml")
|
val scriptFile = File.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml")
|
||||||
FileUtil.writeToFile(scriptFile, builder.asText().toString())
|
scriptFile.writeText(builder.asText().toString())
|
||||||
return scriptFile
|
return scriptFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sanitizeJavaIdentifier(string: String) =
|
||||||
|
buildString {
|
||||||
|
for (char in string) {
|
||||||
|
if (char.isJavaIdentifierPart()) {
|
||||||
|
if (length == 0 && !char.isJavaIdentifierStart()) {
|
||||||
|
append('_')
|
||||||
|
}
|
||||||
|
append(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun makeCompileServices(
|
fun makeCompileServices(
|
||||||
incrementalCaches: Map<TargetId, IncrementalCache>,
|
incrementalCaches: Map<TargetId, IncrementalCache>,
|
||||||
lookupTracker: LookupTracker,
|
lookupTracker: LookupTracker,
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.modules
|
package org.jetbrains.kotlin.modules
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
|
||||||
import com.intellij.openapi.util.text.StringUtil.escapeXml
|
|
||||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||||
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser.*
|
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser.*
|
||||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
@@ -137,6 +135,13 @@ class KotlinModuleXmlBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getEscapedPath(sourceFile: File): String {
|
private fun getEscapedPath(sourceFile: File): String {
|
||||||
return escapeXml(toSystemIndependentName(sourceFile.path))
|
return escapeXml(sourceFile.invariantSeparatorsPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val xmlEscapeReplacement = mapOf("<" to "<", ">" to ">", "&" to "&", "'" to "'", "\"" to """)
|
||||||
|
private val xmlEscapeRegex = Regex(xmlEscapeReplacement.keys.joinToString("|", "(?:", ")") { Regex.escape(it) })
|
||||||
|
|
||||||
|
private fun escapeXml(string: String) = string.replace(xmlEscapeRegex) { xmlEscapeReplacement.getValue(it.value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
@@ -963,4 +963,36 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
assertContains("Required com.example.compilation 'bar'")
|
assertContains("Required com.example.compilation 'bar'")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testLoadCompilerEmbeddableAfterOtherKotlinArtifacts() = with(Project("simpleProject")) {
|
||||||
|
setupWorkingDir()
|
||||||
|
val buildscriptClasspathPrefix = "buildscript-classpath = "
|
||||||
|
gradleBuildScript().appendText(
|
||||||
|
"\n" + """
|
||||||
|
println "$buildscriptClasspathPrefix" + Arrays.toString(buildscript.classLoader.getURLs())
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
// get the classpath, then reorder it so that kotlin-compiler-embeddable is loaded after all other JARs
|
||||||
|
lateinit var classpath: List<String>
|
||||||
|
|
||||||
|
build {
|
||||||
|
val classpathLine = output.lines().single { buildscriptClasspathPrefix in it }
|
||||||
|
classpath = classpathLine.substringAfter(buildscriptClasspathPrefix).removeSurrounding("[", "]").split(", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
gradleBuildScript().modify {
|
||||||
|
val reorderedClasspath = run {
|
||||||
|
val (kotlinCompilerEmbeddable, others) = classpath.partition { "kotlin-compiler-embeddable" in it }
|
||||||
|
others + kotlinCompilerEmbeddable
|
||||||
|
}
|
||||||
|
val newClasspathString = "classpath files(\n" + reorderedClasspath.joinToString(",\n") { "'$it'" } + "\n)"
|
||||||
|
it.checkedReplace("classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}kotlin_version\"", newClasspathString)
|
||||||
|
}
|
||||||
|
|
||||||
|
build("compileKotlin") {
|
||||||
|
assertSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user