report presence of multiple different versions of kotlin-runtime on the classpath as compilation error if other compilation errors have occurred
This commit is contained in:
+15
-3
@@ -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<KtFile>, analyzer: () -> AnalysisResult) {
|
||||
analysisResult = analyzer.invoke()
|
||||
interface Analyzer {
|
||||
fun analyze(): AnalysisResult
|
||||
|
||||
fun reportEnvironmentErrors() {
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeAndReport(files: Collection<KtFile>, 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()) {
|
||||
|
||||
@@ -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<K2JSCompilerArguments> {
|
||||
private static AnalyzerWithCompilerReport analyzeAndReportErrors(@NotNull MessageCollector messageCollector,
|
||||
@NotNull final List<KtFile> sources, @NotNull final Config config) {
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
|
||||
analyzerWithCompilerReport.analyzeAndReport(sources, new Function0<AnalysisResult>() {
|
||||
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;
|
||||
}
|
||||
|
||||
+42
-16
@@ -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<File>) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
$TESTDATA_DIR$/conflictingRuntimeVersions.kt
|
||||
-classpath
|
||||
$TESTDATA_DIR$/kotlin-runtime-4584-stub/kotlin-runtime.jar
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
$TESTDATA_DIR$/simple.kt
|
||||
-classpath
|
||||
$TESTDATA_DIR$/kotlin-runtime-4584-stub/kotlin-runtime.jar
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1 @@
|
||||
val f = unresolvedFunction()
|
||||
Binary file not shown.
@@ -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$");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -161,6 +161,11 @@
|
||||
<exclude>kotlin/internal/OnlyInputTypes*</exclude>
|
||||
<exclude>kotlin/internal</exclude>
|
||||
</excludes>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -228,6 +228,16 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -50,6 +50,13 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>empty-javadoc-jar</id>
|
||||
|
||||
Reference in New Issue
Block a user