/* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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 kotlin.Pair; import kotlin.collections.SetsKt; import kotlin.io.FilesKt; import kotlin.jvm.functions.Function2; import kotlin.text.Charsets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.cli.AbstractCliTest; import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest; import org.jetbrains.kotlin.cli.common.CLICompiler; import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.MessageRenderer; import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector; import org.jetbrains.kotlin.cli.js.K2JSCompiler; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.kotlin.config.CompilerConfiguration; 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.JvmMetadataVersion; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorUtils; 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; import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.JsMetadataVersion; import org.jetbrains.kotlin.utils.StringsKt; 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; import java.util.zip.ZipOutputStream; import static org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject; import static org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile; public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { private static final String TEST_DATA_PATH = "compiler/testData/compileKotlinAgainstCustomBinaries/"; private static final Pattern JAVA_FILES = Pattern.compile(".*\\.java$"); @NotNull private File getTestDataDirectory() { return new File(TEST_DATA_PATH, getTestName(true)); } @NotNull private File getTestDataFileWithExtension(@NotNull String extension) { return new File(getTestDataDirectory(), getTestName(true) + "." + extension); } @NotNull private File compileLibrary(@NotNull String sourcePath, @NotNull File... extraClassPath) { return compileLibrary(sourcePath, Collections.emptyList(), extraClassPath); } private File compileLibrary(@NotNull String sourcePath, List<String> additionalOptions, @NotNull File... extraClassPath) { File destination = new File(tmpdir, sourcePath + ".jar"); compileLibrary(new K2JVMCompiler(), sourcePath, destination, additionalOptions, extraClassPath); return destination; } private void compileLibrary( @NotNull CLICompiler<?> compiler, @NotNull String sourcePath, @NotNull File destination, List<String> additionalOptions, @NotNull File... extraClassPath ) { Pair<String, ExitCode> output = compileKotlin(compiler, sourcePath, destination, additionalOptions, extraClassPath); Assert.assertEquals(normalizeOutput(new Pair<>("", ExitCode.OK)), normalizeOutput(output)); } @NotNull private String normalizeOutput(@NotNull Pair<String, ExitCode> output) { return AbstractCliTest.getNormalizedCompilerOutput(output.getFirst(), output.getSecond(), getTestDataDirectory().getPath()) .replace(FileUtil.toSystemIndependentName(tmpdir.getAbsolutePath()), "$TMP_DIR$"); } private void doTestWithTxt(@NotNull File... extraClassPath) throws Exception { PackageViewDescriptor packageView = analyzeFileToPackageView(extraClassPath); RecursiveDescriptorComparator.Configuration comparator = AbstractLoadJavaTest.COMPARATOR_CONFIGURATION .withValidationStrategy(DescriptorValidator.ValidationVisitor.errorTypesAllowed()); validateAndCompareDescriptorWithFile(packageView, comparator, getTestDataFileWithExtension("txt")); } @NotNull private PackageViewDescriptor analyzeFileToPackageView(@NotNull File... extraClassPath) throws IOException { KotlinCoreEnvironment environment = createEnvironment(Arrays.asList(extraClassPath)); AnalysisResult result = JvmResolveUtil.analyzeAndCheckForErrors( KotlinTestUtils.loadJetFile(environment.getProject(), getTestDataFileWithExtension("kt")), environment ); PackageViewDescriptor packageView = result.getModuleDescriptor().getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME); assertFalse("Failed to find package: " + LoadDescriptorUtil.TEST_PACKAGE_FQNAME, packageView.isEmpty()); return packageView; } @NotNull private KotlinCoreEnvironment createEnvironment(@NotNull List<File> extraClassPath) { List<File> extras = new ArrayList<>(); extras.addAll(extraClassPath); extras.add(KotlinTestUtils.getAnnotationsJar()); CompilerConfiguration configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, extras.toArray(new File[extras.size()])); return KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); } @NotNull private Collection<DeclarationDescriptor> analyzeAndGetAllDescriptors(@NotNull File... extraClassPath) throws IOException { return DescriptorUtils.getAllDescriptors(analyzeFileToPackageView(extraClassPath).getMemberScope()); } @NotNull private static File copyJarFileWithoutEntry(@NotNull File jarPath, @NotNull String... entriesToDelete) { return transformJar(jarPath, (s, bytes) -> 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); try (JarFile jar = new JarFile(jarPath); ZipOutputStream output = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile)))) { for (Enumeration<JarEntry> enumeration = jar.entries(); enumeration.hasMoreElements(); ) { JarEntry jarEntry = enumeration.nextElement(); String name = jarEntry.getName(); if (toDelete.contains(name)) { continue; } 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(); } } return outputFile; } catch (IOException e) { throw ExceptionUtilsKt.rethrow(e); } } @NotNull private File compileJava(@NotNull String libraryDir) throws Exception { List<File> allJavaFiles = FileUtil.findFilesByMask(JAVA_FILES, new File(getTestDataDirectory(), libraryDir)); File result = new File(tmpdir, libraryDir); assert result.mkdirs() : "Could not create directory: " + result; KotlinTestUtils.compileJavaFiles(allJavaFiles, Arrays.asList("-d", result.getPath())); return result; } @NotNull private static File deletePaths(@NotNull File library, @NotNull String... pathsToDelete) { for (String pathToDelete : pathsToDelete) { File fileToDelete = new File(library, pathToDelete); assert fileToDelete.delete() : "Can't delete " + fileToDelete; } return library; } private Pair<String, ExitCode> compileKotlin( @NotNull String fileName, @NotNull File output, @NotNull File... classpath ) { return compileKotlin(fileName, output, Collections.emptyList(), classpath); } @NotNull private Pair<String, ExitCode> compileKotlin( @NotNull String fileName, @NotNull File output, @NotNull List<String> additionalOptions, @NotNull File... classpath ) { return compileKotlin(new K2JVMCompiler(), fileName, output, additionalOptions, classpath); } @NotNull private Pair<String, ExitCode> compileKotlin( @NotNull CLICompiler<?> compiler, @NotNull String fileName, @NotNull File output, @NotNull List<String> additionalOptions, @NotNull File... classpath ) { List<String> args = new ArrayList<>(); File sourceFile = new File(getTestDataDirectory(), fileName); assert sourceFile.exists() : "Source file does not exist: " + sourceFile.getAbsolutePath(); args.add(sourceFile.getPath()); if (compiler instanceof K2JSCompiler) { if (classpath.length > 0) { args.add("-libraries"); args.add(StringsKt.join(Arrays.asList(classpath), File.pathSeparator)); } args.add("-output"); args.add(output.getPath()); args.add("-meta-info"); } else if (compiler instanceof K2JVMCompiler) { if (classpath.length > 0) { args.add("-classpath"); args.add(StringsKt.join(Arrays.asList(classpath), File.pathSeparator)); } args.add("-d"); args.add(output.getPath()); } else { throw new UnsupportedOperationException(compiler.toString()); } args.addAll(additionalOptions); return AbstractCliTest.executeCompilerGrabOutput(compiler, args); } private void doTestBrokenJavaLibrary(@NotNull String libraryName, @NotNull String... pathsToDelete) throws Exception { // 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 File library = deletePaths(compileJava(libraryName), pathsToDelete); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } private void doTestBrokenKotlinLibrary(@NotNull String libraryName, @NotNull String... pathsToDelete) throws Exception { // Analogous to doTestBrokenJavaLibrary, but with a Kotlin library compiled to a JAR file File library = copyJarFileWithoutEntry(compileLibrary(libraryName), pathsToDelete); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } private void doTestKotlinLibraryWithWrongMetadataVersion( @NotNull String libraryName, @Nullable Function2<String, Object, Object> additionalTransformation, @NotNull String... additionalOptions ) throws Exception { int[] version = new JvmMetadataVersion(42, 0, 0).toArray(); File library = transformJar( compileLibrary(libraryName), (entryName, bytes) -> WrongBytecodeVersionTest.Companion.transformMetadataInClassFile(bytes, (fieldName, value) -> { if (additionalTransformation != null) { Object result = additionalTransformation.invoke(fieldName, value); if (result != null) return result; } return JvmAnnotationNames.METADATA_VERSION_FIELD_NAME.equals(fieldName) ? version : null; }) ); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, Arrays.asList(additionalOptions), library); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } private void doTestKotlinLibraryWithWrongMetadataVersionJs(@NotNull String libraryName, @NotNull String... additionalOptions) { compileLibrary(new K2JSCompiler(), libraryName, new File(tmpdir, "library.js"), Collections.emptyList()); File library = new File(tmpdir, "library.meta.js"); FilesKt.writeText(library, FilesKt.readText(library, Charsets.UTF_8).replace( "(" + JsMetadataVersion.INSTANCE.toInteger() + ", ", "(" + new JsMetadataVersion(42, 0, 0).toInteger() + ", " ), Charsets.UTF_8); Pair<String, ExitCode> output = compileKotlin( new K2JSCompiler(), "source.kt", new File(tmpdir, "usage.js"), Arrays.asList(additionalOptions), library ); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } private void doTestPreReleaseKotlinLibrary( @NotNull CLICompiler<?> compiler, @NotNull String libraryName, @NotNull File destination, @NotNull File result, @NotNull File usageDestination, @NotNull String... additionalOptions ) throws Exception { // Compiles the library with the "pre-release" flag, then compiles a usage of this library in the release mode try { System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true"); compileLibrary(compiler, libraryName, destination, Collections.emptyList()); } finally { System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY); } Pair<String, ExitCode> output; try { System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "false"); output = compileKotlin(compiler, "source.kt", usageDestination, Arrays.asList(additionalOptions), result); } finally { System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY); } KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } // ------------------------------------------------------------------------------ public void testRawTypes() throws Exception { KotlinTestUtils.compileJavaFiles( Collections.singletonList( new File(getTestDataDirectory() + "/library/test/A.java") ), Arrays.asList("-d", tmpdir.getPath()) ); Pair<String, ExitCode> outputLib = compileKotlin("library/test/lib.kt", tmpdir, tmpdir); Pair<String, ExitCode> outputMain = compileKotlin("main.kt", tmpdir, tmpdir); KotlinTestUtils.assertEqualsToFile( new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputLib) + "\n" + normalizeOutput(outputMain) ); } public void testDuplicateObjectInBinaryAndSources() throws Exception { Collection<DeclarationDescriptor> allDescriptors = analyzeAndGetAllDescriptors(compileLibrary("library")); assertEquals(allDescriptors.toString(), 2, allDescriptors.size()); for (DeclarationDescriptor descriptor : allDescriptors) { assertTrue("Wrong name: " + descriptor, descriptor.getName().asString().equals("Lol")); assertTrue("Should be an object: " + descriptor, isObject(descriptor)); } } public void testBrokenJarWithNoClassForObject() throws Exception { File brokenJar = copyJarFileWithoutEntry(compileLibrary("library"), "test/Lol.class"); Collection<DeclarationDescriptor> allDescriptors = analyzeAndGetAllDescriptors(brokenJar); assertEmpty("No descriptors should be found: " + allDescriptors, allDescriptors); } public void testSameLibraryTwiceInClasspath() throws Exception { doTestWithTxt(compileLibrary("library-1"), compileLibrary("library-2")); } public void testMissingEnumReferencedInAnnotationArgument() throws Exception { doTestWithTxt(copyJarFileWithoutEntry(compileLibrary("library"), "test/E.class")); } public void testNoWarningsOnJavaKotlinInheritance() throws Exception { // 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( Collections.singletonList(getTestDataFileWithExtension("java")), Arrays.asList("-d", tmpdir.getPath()) ); KotlinCoreEnvironment environment = createEnvironment(Collections.singletonList(tmpdir)); AnalysisResult result = JvmResolveUtil.analyze( KotlinTestUtils.loadJetFile(environment.getProject(), getTestDataFileWithExtension("kt")), environment ); result.throwIfError(); BindingContext bindingContext = result.getBindingContext(); AnalyzerWithCompilerReport.Companion.reportDiagnostics( bindingContext.getDiagnostics(), new PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false) ); assertEquals("There should be no diagnostics", 0, Iterables.size(bindingContext.getDiagnostics())); } public void testIncompleteHierarchyInJava() throws Exception { doTestBrokenJavaLibrary("library", "test/Super.class"); } public void testIncompleteHierarchyInKotlin() throws Exception { doTestBrokenKotlinLibrary("library", "test/Super.class"); } public void testMissingDependencySimple() throws Exception { doTestBrokenKotlinLibrary("library", "a/A.class"); } public void testMissingDependencyDifferentCases() throws Exception { doTestBrokenKotlinLibrary("library", "a/A.class"); } public void testMissingDependencyNestedAnnotation() throws Exception { doTestBrokenKotlinLibrary("library", "a/A$Anno.class"); } public void testMissingDependencyConflictingLibraries() throws Exception { File library1 = copyJarFileWithoutEntry(compileLibrary("library1"), "a/A.class", "a/A$Inner.class", "a/AA.class", "a/AA$Inner.class"); File library2 = copyJarFileWithoutEntry(compileLibrary("library2"), "a/A.class", "a/A$Inner.class", "a/AA.class", "a/AA$Inner.class"); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library1, library2); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } public void testMissingDependencyJava() throws Exception { doTestBrokenJavaLibrary("library", "test/Bar.class"); } public void testMissingDependencyJavaConflictingLibraries() throws Exception { File library1 = deletePaths(compileJava("library1"), "test/A.class", "test/A$Inner.class"); File library2 = deletePaths(compileJava("library2"), "test/A.class", "test/A$Inner.class"); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library1, library2); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } public void testMissingDependencyJavaNestedAnnotation() throws Exception { doTestBrokenJavaLibrary("library", "test/A$Anno.class"); } public void testReleaseCompilerAgainstPreReleaseLibrary() throws Exception { File destination = new File(tmpdir, "library.jar"); doTestPreReleaseKotlinLibrary(new K2JVMCompiler(), "library", destination, destination, tmpdir); } public void testReleaseCompilerAgainstPreReleaseLibraryJs() throws Exception { doTestPreReleaseKotlinLibrary( new K2JSCompiler(), "library", new File(tmpdir, "library.js"), new File(tmpdir, "library.meta.js"), new File(tmpdir, "usage.js") ); } public void testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() throws Exception { File destination = new File(tmpdir, "library.jar"); doTestPreReleaseKotlinLibrary( new K2JVMCompiler(), "library", destination, destination, tmpdir, "-Xskip-metadata-version-check" ); } public void testReleaseCompilerAgainstPreReleaseLibraryJsSkipVersionCheck() throws Exception { doTestPreReleaseKotlinLibrary( new K2JSCompiler(), "library", new File(tmpdir, "library.js"), new File(tmpdir, "library.meta.js"), new File(tmpdir, "usage.js"), "-Xskip-metadata-version-check" ); } public void testWrongMetadataVersion() throws Exception { doTestKotlinLibraryWithWrongMetadataVersion("library", null); } public void testWrongMetadataVersionJs() throws Exception { doTestKotlinLibraryWithWrongMetadataVersionJs("library"); } public void testWrongMetadataVersionBadMetadata() throws Exception { doTestKotlinLibraryWithWrongMetadataVersion( "library", (name, value) -> { if (JvmAnnotationNames.METADATA_DATA_FIELD_NAME.equals(name)) { String[] strings = (String[]) value; for (int i = 0; i < strings.length; i++) { byte[] bytes = strings[i].getBytes(); for (int j = 0; j < bytes.length; j++) bytes[j] ^= 42; strings[i] = new String(bytes); } return strings; } return null; } ); } public void testWrongMetadataVersionBadMetadata2() throws Exception { doTestKotlinLibraryWithWrongMetadataVersion( "library", (name, value) -> { if (JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME.equals(name)) { return ArrayUtil.EMPTY_STRING_ARRAY; } return null; } ); } public void testWrongMetadataVersionSkipVersionCheck() throws Exception { doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check"); } public void testWrongMetadataVersionJsSkipVersionCheck() throws Exception { doTestKotlinLibraryWithWrongMetadataVersionJs("library", "-Xskip-metadata-version-check"); } /*test source mapping generation when source info is absent*/ public void testInlineFunWithoutDebugInfo() throws Exception { compileKotlin("sourceInline.kt", tmpdir); File inlineFunClass = new File(tmpdir.getAbsolutePath(), "test/A.class"); ClassWriter cw = new ClassWriter(Opcodes.ASM5); new ClassReader(FilesKt.readBytes(inlineFunClass)).accept(new ClassVisitor(Opcodes.ASM5, cw) { @Override public void visitSource(String source, String debug) { //skip debug info } }, 0); assert inlineFunClass.delete(); assert !inlineFunClass.exists(); FilesKt.writeBytes(inlineFunClass, cw.toByteArray()); compileKotlin("source.kt", tmpdir, tmpdir); Ref<String> debugInfo = new Ref<>(); File resultFile = new File(tmpdir.getAbsolutePath(), "test/B.class"); new ClassReader(FilesKt.readBytes(resultFile)).accept(new ClassVisitor(Opcodes.ASM5) { @Override public void visitSource(String source, String debug) { //skip debug info debugInfo.set(debug); } }, 0); String 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"; if (InlineCodegenUtil.GENERATE_SMAP) { assertEquals(expected, debugInfo.get()); } else { assertEquals(null, debugInfo.get()); } } public void testReplaceAnnotationClassWithInterface() throws Exception { File library1 = compileLibrary("library-1"); File usage = compileLibrary("usage", library1); File library2 = compileLibrary("library-2"); doTestWithTxt(usage, library2); } public void testProhibitNestedClassesByDollarName() throws Exception { File library = compileLibrary("library"); KotlinTestUtils.compileJavaFiles( Collections.singletonList( new File(getTestDataDirectory() + "/library/test/JavaOuter.java") ), Arrays.asList("-d", tmpdir.getPath()) ); Pair<String, ExitCode> outputMain = compileKotlin("main.kt", tmpdir, tmpdir, library); KotlinTestUtils.assertEqualsToFile( new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain) ); } public void testTypeAliasesAreInvisibleInCompatibilityMode() { compileKotlin("typeAliases.kt", tmpdir); Pair<String, ExitCode> outputMain = compileKotlin("main.kt", tmpdir, Arrays.asList("-language-version", "1.0"), tmpdir); KotlinTestUtils.assertEqualsToFile( new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain) ); } public void testInnerClassPackageConflict() throws Exception { compileJava("library"); FileUtil.copy(new File(getTestDataDirectory(), "library/test/Foo/x.txt"), new File(tmpdir, "library/test/Foo/x.txt")); MockLibraryUtil.createJarFile(tmpdir, new File(tmpdir, "library"), null, "library", false); File jarPath = new File(tmpdir, "library.jar"); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, jarPath); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } public void testInnerClassPackageConflict2() throws Exception { File library1 = compileJava("library1"); File library2 = compileJava("library2"); // Copy everything from library2 to library1 FileUtil.visitFiles(library2, file -> { if (!file.isDirectory()) { File newFile = new File(library1, FilesKt.relativeTo(file, library2).getPath()); if (!newFile.getParentFile().exists()) { assert newFile.getParentFile().mkdirs(); } assert file.renameTo(newFile); } return true; }); Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library1); KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output)); } public void testWrongInlineTarget() throws Exception { File library = compileLibrary("library", Arrays.asList("-jvm-target", "1.8")); Pair<String, ExitCode> outputMain = compileKotlin("source.kt", tmpdir, library); KotlinTestUtils.assertEqualsToFile( new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain) ); } }