J2K CompileKotlinAgainstCustomBinariesTest: prettify

This commit is contained in:
Alexander Udalov
2017-05-25 16:26:49 +03:00
parent 2ef48bfbca
commit 0899eb9924
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.jvm.compiler
import com.google.common.collect.Iterables
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.cli.AbstractCliTest
import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest
import org.jetbrains.kotlin.cli.common.CLICompiler
@@ -41,21 +38,13 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isObject
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.util.DescriptorValidator
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile
import org.jetbrains.kotlin.utils.JsMetadataVersion
import org.jetbrains.kotlin.utils.join
import org.jetbrains.kotlin.utils.rethrow
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.ClassWriter
import org.jetbrains.org.objectweb.asm.Opcodes
import org.junit.Assert
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.regex.Pattern
@@ -67,109 +56,77 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
get() = File(TEST_DATA_PATH, getTestName(true))
private fun getTestDataFileWithExtension(extension: String): File {
return File(testDataDirectory, getTestName(true) + "." + extension)
}
private fun compileLibrary(sourcePath: String, vararg extraClassPath: File): File {
return compileLibrary(sourcePath, emptyList<String>(), *extraClassPath)
}
private fun compileLibrary(sourcePath: String, additionalOptions: List<String>, vararg extraClassPath: File): File {
val destination = File(tmpdir, sourcePath + ".jar")
compileLibrary(K2JVMCompiler(), sourcePath, destination, additionalOptions, *extraClassPath)
return destination
return File(testDataDirectory, "${getTestName(true)}.$extension")
}
private fun compileLibrary(
compiler: CLICompiler<*>, sourcePath: String, destination: File, additionalOptions: List<String>, vararg extraClassPath: File
) {
val output = compileKotlin(compiler, sourcePath, destination, additionalOptions, *extraClassPath)
Assert.assertEquals(normalizeOutput(Pair("", ExitCode.OK)), normalizeOutput(output))
sourcePath: String,
compiler: CLICompiler<*> = K2JVMCompiler(),
destination: File = File(tmpdir, "$sourcePath.jar"),
additionalOptions: List<String> = emptyList(),
vararg extraClassPath: File
): File {
val output = compileKotlin(sourcePath, destination, extraClassPath.toList(), compiler, additionalOptions)
assertEquals(normalizeOutput("" to ExitCode.OK), normalizeOutput(output))
return destination
}
private fun normalizeOutput(output: Pair<String, ExitCode>): String {
return AbstractCliTest.getNormalizedCompilerOutput(output.first, output.second, testDataDirectory.path)
.replace(FileUtil.toSystemIndependentName(tmpdir.absolutePath), "\$TMP_DIR$")
.replace(FileUtil.toSystemIndependentName(tmpdir.absolutePath), "\$TMP_DIR\$")
}
@Throws(Exception::class)
private fun doTestWithTxt(vararg extraClassPath: File) {
val packageView = analyzeFileToPackageView(*extraClassPath)
val comparator = AbstractLoadJavaTest.COMPARATOR_CONFIGURATION
.withValidationStrategy(DescriptorValidator.ValidationVisitor.errorTypesAllowed())
validateAndCompareDescriptorWithFile(packageView, comparator, getTestDataFileWithExtension("txt"))
validateAndCompareDescriptorWithFile(
analyzeFileToPackageView(*extraClassPath),
AbstractLoadJavaTest.COMPARATOR_CONFIGURATION,
getTestDataFileWithExtension("txt")
)
}
@Throws(IOException::class)
private fun analyzeFileToPackageView(vararg extraClassPath: File): PackageViewDescriptor {
val environment = createEnvironment(Arrays.asList(*extraClassPath))
val environment = createEnvironment(extraClassPath.toList())
val result = JvmResolveUtil.analyzeAndCheckForErrors(
KotlinTestUtils.loadJetFile(environment.project, getTestDataFileWithExtension("kt")), environment
)
val ktFile = KotlinTestUtils.loadJetFile(environment.project, getTestDataFileWithExtension("kt"))
val result = JvmResolveUtil.analyzeAndCheckForErrors(ktFile, environment)
val packageView = result.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME)
assertFalse("Failed to find package: " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, packageView.isEmpty())
return packageView
return result.moduleDescriptor.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME).also {
assertFalse("Failed to find package: " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, it.isEmpty())
}
}
private fun createEnvironment(extraClassPath: List<File>): KotlinCoreEnvironment {
val extras = ArrayList<File>()
extras.addAll(extraClassPath)
extras.add(KotlinTestUtils.getAnnotationsJar())
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *extras.toTypedArray())
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, *extraClassPath.toTypedArray())
return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
}
@Throws(IOException::class)
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> {
return DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
}
private fun analyzeAndGetAllDescriptors(vararg extraClassPath: File): Collection<DeclarationDescriptor> =
DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(*extraClassPath).memberScope)
@Throws(Exception::class)
private fun compileJava(libraryDir: String): File {
val allJavaFiles = FileUtil.findFilesByMask(JAVA_FILES, File(testDataDirectory, libraryDir))
val result = File(tmpdir, libraryDir)
assert(result.mkdirs()) { "Could not create directory: " + result }
KotlinTestUtils.compileJavaFiles(allJavaFiles, Arrays.asList("-d", result.path))
assert(result.mkdirs()) { "Could not create directory: $result" }
KotlinTestUtils.compileJavaFiles(allJavaFiles, listOf("-d", result.path))
return result
}
private fun compileKotlin(
fileName: String,
output: File,
vararg classpath: File
classpath: List<File> = emptyList(),
compiler: CLICompiler<*> = K2JVMCompiler(),
additionalOptions: List<String> = emptyList()
): Pair<String, ExitCode> {
return compileKotlin(fileName, output, emptyList<String>(), *classpath)
}
private fun compileKotlin(
fileName: String,
output: File,
additionalOptions: List<String>,
vararg classpath: File
): Pair<String, ExitCode> {
return compileKotlin(K2JVMCompiler(), fileName, output, additionalOptions, *classpath)
}
private fun compileKotlin(
compiler: CLICompiler<*>,
fileName: String,
output: File,
additionalOptions: List<String>,
vararg classpath: File
): Pair<String, ExitCode> {
val args = ArrayList<String>()
val args = mutableListOf<String>()
val sourceFile = File(testDataDirectory, fileName)
assert(sourceFile.exists()) { "Source file does not exist: " + sourceFile.absolutePath }
assert(sourceFile.exists()) { "Source file does not exist: ${sourceFile.absolutePath}" }
args.add(sourceFile.path)
if (compiler is K2JSCompiler) {
if (classpath.isNotEmpty()) {
args.add("-libraries")
args.add(join(Arrays.asList(*classpath), File.pathSeparator))
args.add(classpath.joinToString(File.pathSeparator))
}
args.add("-output")
args.add(output.path)
@@ -178,7 +135,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
else if (compiler is K2JVMCompiler) {
if (classpath.isNotEmpty()) {
args.add("-classpath")
args.add(join(Arrays.asList(*classpath), File.pathSeparator))
args.add(classpath.joinToString(File.pathSeparator))
}
args.add("-d")
args.add(output.path)
@@ -192,25 +149,22 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
return AbstractCliTest.executeCompilerGrabOutput(compiler, args)
}
@Throws(Exception::class)
private fun doTestBrokenJavaLibrary(libraryName: String, vararg pathsToDelete: String) {
// This function compiles a Java library, then deletes one class file and attempts to compile a Kotlin source against
// this broken library. The expected result is an error message from the compiler
val library = deletePaths(compileJava(libraryName), *pathsToDelete)
val output = compileKotlin("source.kt", tmpdir, library)
val output = compileKotlin("source.kt", tmpdir, listOf(library))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
private fun doTestBrokenKotlinLibrary(libraryName: String, vararg pathsToDelete: String) {
// Analogous to doTestBrokenJavaLibrary, but with a Kotlin library compiled to a JAR file
val library = copyJarFileWithoutEntry(compileLibrary(libraryName), *pathsToDelete)
val output = compileKotlin("source.kt", tmpdir, library)
val output = compileKotlin("source.kt", tmpdir, listOf(library))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
private fun doTestKotlinLibraryWithWrongMetadataVersion(
libraryName: String,
additionalTransformation: ((fieldName: String, value: Any?) -> Any?)?,
@@ -219,22 +173,19 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
val version = JvmMetadataVersion(42, 0, 0).toArray()
val library = transformJar(
compileLibrary(libraryName),
{ entryName, bytes ->
{ _, bytes ->
WrongBytecodeVersionTest.transformMetadataInClassFile(bytes) { fieldName, value ->
if (additionalTransformation != null) {
val result = additionalTransformation.invoke(fieldName, value)
if (result != null) return@transformMetadataInClassFile result
}
if (JvmAnnotationNames.METADATA_VERSION_FIELD_NAME == fieldName) version else null
additionalTransformation?.invoke(fieldName, value) ?:
version.takeIf { JvmAnnotationNames.METADATA_VERSION_FIELD_NAME == fieldName }
}
}
)
val output = compileKotlin("source.kt", tmpdir, Arrays.asList(*additionalOptions), library)
val output = compileKotlin("source.kt", tmpdir, listOf(library), K2JVMCompiler(), additionalOptions.toList())
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
private fun doTestKotlinLibraryWithWrongMetadataVersionJs(libraryName: String, vararg additionalOptions: String) {
compileLibrary(K2JSCompiler(), libraryName, File(tmpdir, "library.js"), emptyList<String>())
compileLibrary(libraryName, K2JSCompiler(), File(tmpdir, "library.js"), emptyList())
val library = File(tmpdir, "library.meta.js")
library.writeText(library.readText(Charsets.UTF_8).replace(
@@ -242,13 +193,10 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
"(" + JsMetadataVersion(42, 0, 0).toInteger() + ", "
), Charsets.UTF_8)
val output = compileKotlin(
K2JSCompiler(), "source.kt", File(tmpdir, "usage.js"), Arrays.asList(*additionalOptions), library
)
val output = compileKotlin("source.kt", File(tmpdir, "usage.js"), listOf(library), K2JSCompiler(), additionalOptions.toList())
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
private fun doTestPreReleaseKotlinLibrary(
compiler: CLICompiler<*>,
libraryName: String,
@@ -261,7 +209,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true")
compileLibrary(compiler, libraryName, destination, emptyList<String>())
compileLibrary(libraryName, compiler, destination)
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
@@ -270,7 +218,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
val output: Pair<String, ExitCode>
try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "false")
output = compileKotlin(compiler, "source.kt", usageDestination, Arrays.asList(*additionalOptions), result)
output = compileKotlin("source.kt", usageDestination, listOf(result), compiler, additionalOptions.toList())
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
@@ -281,23 +229,21 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
// ------------------------------------------------------------------------------
@Throws(Exception::class)
fun testRawTypes() {
KotlinTestUtils.compileJavaFiles(
listOf(File(testDataDirectory.toString() + "/library/test/A.java")),
Arrays.asList("-d", tmpdir.path)
listOf("-d", tmpdir.path)
)
val outputLib = compileKotlin("library/test/lib.kt", tmpdir, tmpdir)
val outputLib = compileKotlin("library/test/lib.kt", tmpdir, listOf(tmpdir))
val outputMain = compileKotlin("main.kt", tmpdir, tmpdir)
val outputMain = compileKotlin("main.kt", tmpdir, listOf(tmpdir))
KotlinTestUtils.assertEqualsToFile(
File(testDataDirectory, "output.txt"), normalizeOutput(outputLib) + "\n" + normalizeOutput(outputMain)
)
}
@Throws(Exception::class)
fun testDuplicateObjectInBinaryAndSources() {
val allDescriptors = analyzeAndGetAllDescriptors(compileLibrary("library"))
assertEquals(allDescriptors.toString(), 2, allDescriptors.size)
@@ -307,109 +253,92 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
}
}
@Throws(Exception::class)
fun testBrokenJarWithNoClassForObject() {
val brokenJar = copyJarFileWithoutEntry(compileLibrary("library"), "test/Lol.class")
val allDescriptors = analyzeAndGetAllDescriptors(brokenJar)
assertEmpty("No descriptors should be found: " + allDescriptors, allDescriptors)
}
@Throws(Exception::class)
fun testSameLibraryTwiceInClasspath() {
doTestWithTxt(compileLibrary("library-1"), compileLibrary("library-2"))
}
@Throws(Exception::class)
fun testMissingEnumReferencedInAnnotationArgument() {
doTestWithTxt(copyJarFileWithoutEntry(compileLibrary("library"), "test/E.class"))
}
@Throws(Exception::class)
fun testNoWarningsOnJavaKotlinInheritance() {
// This test checks that there are no PARAMETER_NAME_CHANGED_ON_OVERRIDE or DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES
// warnings when subclassing in Kotlin from Java binaries (in case when no parameter names are available for Java classes)
KotlinTestUtils.compileJavaFiles(
listOf(getTestDataFileWithExtension("java")),
Arrays.asList("-d", tmpdir.path)
listOf("-d", tmpdir.path)
)
val environment = createEnvironment(listOf(tmpdir))
val result = JvmResolveUtil.analyze(
KotlinTestUtils.loadJetFile(environment.project, getTestDataFileWithExtension("kt")), environment
)
val ktFile = KotlinTestUtils.loadJetFile(environment.project, getTestDataFileWithExtension("kt"))
val result = JvmResolveUtil.analyze(ktFile, environment)
result.throwIfError()
val bindingContext = result.bindingContext
AnalyzerWithCompilerReport.reportDiagnostics(
bindingContext.diagnostics,
result.bindingContext.diagnostics,
PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
)
assertEquals("There should be no diagnostics", 0, Iterables.size(bindingContext.diagnostics))
assertEquals("There should be no diagnostics", 0, result.bindingContext.diagnostics.count())
}
@Throws(Exception::class)
fun testIncompleteHierarchyInJava() {
doTestBrokenJavaLibrary("library", "test/Super.class")
}
@Throws(Exception::class)
fun testIncompleteHierarchyInKotlin() {
doTestBrokenKotlinLibrary("library", "test/Super.class")
}
@Throws(Exception::class)
fun testMissingDependencySimple() {
doTestBrokenKotlinLibrary("library", "a/A.class")
}
@Throws(Exception::class)
fun testMissingDependencyDifferentCases() {
doTestBrokenKotlinLibrary("library", "a/A.class")
}
@Throws(Exception::class)
fun testMissingDependencyNestedAnnotation() {
doTestBrokenKotlinLibrary("library", "a/A\$Anno.class")
}
@Throws(Exception::class)
fun testMissingDependencyConflictingLibraries() {
val library1 = copyJarFileWithoutEntry(compileLibrary("library1"),
"a/A.class", "a/A\$Inner.class", "a/AA.class", "a/AA\$Inner.class")
val library2 = copyJarFileWithoutEntry(compileLibrary("library2"),
"a/A.class", "a/A\$Inner.class", "a/AA.class", "a/AA\$Inner.class")
val output = compileKotlin("source.kt", tmpdir, library1, library2)
val output = compileKotlin("source.kt", tmpdir, listOf(library1, library2))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
fun testMissingDependencyJava() {
doTestBrokenJavaLibrary("library", "test/Bar.class")
}
@Throws(Exception::class)
fun testMissingDependencyJavaConflictingLibraries() {
val library1 = deletePaths(compileJava("library1"), "test/A.class", "test/A\$Inner.class")
val library2 = deletePaths(compileJava("library2"), "test/A.class", "test/A\$Inner.class")
val output = compileKotlin("source.kt", tmpdir, library1, library2)
val output = compileKotlin("source.kt", tmpdir, listOf(library1, library2))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
fun testMissingDependencyJavaNestedAnnotation() {
doTestBrokenJavaLibrary("library", "test/A\$Anno.class")
}
@Throws(Exception::class)
fun testReleaseCompilerAgainstPreReleaseLibrary() {
val destination = File(tmpdir, "library.jar")
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", destination, destination, tmpdir)
}
@Throws(Exception::class)
fun testReleaseCompilerAgainstPreReleaseLibraryJs() {
doTestPreReleaseKotlinLibrary(
K2JSCompiler(), "library",
@@ -418,7 +347,6 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
)
}
@Throws(Exception::class)
fun testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() {
val destination = File(tmpdir, "library.jar")
doTestPreReleaseKotlinLibrary(
@@ -428,7 +356,6 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
)
}
@Throws(Exception::class)
fun testReleaseCompilerAgainstPreReleaseLibraryJsSkipVersionCheck() {
doTestPreReleaseKotlinLibrary(
K2JSCompiler(), "library",
@@ -438,67 +365,49 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
)
}
@Throws(Exception::class)
fun testWrongMetadataVersion() {
doTestKotlinLibraryWithWrongMetadataVersion("library", null)
}
@Throws(Exception::class)
fun testWrongMetadataVersionJs() {
doTestKotlinLibraryWithWrongMetadataVersionJs("library")
}
@Throws(Exception::class)
fun testWrongMetadataVersionBadMetadata() {
doTestKotlinLibraryWithWrongMetadataVersion(
"library",
{ name, value ->
if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME == name) {
val strings = value as Array<String>
for (i in strings.indices) {
val bytes = strings[i].toByteArray()
for (j in bytes.indices) bytes[j] = bytes[j] xor 42
strings[i] = String(bytes)
}
return@doTestKotlinLibraryWithWrongMetadataVersion strings
}
null
}
)
doTestKotlinLibraryWithWrongMetadataVersion("library", { name, value ->
if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME == name) {
@Suppress("UNCHECKED_CAST")
val strings = value as Array<String>
strings.map { string ->
String(string.toByteArray().map { x -> x xor 42 }.toTypedArray().toByteArray())
}.toTypedArray()
}
else null
})
}
@Throws(Exception::class)
fun testWrongMetadataVersionBadMetadata2() {
doTestKotlinLibraryWithWrongMetadataVersion(
"library",
{ name, value ->
if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME == name) {
return@doTestKotlinLibraryWithWrongMetadataVersion ArrayUtil.EMPTY_STRING_ARRAY
}
null
}
)
doTestKotlinLibraryWithWrongMetadataVersion("library", { name, _ ->
if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME == name) arrayOf<String>() else null
})
}
@Throws(Exception::class)
fun testWrongMetadataVersionSkipVersionCheck() {
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check")
}
@Throws(Exception::class)
fun testWrongMetadataVersionJsSkipVersionCheck() {
doTestKotlinLibraryWithWrongMetadataVersionJs("library", "-Xskip-metadata-version-check")
}
/*test source mapping generation when source info is absent*/
@Throws(Exception::class)
fun testInlineFunWithoutDebugInfo() {
compileKotlin("sourceInline.kt", tmpdir)
val inlineFunClass = File(tmpdir.absolutePath, "test/A.class")
val cw = ClassWriter(Opcodes.ASM5)
ClassReader(inlineFunClass.readBytes()).accept(object : ClassVisitor(Opcodes.ASM5, cw) {
override fun visitSource(source: String, debug: String) {
override fun visitSource(source: String?, debug: String?) {
//skip debug info
}
}, 0)
@@ -508,54 +417,53 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
inlineFunClass.writeBytes(cw.toByteArray())
compileKotlin("source.kt", tmpdir, tmpdir)
compileKotlin("source.kt", tmpdir, listOf(tmpdir))
val debugInfo = Ref<String>()
var debugInfo: String? = null
val resultFile = File(tmpdir.absolutePath, "test/B.class")
ClassReader(resultFile.readBytes()).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitSource(source: String, debug: String) {
//skip debug info
debugInfo.set(debug)
override fun visitSource(source: String?, debug: String?) {
debugInfo = debug
}
}, 0)
val expected = "SMAP\n" +
"source.kt\n" +
"Kotlin\n" +
"*S Kotlin\n" +
"*F\n" +
"+ 1 source.kt\n" +
"test/B\n" +
"*L\n" +
"1#1,13:1\n" +
"*E\n"
val expected = """
SMAP
source.kt
Kotlin
*S Kotlin
*F
+ 1 source.kt
test/B
*L
1#1,13:1
*E
""".trimIndent() + "\n"
if (InlineCodegenUtil.GENERATE_SMAP) {
assertEquals(expected, debugInfo.get())
assertEquals(expected, debugInfo)
}
else {
assertEquals(null, debugInfo.get())
assertEquals(null, debugInfo)
}
}
@Throws(Exception::class)
fun testReplaceAnnotationClassWithInterface() {
val library1 = compileLibrary("library-1")
val usage = compileLibrary("usage", library1)
val usage = compileLibrary("usage", extraClassPath = *arrayOf(library1))
val library2 = compileLibrary("library-2")
doTestWithTxt(usage, library2)
}
@Throws(Exception::class)
fun testProhibitNestedClassesByDollarName() {
val library = compileLibrary("library")
KotlinTestUtils.compileJavaFiles(
listOf(File(testDataDirectory.toString() + "/library/test/JavaOuter.java")),
Arrays.asList("-d", tmpdir.path)
listOf("-d", tmpdir.path)
)
val outputMain = compileKotlin("main.kt", tmpdir, tmpdir, library)
val outputMain = compileKotlin("main.kt", tmpdir, listOf(tmpdir, library))
KotlinTestUtils.assertEqualsToFile(
File(testDataDirectory, "output.txt"), normalizeOutput(outputMain)
@@ -565,25 +473,22 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
fun testTypeAliasesAreInvisibleInCompatibilityMode() {
compileKotlin("typeAliases.kt", tmpdir)
val outputMain = compileKotlin("main.kt", tmpdir, Arrays.asList("-language-version", "1.0"), tmpdir)
val outputMain = compileKotlin("main.kt", tmpdir, listOf(tmpdir), K2JVMCompiler(), listOf("-language-version", "1.0"))
KotlinTestUtils.assertEqualsToFile(
File(testDataDirectory, "output.txt"), normalizeOutput(outputMain)
)
}
@Throws(Exception::class)
fun testInnerClassPackageConflict() {
compileJava("library")
FileUtil.copy(File(testDataDirectory, "library/test/Foo/x.txt"),
File(tmpdir, "library/test/Foo/x.txt"))
File(testDataDirectory, "library/test/Foo/x.txt").copyTo(File(tmpdir, "library/test/Foo/x.txt"))
MockLibraryUtil.createJarFile(tmpdir, File(tmpdir, "library"), null, "library", false)
val jarPath = File(tmpdir, "library.jar")
val output = compileKotlin("source.kt", tmpdir, jarPath)
val output = compileKotlin("source.kt", tmpdir, listOf(jarPath))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
fun testInnerClassPackageConflict2() {
val library1 = compileJava("library1")
val library2 = compileJava("library2")
@@ -600,15 +505,14 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
true
}
val output = compileKotlin("source.kt", tmpdir, library1)
val output = compileKotlin("source.kt", tmpdir, listOf(library1))
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "output.txt"), normalizeOutput(output))
}
@Throws(Exception::class)
fun testWrongInlineTarget() {
val library = compileLibrary("library", Arrays.asList("-jvm-target", "1.8"))
val library = compileLibrary("library", additionalOptions = listOf("-jvm-target", "1.8"))
val outputMain = compileKotlin("source.kt", tmpdir, library)
val outputMain = compileKotlin("source.kt", tmpdir, listOf(library))
KotlinTestUtils.assertEqualsToFile(
File(testDataDirectory, "output.txt"), normalizeOutput(outputMain)
@@ -619,51 +523,40 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() {
private val TEST_DATA_PATH = "compiler/testData/compileKotlinAgainstCustomBinaries/"
private val JAVA_FILES = Pattern.compile(".*\\.java$")
private fun copyJarFileWithoutEntry(jarPath: File, vararg entriesToDelete: String): File {
return transformJar(jarPath, { s, bytes -> bytes }, *entriesToDelete)
}
private fun copyJarFileWithoutEntry(jarPath: File, vararg entriesToDelete: String): File =
transformJar(jarPath, { _, bytes -> bytes }, entriesToDelete.toSet())
private fun transformJar(
jarPath: File,
transformEntry: Function2<String, ByteArray, ByteArray>,
vararg entriesToDelete: String
transformEntry: (String, ByteArray) -> ByteArray,
entriesToDelete: Set<String> = emptySet()
): File {
try {
val outputFile = File(jarPath.parentFile, FileUtil.getNameWithoutExtension(jarPath) + "-after.jar")
val toDelete = setOf(*entriesToDelete)
val outputFile = File(jarPath.parentFile, "${jarPath.nameWithoutExtension}-after.jar")
JarFile(jarPath).use { jar ->
ZipOutputStream(BufferedOutputStream(FileOutputStream(outputFile))).use { output ->
val enumeration = jar.entries()
while (enumeration.hasMoreElements()) {
val jarEntry = enumeration.nextElement()
val name = jarEntry.name
if (toDelete.contains(name)) {
continue
}
val bytes = FileUtil.loadBytes(jar.getInputStream(jarEntry))
val newBytes = if (name.endsWith(".class")) transformEntry.invoke(name, bytes) else bytes
val newEntry = JarEntry(name)
newEntry.size = newBytes.size.toLong()
output.putNextEntry(newEntry)
output.write(newBytes)
output.closeEntry()
}
JarFile(jarPath).use { jar ->
ZipOutputStream(outputFile.outputStream().buffered()).use { output ->
for (jarEntry in jar.entries()) {
val name = jarEntry.name
if (name in entriesToDelete) continue
val bytes = jar.getInputStream(jarEntry).readBytes()
val newBytes = if (name.endsWith(".class")) transformEntry(name, bytes) else bytes
val newEntry = JarEntry(name)
newEntry.size = newBytes.size.toLong()
output.putNextEntry(newEntry)
output.write(newBytes)
output.closeEntry()
}
}
return outputFile
}
catch (e: IOException) {
throw rethrow(e)
}
return outputFile
}
private fun deletePaths(library: File, vararg pathsToDelete: String): File {
for (pathToDelete in pathsToDelete) {
val fileToDelete = File(library, pathToDelete)
assert(fileToDelete.delete()) { "Can't delete " + fileToDelete }
assert(fileToDelete.delete()) { "Can't delete $fileToDelete" }
}
return library
}