blob: 30dc93f05bbb619cd31e42718a6532262ad10029 [file] [log] [blame]
// Copyright (c) 2021, 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.desugar.nestaccesscontrol;
import static com.android.tools.r8.TestRuntime.getCheckedInJdk11;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.desugar.nestaccesscontrol.methodparameters.Outer;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class MethodParametersTest extends TestBase {
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
// java.lang.reflect.Method.getParameters() supported from Android 8.1.
return getTestParameters()
.withDexRuntimesStartingFromIncluding(Version.V8_1_0)
.withCfRuntimes()
.withAllApiLevelsAlsoForCf()
.build();
}
public MethodParametersTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void test() throws Exception {
// Compile with javac from JDK 11 to get a class file using nest access control.
Path nestCompiledWithParameters =
javac(getCheckedInJdk11())
.addSourceFiles(ToolHelper.getSourceFileForTestClass(Outer.class))
.addOptions("-parameters")
.compile();
Path nestDesugared =
testForD8(Backend.CF)
.addProgramFiles(nestCompiledWithParameters)
.setMinApi(parameters.getApiLevel())
.compile()
.assertNoMessages()
.inspect(this::verifyNoAnnotationsOnSyntheticConstructors)
.writeToZip();
Path nestDesugaredTwice =
testForD8(Backend.CF)
.addProgramFiles(nestDesugared)
.setMinApi(parameters.getApiLevel())
.compile()
.assertNoMessages()
.inspect(this::verifyNoAnnotationsOnSyntheticConstructors)
.writeToZip();
Path programDesugared =
testForD8(Backend.CF)
.addClasspathClasses(Outer.class)
.addInnerClasses(getClass())
.setMinApi(parameters.getApiLevel())
.compile()
.assertNoMessages()
.writeToZip();
testForD8(parameters.getBackend())
.addProgramFiles(nestDesugaredTwice)
.addProgramFiles(programDesugared)
.setMinApi(parameters.getApiLevel())
.compile()
.assertNoMessages()
.inspect(this::verifyNoAnnotationsOnSyntheticConstructors)
.run(parameters.getRuntime(), TestRunner.class)
// Order of constructors is different on dex due to sorting.
.applyIf(
parameters.isCfRuntime(),
result ->
result.assertSuccessWithOutputLines(
"int, int, Outer$Inner-IA, 3",
"int, Outer$Inner-IA, 2",
"Outer$Inner-IA, 1",
"int, int, 2",
"int, 1",
"0"),
result ->
result.assertSuccessWithOutputLines(
"0",
"int, 1",
"int, int, 2",
"int, int, Outer$Inner-IA, 3",
"int, Outer$Inner-IA, 2",
"Outer$Inner-IA, 1"));
}
@Test
public void testJavacBridges() throws Exception {
assumeTrue(parameters.useRuntimeAsNoneRuntime());
verifyNoAnnotationsOnSyntheticConstructors(
new CodeInspector(ToolHelper.getClassFileForTestClass(Outer.Inner.class)));
}
private void verifyNoAnnotationsOnSyntheticConstructors(CodeInspector inspector) {
ClassSubject innerClassSubject = inspector.clazz(Outer.Inner.class);
List<FoundMethodSubject> syntheticInitializers =
innerClassSubject.allMethods(
method -> method.isInstanceInitializer() && method.isSynthetic());
assertEquals(3, syntheticInitializers.size());
syntheticInitializers.forEach(
syntheticInitializer ->
assertTrue(
syntheticInitializer.getProgramMethod().getDefinition().annotations().isEmpty()));
}
static class TestRunner {
public static void main(String[] args) {
Outer.callPrivateInnerConstructorZeroArgs();
}
}
}