blob: c007ec31800c158da4d839207bf5514156fae187 [file] [log] [blame]
// Copyright (c) 2025, 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.TestBase.descriptor;
import static com.android.tools.r8.TestBase.testForD8;
import static com.android.tools.r8.TestBase.writeClassesToJar;
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.benchmarks.BenchmarkResults;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class AssistantTestBuilder
extends TestCompilerBuilder<
R8AssistantCommand,
R8AssistantCommand.Builder,
AssistantTestCompileResult,
AssistantTestRunResult,
AssistantTestBuilder> {
private final D8TestBuilder initialCompileBuilder;
private Path output;
private String customReflectiveOperationReceiver = null;
private List<Class<?>> customReflectiveOperationInputClasses = new ArrayList<>();
private AssistantTestBuilder(TestState state) {
super(state, R8AssistantCommand.builder(state.getDiagnosticsHandler()), Backend.DEX);
initialCompileBuilder = testForD8(state.getTempFolder());
}
public static AssistantTestBuilder create(TestState state) {
return new AssistantTestBuilder(state);
}
@Override
AssistantTestBuilder self() {
return this;
}
@Override
public AssistantTestBuilder addClasspathClasses(Collection<Class<?>> classes) {
throw new Unimplemented("No classpath for assistant");
}
@Override
public AssistantTestBuilder addClasspathFiles(Collection<Path> files) {
throw new Unimplemented("No classpath for assistant");
}
public AssistantTestBuilder addInstrumentationClasses(Class<?>... classes) {
Collections.addAll(customReflectiveOperationInputClasses, classes);
return self();
}
@Override
public AssistantTestBuilder addProgramFiles(Collection<Path> files) {
initialCompileBuilder.addProgramFiles(files);
return self();
}
@Override
AssistantTestCompileResult internalCompile(
R8AssistantCommand.Builder builder,
Consumer<InternalOptions> optionsConsumer,
Supplier<AndroidApp> app,
BenchmarkResults benchmarkResults)
throws CompilationFailedException {
Path initialCompilation;
try {
initialCompilation = initialCompileBuilder.setMinApi(getMinApiLevel()).compile().writeToZip();
if (output == null) {
output = getState().getNewTempFile("assistant_output.jar");
}
if (!customReflectiveOperationInputClasses.isEmpty()) {
builder.addReflectiveOperationReceiverInput(
ArchiveProgramResourceProvider.fromArchive(
writeClassesToJar(customReflectiveOperationInputClasses)));
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
builder
.addProgramFiles(initialCompilation)
.setOutput(output, OutputMode.DexIndexed)
.setMinApiLevel(getMinApiLevel());
if (customReflectiveOperationReceiver != null) {
builder.setReflectiveReceiverClassDescriptor(customReflectiveOperationReceiver);
}
R8Assistant.run(builder.build());
return new AssistantTestCompileResult(
initialCompilation,
getState(),
AndroidApp.builder().addProgramFiles(output).build(),
getMinApiLevel());
}
public AssistantTestBuilder setCustomReflectiveOperationReceiver(
String customReflectiveOperationReceiver) {
this.customReflectiveOperationReceiver = customReflectiveOperationReceiver;
return self();
}
public AssistantTestBuilder setCustomReflectiveOperationReceiver(
Class<?> customReflectiveOperationReceiver) {
this.customReflectiveOperationReceiver = descriptor(customReflectiveOperationReceiver);
return self();
}
}