Report incompatible metadata version error correctly
Similarly to pre-release classes, load metadata for the class anyway and allow the resolution to select it as the result and prohibit its usage in the end with the special diagnostic reported in MissingDependencyClassChecker
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.Pair;
|
||||
@@ -72,8 +73,10 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir {
|
||||
@NotNull String testDataDir,
|
||||
@NotNull BinaryVersion version
|
||||
) {
|
||||
String testDataAbsoluteDir = new File(testDataDir).getAbsolutePath();
|
||||
String normalizedOutputWithoutExitCode = pureOutput
|
||||
.replace(new File(testDataDir).getAbsolutePath(), "$TESTDATA_DIR$")
|
||||
.replace(testDataAbsoluteDir, "$TESTDATA_DIR$")
|
||||
.replace(FileUtil.toSystemIndependentName(testDataAbsoluteDir), "$TESTDATA_DIR$")
|
||||
.replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getAbsolutePath(), "$PROJECT_DIR$")
|
||||
.replace("expected version is " + version, "expected version is $ABI_VERSION$")
|
||||
.replace("\\", "/")
|
||||
|
||||
+54
-4
@@ -22,9 +22,11 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import kotlin.Pair;
|
||||
import kotlin.collections.SetsKt;
|
||||
import kotlin.io.FilesKt;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||
import org.jetbrains.kotlin.cli.AbstractCliTest;
|
||||
import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest;
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode;
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport;
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer;
|
||||
@@ -37,6 +39,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver;
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -92,7 +95,7 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
private String normalizeOutput(@NotNull Pair<String, ExitCode> output) {
|
||||
return AbstractCliTest.getNormalizedCompilerOutput(
|
||||
output.getFirst(), output.getSecond(), getTestDataDirectory().getPath(), JvmMetadataVersion.INSTANCE
|
||||
);
|
||||
).replace(FileUtil.toSystemIndependentName(tmpdir.getAbsolutePath()), "$TMP_DIR$");
|
||||
}
|
||||
|
||||
private void doTestWithTxt(@NotNull File... extraClassPath) throws Exception {
|
||||
@@ -134,6 +137,20 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
|
||||
@NotNull
|
||||
private static File copyJarFileWithoutEntry(@NotNull File jarPath, @NotNull String... entriesToDelete) {
|
||||
return transformJar(jarPath, new Function2<String, byte[], byte[]>() {
|
||||
@Override
|
||||
public byte[] invoke(String s, byte[] bytes) {
|
||||
return bytes;
|
||||
}
|
||||
}, entriesToDelete);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static File transformJar(
|
||||
@NotNull File jarPath,
|
||||
@NotNull Function2<String, byte[], byte[]> transformEntry,
|
||||
@NotNull String... entriesToDelete
|
||||
) {
|
||||
try {
|
||||
File outputFile = new File(jarPath.getParentFile(), FileUtil.getNameWithoutExtension(jarPath) + "-after.jar");
|
||||
Set<String> toDelete = SetsKt.setOf(entriesToDelete);
|
||||
@@ -144,11 +161,16 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
try {
|
||||
for (Enumeration<JarEntry> enumeration = jar.entries(); enumeration.hasMoreElements(); ) {
|
||||
JarEntry jarEntry = enumeration.nextElement();
|
||||
if (toDelete.contains(jarEntry.getName())) {
|
||||
String name = jarEntry.getName();
|
||||
if (toDelete.contains(name)) {
|
||||
continue;
|
||||
}
|
||||
output.putNextEntry(jarEntry);
|
||||
output.write(FileUtil.loadBytes(jar.getInputStream(jarEntry)));
|
||||
byte[] bytes = FileUtil.loadBytes(jar.getInputStream(jarEntry));
|
||||
byte[] newBytes = name.endsWith(".class") ? transformEntry.invoke(name, bytes) : bytes;
|
||||
JarEntry newEntry = new JarEntry(name);
|
||||
newEntry.setSize(newBytes.length);
|
||||
output.putNextEntry(newEntry);
|
||||
output.write(newBytes);
|
||||
output.closeEntry();
|
||||
}
|
||||
}
|
||||
@@ -228,6 +250,23 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output));
|
||||
}
|
||||
|
||||
private void doTestKotlinLibraryWithWrongMetadataVersion(@NotNull String libraryName, @NotNull String... additionalOptions) throws Exception {
|
||||
final int[] version = new JvmMetadataVersion(42, 0, 0).toArray();
|
||||
File library = transformJar(compileLibrary(libraryName), new Function2<String, byte[], byte[]>() {
|
||||
@Override
|
||||
public byte[] invoke(String name, byte[] bytes) {
|
||||
return WrongBytecodeVersionTest.Companion.transformMetadataInClassFile(bytes, new Function2<String, Object, Object>() {
|
||||
@Override
|
||||
public Object invoke(String name, Object value) {
|
||||
return JvmAnnotationNames.METADATA_VERSION_FIELD_NAME.equals(name) ? version : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, Arrays.asList(additionalOptions), library);
|
||||
KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void doTestPreReleaseKotlinLibrary(@NotNull String libraryName, @NotNull String... additionalOptions) throws Exception {
|
||||
// Compiles the library with the "pre-release" flag, then compiles a usage of this library in the release mode
|
||||
@@ -377,6 +416,17 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
}
|
||||
*/
|
||||
|
||||
public void testWrongMetadataVersion() throws Exception {
|
||||
doTestKotlinLibraryWithWrongMetadataVersion("library");
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: refactor and uncomment
|
||||
public void testWrongMetadataVersionSkipVersionCheck() throws Exception {
|
||||
doTestKotlinLibraryWithWrongMetadataVersion("library", "-Xskip-metadata-version-check");
|
||||
}
|
||||
*/
|
||||
|
||||
/*test source mapping generation when source info is absent*/
|
||||
public void testInlineFunWithoutDebugInfo() throws Exception {
|
||||
compileKotlin("sourceInline.kt", tmpdir);
|
||||
|
||||
Reference in New Issue
Block a user