blob: 61e51bef75e6a8975b0a41efe0c9f263a5565a51 [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.naming.applymapping;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
// AbstractChecker -> X:
abstract class AbstractChecker {
// String tag -> p
private String tag = "PrivateInitialTag_AbstractChecker";
// check() -> x
private void check() {
System.out.println("AbstractChecker#check:" + tag);
}
// foo() -> a
protected void foo() {
check();
}
}
// ConcreteChecker -> Y:
class ConcreteChecker extends AbstractChecker {
// This should not be conflict with AbstractChecker#tag due to the access control.
// String tag -> q
private String tag = "PrivateInitialTag_ConcreteChecker";
ConcreteChecker(String tag){
this.tag = tag;
}
// This should not be conflict with AbstractChecker#check due to the access control.
// check() -> y
private void check() {
System.out.println("ConcreteChecker#check:" + tag);
}
// foo() -> a
@Override
protected void foo() {
super.foo();
check();
}
}
class MemberResolutionTestMain {
public static void main(String[] args) {
ConcreteChecker c = new ConcreteChecker("NewTag");
c.foo();
}
}
@RunWith(Parameterized.class)
public class MemberResolutionTest extends TestBase {
private final static List<Class> CLASSES = ImmutableList.of(
AbstractChecker.class, ConcreteChecker.class, MemberResolutionTestMain.class);
private Backend backend;
@Parameterized.Parameters(name = "Backend: {0}")
public static Collection<Backend> data() {
return Arrays.asList(Backend.values());
}
public MemberResolutionTest(Backend backend) {
this.backend = backend;
}
@Test
public void testPrivateMethodsWithSameName() throws Exception {
String pkg = this.getClass().getPackage().getName();
Path mapPath = temp.newFile("test-mapping.txt").toPath();
List<String> pgMap = ImmutableList.of(
pkg + ".AbstractChecker -> " + pkg + ".X:",
" java.lang.String tag -> p",
" void check() -> x",
" void foo() -> a",
pkg + ".ConcreteChecker -> " + pkg + ".Y:",
" java.lang.String tag -> q",
" void check() -> y",
" void foo() -> a"
);
FileUtils.writeTextFile(mapPath, pgMap);
AndroidApp app = readClasses(CLASSES);
R8Command.Builder builder = ToolHelper.prepareR8CommandBuilder(app, emptyConsumer(backend));
builder
.addProguardConfiguration(
ImmutableList.of(
keepMainProguardConfiguration(MemberResolutionTestMain.class),
// Do not turn on -allowaccessmodification
"-applymapping " + mapPath,
"-dontobfuscate"), // to use the renamed names in test-mapping.txt
Origin.unknown())
.addLibraryFiles(runtimeJar(backend));
AndroidApp processedApp =
ToolHelper.runR8(
builder.build(),
options -> {
options.enableInlining = false;
options.enableVerticalClassMerging = false;
});
String outputBefore = runOnJava(MemberResolutionTestMain.class);
String outputAfter = runOnVM(processedApp, MemberResolutionTestMain.class, backend);
assertEquals(outputBefore, outputAfter);
CodeInspector codeInspector = new CodeInspector(processedApp, mapPath);
ClassSubject base = codeInspector.clazz(AbstractChecker.class);
assertThat(base, isPresent());
FieldSubject p = base.field("java.lang.String", "tag");
assertThat(p, isPresent());
assertThat(p, isRenamed());
assertEquals("p", p.getFinalName());
MethodSubject x = base.method("void", "check", ImmutableList.of());
assertThat(x, isPresent());
assertThat(x, isRenamed());
assertEquals("x", x.getFinalName());
ClassSubject sub = codeInspector.clazz(ConcreteChecker.class);
assertThat(sub, isPresent());
FieldSubject q = sub.field("java.lang.String", "tag");
assertThat(q, isPresent());
assertThat(q, isRenamed());
assertEquals("q", q.getFinalName());
MethodSubject y = sub.method("void", "check", ImmutableList.of());
assertThat(y, isPresent());
assertThat(y, isRenamed());
assertEquals("y", y.getFinalName());
}
}