From ccef1ad49e7fa482039198e203b789e6c1e52d19 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 19 Jan 2016 13:51:35 +0100 Subject: [PATCH] report presence of multiple different versions of kotlin-runtime on the classpath as compilation error if other compilation errors have occurred --- .../messages/AnalyzerWithCompilerReport.kt | 18 +++++- .../jetbrains/kotlin/cli/js/K2JSCompiler.java | 10 ++- .../compiler/KotlinToJVMBytecodeCompiler.kt | 58 +++++++++++++----- .../cli/jvm/conflictingRuntimeVersion.args | 5 ++ .../cli/jvm/conflictingRuntimeVersion.out | 5 ++ .../jvm/conflictingRuntimeVersionNoError.args | 5 ++ .../jvm/conflictingRuntimeVersionNoError.out | 1 + .../cli/jvm/conflictingRuntimeVersions.kt | 1 + .../kotlin-runtime.jar | Bin 0 -> 6106 bytes .../org/jetbrains/kotlin/cli/CliBaseTest.java | 2 + .../cli/KotlincExecutableTestGenerated.java | 12 ++++ libraries/kotlin.test/shared/pom.xml | 5 ++ libraries/pom.xml | 10 +++ libraries/tools/kotlin-reflect/pom.xml | 7 +++ 14 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 compiler/testData/cli/jvm/conflictingRuntimeVersion.args create mode 100644 compiler/testData/cli/jvm/conflictingRuntimeVersion.out create mode 100644 compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.args create mode 100644 compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.out create mode 100644 compiler/testData/cli/jvm/conflictingRuntimeVersions.kt create mode 100644 compiler/testData/cli/jvm/kotlin-runtime-4584-stub/kotlin-runtime.jar diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt index 03d501013fc..786649a9a2e 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import java.util.* + class AnalyzerWithCompilerReport(collector: MessageCollector) { private val messageCollector: MessageSeverityCollector = MessageSeverityCollector(collector) @@ -51,7 +52,8 @@ class AnalyzerWithCompilerReport(collector: MessageCollector) { val bindingContext = analysisResult.bindingContext val classes = bindingContext.getKeys(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY) if (!classes.isEmpty()) { - val message = StringBuilder("Supertypes of the following classes cannot be resolved. " + "Please make sure you have the required dependencies in the classpath:\n") + val message = StringBuilder("Supertypes of the following classes cannot be resolved. " + + "Please make sure you have the required dependencies in the classpath:\n") for (descriptor in classes) { val fqName = DescriptorUtils.getFqName(descriptor).asString() val unresolved = bindingContext.get(TraceBasedErrorReporter.INCOMPLETE_HIERARCHY, descriptor) @@ -116,9 +118,19 @@ class AnalyzerWithCompilerReport(collector: MessageCollector) { return messageCollector.anyReported(CompilerMessageSeverity.ERROR) } - fun analyzeAndReport(files: Collection, analyzer: () -> AnalysisResult) { - analysisResult = analyzer.invoke() + interface Analyzer { + fun analyze(): AnalysisResult + + fun reportEnvironmentErrors() { + } + } + + fun analyzeAndReport(files: Collection, analyzer: Analyzer) { + analysisResult = analyzer.analyze() reportSyntaxErrors(files) + if (analysisResult.bindingContext.diagnostics.any { it.isValid && it.severity == Severity.ERROR }) { + analyzer.reportEnvironmentErrors() + } val abiVersionErrors = abiVersionErrors reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector, !abiVersionErrors.isEmpty()) if (hasErrors()) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java index 5ff011aa2e7..8771e153e74 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java @@ -25,7 +25,6 @@ import com.intellij.util.Function; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import kotlin.Unit; -import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -232,11 +231,16 @@ public class K2JSCompiler extends CLICompiler { private static AnalyzerWithCompilerReport analyzeAndReportErrors(@NotNull MessageCollector messageCollector, @NotNull final List sources, @NotNull final Config config) { AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector); - analyzerWithCompilerReport.analyzeAndReport(sources, new Function0() { + analyzerWithCompilerReport.analyzeAndReport(sources, new AnalyzerWithCompilerReport.Analyzer() { + @NotNull @Override - public AnalysisResult invoke() { + public AnalysisResult analyze() { return TopDownAnalyzerFacadeForJS.analyzeFiles(sources, config); } + + @Override + public void reportEnvironmentErrors() { + } }); return analyzerWithCompilerReport; } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 2996bb0f0fb..e25c5dff964 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -16,15 +16,13 @@ package org.jetbrains.kotlin.cli.jvm.compiler +import com.intellij.openapi.util.io.JarUtil import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CompilerPluginContext import org.jetbrains.kotlin.cli.common.ExitCode -import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.messages.MessageUtil +import org.jetbrains.kotlin.cli.common.messages.* import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.config.* @@ -46,11 +44,13 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.util.PerformanceCounter import org.jetbrains.kotlin.utils.KotlinPaths +import org.jetbrains.kotlin.utils.PathUtil import java.io.File import java.lang.reflect.Constructor import java.lang.reflect.InvocationTargetException import java.net.URLClassLoader import java.util.concurrent.TimeUnit +import java.util.jar.Attributes object KotlinToJVMBytecodeCompiler { @@ -102,7 +102,7 @@ object KotlinToJVMBytecodeCompiler { moduleVisibilityManager.addFriendPath(path) } - val targetDescription = "in targets [" + chunk.joinToString { input -> input.getModuleName() + "-" + input.getModuleType() } + "]" + val targetDescription = "in targets [" + chunk.joinToString { input -> input.getModuleName() + "-" + input.getModuleType() } + "]" val result = analyze(environment, targetDescription) ?: return false ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() @@ -270,18 +270,24 @@ object KotlinToJVMBytecodeCompiler { val analysisStart = PerformanceCounter.currentTime() val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector) analyzerWithCompilerReport.analyzeAndReport( - environment.getSourceFiles(), { - val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace() - val moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, - environment.getModuleName()) + environment.getSourceFiles(), object : AnalyzerWithCompilerReport.Analyzer { + override fun analyze(): AnalysisResult { + val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace() + val moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, + environment.getModuleName()) - TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( - moduleContext, - environment.getSourceFiles(), - sharedTrace, - environment.configuration.get(JVMConfigurationKeys.MODULES), - environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), - JvmPackagePartProvider(environment)) + return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( + moduleContext, + environment.getSourceFiles(), + sharedTrace, + environment.configuration.get(JVMConfigurationKeys.MODULES), + environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), + JvmPackagePartProvider(environment)) + } + + override fun reportEnvironmentErrors() { + reportRuntimeConflicts(collector, environment.configuration.jvmClasspathRoots) + } }) val analysisNanos = PerformanceCounter.currentTime() - analysisStart val message = "ANALYZE: " + environment.getSourceFiles().size + " files (" + @@ -397,4 +403,24 @@ object KotlinToJVMBytecodeCompiler { assert(result != null) { "Message collector not specified in compiler configuration" } return result!! } + + private fun reportRuntimeConflicts(messageCollector: MessageCollector, jvmClasspathRoots: List) { + fun String.removeIdeaVersionSuffix(): String { + val versionIndex = indexOfAny(arrayListOf("-IJ", "-Idea")) + return if (versionIndex >= 0) substring(0, versionIndex) else this + } + + val runtimes = jvmClasspathRoots.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() } + + val runtimeVersions = runtimes.map { + JarUtil.getJarAttribute(it, Attributes.Name.IMPLEMENTATION_VERSION).orEmpty().removeIdeaVersionSuffix() + } + + if (runtimeVersions.toSet().size > 1) { + messageCollector.report(CompilerMessageSeverity.ERROR, + "Conflicting versions of Kotlin runtime on classpath: " + runtimes.joinToString { it.path }, + CompilerMessageLocation.NO_LOCATION) + } + } } + diff --git a/compiler/testData/cli/jvm/conflictingRuntimeVersion.args b/compiler/testData/cli/jvm/conflictingRuntimeVersion.args new file mode 100644 index 00000000000..4ba510281f2 --- /dev/null +++ b/compiler/testData/cli/jvm/conflictingRuntimeVersion.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/conflictingRuntimeVersions.kt +-classpath +$TESTDATA_DIR$/kotlin-runtime-4584-stub/kotlin-runtime.jar +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/conflictingRuntimeVersion.out b/compiler/testData/cli/jvm/conflictingRuntimeVersion.out new file mode 100644 index 00000000000..9521d8c8be1 --- /dev/null +++ b/compiler/testData/cli/jvm/conflictingRuntimeVersion.out @@ -0,0 +1,5 @@ +error: conflicting versions of Kotlin runtime on classpath: compiler/testData/cli/jvm/kotlin-runtime-4584-stub/kotlin-runtime.jar, $PROJECT_DIR$/lib/kotlin-runtime.jar +compiler/testData/cli/jvm/conflictingRuntimeVersions.kt:1:9: error: unresolved reference: unresolvedFunction +val f = unresolvedFunction() + ^ +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.args b/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.args new file mode 100644 index 00000000000..f468c786298 --- /dev/null +++ b/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/simple.kt +-classpath +$TESTDATA_DIR$/kotlin-runtime-4584-stub/kotlin-runtime.jar +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.out b/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.out new file mode 100644 index 00000000000..a0aba9318ad --- /dev/null +++ b/compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.out @@ -0,0 +1 @@ +OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/conflictingRuntimeVersions.kt b/compiler/testData/cli/jvm/conflictingRuntimeVersions.kt new file mode 100644 index 00000000000..39dd7f75cad --- /dev/null +++ b/compiler/testData/cli/jvm/conflictingRuntimeVersions.kt @@ -0,0 +1 @@ +val f = unresolvedFunction() diff --git a/compiler/testData/cli/jvm/kotlin-runtime-4584-stub/kotlin-runtime.jar b/compiler/testData/cli/jvm/kotlin-runtime-4584-stub/kotlin-runtime.jar new file mode 100644 index 0000000000000000000000000000000000000000..16c58570900dfa81f09280a881f4dc0b7d8bee47 GIT binary patch literal 6106 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 DuaZ=l literal 0 HcmV?d00001 diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliBaseTest.java b/compiler/tests/org/jetbrains/kotlin/cli/CliBaseTest.java index de15f64738d..dfeb2dfe850 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliBaseTest.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliBaseTest.java @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion; import org.jetbrains.kotlin.test.KotlinTestUtils; import org.jetbrains.kotlin.test.Tmpdir; import org.jetbrains.kotlin.utils.ExceptionUtilsKt; +import org.jetbrains.kotlin.utils.PathUtil; import org.junit.Rule; import org.junit.rules.TestName; @@ -83,6 +84,7 @@ public class CliBaseTest { ) { String normalizedOutputWithoutExitCode = pureOutput .replace(new File(testDataDir).getAbsolutePath(), "$TESTDATA_DIR$") + .replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getAbsolutePath(), "$PROJECT_DIR$") .replace("expected version is " + version, "expected version is $ABI_VERSION$") .replace("\\", "/") .replace(KotlinVersion.VERSION, "$VERSION$"); diff --git a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java index 1e23f2a3c72..38282e1031a 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java @@ -73,6 +73,18 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes doJvmTest(fileName); } + @TestMetadata("conflictingRuntimeVersion.args") + public void testConflictingRuntimeVersion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/conflictingRuntimeVersion.args"); + doJvmTest(fileName); + } + + @TestMetadata("conflictingRuntimeVersionNoError.args") + public void testConflictingRuntimeVersionNoError() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/conflictingRuntimeVersionNoError.args"); + doJvmTest(fileName); + } + @TestMetadata("diagnosticsOrder.args") public void testDiagnosticsOrder() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/diagnosticsOrder.args"); diff --git a/libraries/kotlin.test/shared/pom.xml b/libraries/kotlin.test/shared/pom.xml index da45fd238b4..4d86c0ef78a 100644 --- a/libraries/kotlin.test/shared/pom.xml +++ b/libraries/kotlin.test/shared/pom.xml @@ -161,6 +161,11 @@ kotlin/internal/OnlyInputTypes* kotlin/internal + + + true + + diff --git a/libraries/pom.xml b/libraries/pom.xml index b164b4af3a9..ec5c537c07a 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -228,6 +228,16 @@ + + maven-jar-plugin + + + + true + + + + diff --git a/libraries/tools/kotlin-reflect/pom.xml b/libraries/tools/kotlin-reflect/pom.xml index 59a35382fab..88a45423f1a 100644 --- a/libraries/tools/kotlin-reflect/pom.xml +++ b/libraries/tools/kotlin-reflect/pom.xml @@ -50,6 +50,13 @@ org.apache.maven.plugins maven-jar-plugin 2.6 + + + + true + + + empty-javadoc-jar