| // Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8; |
| |
| import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage; |
| import static org.hamcrest.CoreMatchers.containsString; |
| |
| import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; |
| import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; |
| import com.android.tools.r8.TestRuntime.CfRuntime; |
| import com.android.tools.r8.utils.DescriptorUtils; |
| import com.android.tools.r8.utils.FileUtils; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.IdentityHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.function.Consumer; |
| import java.util.stream.Collectors; |
| import org.hamcrest.Matcher; |
| import org.junit.rules.TemporaryFolder; |
| |
| public abstract class KotlinTestBase extends TestBase { |
| |
| protected static final String checkParameterIsNotNullSignature = |
| "void kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull(" |
| + "java.lang.Object, java.lang.String)"; |
| protected static final String throwParameterIsNotNullExceptionSignature = |
| "void kotlin.jvm.internal.Intrinsics.throwParameterIsNullException(java.lang.String)"; |
| public static final String METADATA_DESCRIPTOR = "Lkotlin/Metadata;"; |
| public static final String METADATA_TYPE = |
| DescriptorUtils.descriptorToJavaType(METADATA_DESCRIPTOR); |
| |
| private static final String RSRC = "kotlinR8TestResources"; |
| |
| private static final Map<String, KotlinCompileMemoizer> compileMemoizers = new HashMap<>(); |
| |
| protected final KotlinCompiler kotlinc; |
| protected final KotlinTargetVersion targetVersion; |
| protected final KotlinTestParameters kotlinParameters; |
| |
| protected KotlinTestBase(KotlinTestParameters kotlinParameters) { |
| this.targetVersion = kotlinParameters.getTargetVersion(); |
| this.kotlinc = kotlinParameters.getCompiler(); |
| this.kotlinParameters = kotlinParameters; |
| } |
| |
| public static CfRuntime getKotlincHostRuntime(TestRuntime runtime) { |
| return runtime.isCf() ? runtime.asCf() : TestRuntime.getCheckedInJdk9(); |
| } |
| |
| protected static List<Path> getKotlinFilesInTestPackage(Package pkg) throws IOException { |
| String folder = DescriptorUtils.getBinaryNameFromJavaType(pkg.getName()); |
| return Files.walk(Paths.get(ToolHelper.TESTS_DIR, "java", folder)) |
| .filter(path -> path.toString().endsWith(".kt")) |
| .collect(Collectors.toList()); |
| } |
| |
| protected static Path getKotlinFileInTestPackage(Package pkg, String fileName) { |
| String folder = DescriptorUtils.getBinaryNameFromJavaType(pkg.getName()); |
| return getKotlinFileInTest(folder, fileName); |
| } |
| |
| protected static Path getKotlinFileInTest(String folder, String fileName) { |
| return Paths.get(ToolHelper.TESTS_DIR, "java", folder, fileName + FileUtils.KT_EXTENSION); |
| } |
| |
| public static Path getKotlinFileInResource(String folder, String fileName) { |
| return Paths.get(ToolHelper.TESTS_DIR, RSRC, folder, fileName + FileUtils.KT_EXTENSION); |
| } |
| |
| public static List<Path> getKotlinFilesInResource(String folder) { |
| try { |
| return Files.walk(Paths.get(ToolHelper.TESTS_DIR, RSRC, folder)) |
| .filter(path -> path.toString().endsWith(".kt") || path.toString().endsWith(".java")) |
| .collect(Collectors.toList()); |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public static Path getKotlinResourcesFolder() { |
| return Paths.get(ToolHelper.TESTS_DIR, RSRC); |
| } |
| |
| protected Path getJavaJarFile(String folder) { |
| return Paths.get(ToolHelper.TESTS_BUILD_DIR, RSRC, |
| targetVersion.getFolderName(), folder + ".java" + FileUtils.JAR_EXTENSION); |
| } |
| |
| protected Path getMappingfile(String folder, String mappingFileName) { |
| return Paths.get(ToolHelper.TESTS_DIR, RSRC, folder, mappingFileName); |
| } |
| |
| protected static Matcher<String> expectedInfoMessagesFromKotlinStdLib() { |
| return containsString("No VersionRequirement"); |
| } |
| |
| protected KotlinCompilerTool kotlinCompilerTool() { |
| return KotlinCompilerTool.create(CfRuntime.getCheckedInJdk9(), temp, kotlinc, targetVersion); |
| } |
| |
| public static KotlinCompileMemoizer getCompileMemoizer(Path... source) { |
| return new KotlinCompileMemoizer(Arrays.asList(source)); |
| } |
| |
| public static KotlinCompileMemoizer getCompileMemoizer(Collection<Path> sources) { |
| assert sources.size() > 0; |
| return new KotlinCompileMemoizer(sources); |
| } |
| |
| public static KotlinCompileMemoizer getCompileMemoizer( |
| Collection<Path> sources, CfRuntime runtime, TemporaryFolder temporaryFolder) { |
| return new KotlinCompileMemoizer(sources, runtime, temporaryFolder); |
| } |
| |
| public static KotlinCompileMemoizer getCompileMemoizer( |
| Collection<Path> sources, String sharedFolder) { |
| return compileMemoizers.computeIfAbsent( |
| sharedFolder, ignore -> new KotlinCompileMemoizer(sources)); |
| } |
| |
| public ThrowableConsumer<R8TestCompileResult> assertUnusedKeepRuleForKotlinMetadata( |
| boolean condition) { |
| return compileResult -> { |
| if (!condition) { |
| return; |
| } |
| compileResult |
| .getDiagnosticMessages() |
| .assertInfoThatMatches( |
| diagnosticMessage( |
| containsString( |
| "Proguard configuration rule does not match anything: `-keep class" |
| + " kotlin.Metadata"))); |
| }; |
| } |
| |
| public static class KotlinCompileMemoizer { |
| |
| private final Collection<Path> sources; |
| private final CfRuntime runtime; |
| private final TemporaryFolder temporaryFolder; |
| |
| private Consumer<KotlinCompilerTool> kotlinCompilerToolConsumer = x -> {}; |
| private final Map<KotlinCompiler, Map<KotlinTargetVersion, Path>> compiledPaths = |
| new IdentityHashMap<>(); |
| |
| public KotlinCompileMemoizer(Collection<Path> sources) { |
| this(sources, CfRuntime.getCheckedInJdk9(), null); |
| } |
| |
| public KotlinCompileMemoizer( |
| Collection<Path> sources, CfRuntime runtime, TemporaryFolder temporaryFolder) { |
| this.sources = sources; |
| this.runtime = runtime; |
| this.temporaryFolder = temporaryFolder; |
| } |
| |
| public KotlinCompileMemoizer configure(Consumer<KotlinCompilerTool> consumer) { |
| this.kotlinCompilerToolConsumer = consumer; |
| return this; |
| } |
| |
| public Path getForConfiguration(KotlinTestParameters kotlinParameters) { |
| return getForConfiguration( |
| kotlinParameters.getCompiler(), kotlinParameters.getTargetVersion()); |
| } |
| |
| public Path getForConfiguration(KotlinCompiler compiler, KotlinTargetVersion targetVersion) { |
| Map<KotlinTargetVersion, Path> kotlinTargetVersionPathMap = compiledPaths.get(compiler); |
| if (kotlinTargetVersionPathMap == null) { |
| kotlinTargetVersionPathMap = new IdentityHashMap<>(); |
| compiledPaths.put(compiler, kotlinTargetVersionPathMap); |
| } |
| return kotlinTargetVersionPathMap.computeIfAbsent( |
| targetVersion, |
| ignored -> { |
| try { |
| KotlinCompilerTool kotlinc = |
| temporaryFolder == null |
| ? kotlinc(compiler, targetVersion) |
| : kotlinc(runtime, temporaryFolder, compiler, targetVersion); |
| return kotlinc.addSourceFiles(sources).apply(kotlinCompilerToolConsumer).compile(); |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| }); |
| } |
| } |
| } |