blob: 16963276d630953399de84169cd64fbfc9d3dc0d [file] [log] [blame]
// 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.TestRuntime.CfRuntime;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
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;
}
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);
}
}
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);
}
});
}
}
}