blob: 5b00775715ff5871b0e961c9d1ccbe125e7f4af6 [file] [log] [blame]
// Copyright (c) 2022, 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.synthesis;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class SyntheticMarkerDexTest extends TestBase {
static final String EXPECTED = StringUtils.lines("Hello, world");
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withDefaultDexRuntime().withApiLevel(AndroidApiLevel.B).build();
}
public SyntheticMarkerDexTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void test() throws Exception {
Path out =
testForD8(parameters.getBackend())
.setMinApi(parameters.getApiLevel())
.setIntermediate(true)
.addProgramClasses(TestClass.class)
.compile()
.inspect(this::checkSyntheticClassIsMarked)
.writeToZip();
testForD8(parameters.getBackend())
.setMinApi(parameters.getApiLevel())
.addProgramFiles(out)
// Use intermediate again to preserve synthetics.
.setIntermediate(true)
// Disable desugaring so we are sure the lambda synthetic is created in the first round.
.disableDesugaring()
.compile()
.inspect(this::checkSyntheticClassIsMarked)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
}
private void checkSyntheticClassIsMarked(CodeInspector inspector) {
// Compilation gives rise to the main class plus one lambda.
assertEquals(2, inspector.allClasses().size());
inspector.forAllClasses(
clazz -> {
if (!clazz.getFinalReference().equals(Reference.classFromClass(TestClass.class))) {
// This should be the lambda class.
DexAnnotation[] annotations = clazz.getDexProgramClass().annotations().annotations;
assertEquals(1, annotations.length);
DexEncodedAnnotation annotation = annotations[0].annotation;
assertEquals(2, annotation.elements.length);
assertEquals(
"com.android.tools.r8.annotations.SynthesizedClassV2",
annotation.type.toSourceString());
}
});
}
public static class TestClass {
public static void run(Runnable r) {
r.run();
}
public static void main(String[] args) {
run(() -> System.out.println("Hello, world"));
}
}
}