blob: bda2ba8c54ab9a3eb3a2fbcd25808e2713ec006d [file] [log] [blame]
// Copyright (c) 2019, 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;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestShrinkerBuilder;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
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 java.nio.file.Path;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class UniqueFieldMemberNamesTest extends TestBase {
@ClassRule public static TemporaryFolder tempFolder = ToolHelper.getTemporaryFolderForTest();
private static Path programClassA;
private static Path programClassB;
@BeforeClass
public static void setup() throws Exception {
{
JasminBuilder builder = new JasminBuilder();
ClassBuilder classBuilder = builder.addClass("A", "java/lang/Object");
classBuilder.addField("public", "a", "Ljava/lang/Object;", null);
classBuilder.addField("public", "f", "Ljava/lang/Object;", null);
programClassA = tempFolder.getRoot().toPath().resolve("input.jar");
builder.writeJar(programClassA);
}
{
JasminBuilder builder = new JasminBuilder();
ClassBuilder classBuilder = builder.addClass("B", "java/lang/Object");
classBuilder.addField("public", "f", "Ljava/lang/Object;", null);
classBuilder.addField("public", "f", "Ljava/lang/String;", null);
programClassB = tempFolder.getRoot().toPath().resolve("library.jar");
builder.writeJar(programClassB);
}
}
@Test
public void testR8() throws Exception {
runTest(testForR8(Backend.DEX), true);
}
@Test
public void testR8WithLibrary() throws Exception {
runTestWithLibrary(testForR8(Backend.DEX), true);
}
@Test
public void testProguard() throws Exception {
runTest(testForProguard(), false);
}
@Test
public void testProguardWithLibrary() throws Exception {
runTestWithLibrary(testForProguard(), false);
}
private void runTest(TestShrinkerBuilder<?, ?, ?, ?, ?> builder, boolean isR8) throws Exception {
CodeInspector inspector =
builder
.addProgramFiles(programClassA, programClassB)
.addKeepRules("-useuniqueclassmembernames")
.addKeepRules("-keep class A { java.lang.Object a; }")
.noTreeShaking()
.compile()
.inspector();
ClassSubject aClassSubject = inspector.clazz("A");
assertThat(aClassSubject, isPresent());
ClassSubject bClassSubject = inspector.clazz("B");
assertThat(bClassSubject, isPresent());
FieldSubject fieldSubject1 = aClassSubject.field("java.lang.Object", "f");
assertThat(fieldSubject1, isPresent());
assertThat(fieldSubject1, isRenamed());
assertNotEquals("a", fieldSubject1.getFinalName());
FieldSubject fieldSubject2 = bClassSubject.field("java.lang.Object", "f");
assertThat(fieldSubject2, isPresent());
assertThat(fieldSubject2, isRenamed());
assertEquals(fieldSubject2.getFinalName(), fieldSubject1.getFinalName());
FieldSubject fieldSubject3 = bClassSubject.field("java.lang.String", "f");
assertThat(fieldSubject3, isPresent());
assertThat(fieldSubject3, isRenamed());
if (isR8) {
// TODO(b/128973195): Fields should be given distinct names due to -useuniqueclassmembernames.
assertEquals(fieldSubject2.getFinalName(), fieldSubject3.getFinalName());
} else {
assertNotEquals(fieldSubject2.getFinalName(), fieldSubject3.getFinalName());
}
}
private void runTestWithLibrary(TestShrinkerBuilder<?, ?, ?, ?, ?> builder, boolean isR8)
throws Exception {
CodeInspector inspector =
builder
.addProgramFiles(programClassB)
.addLibraryFiles(programClassA, runtimeJar(Backend.DEX))
.addKeepRules("-useuniqueclassmembernames")
.addKeepRules("-keep class A { java.lang.Object a; }")
.noTreeShaking()
.compile()
.inspector();
ClassSubject bClassSubject = inspector.clazz("B");
assertThat(bClassSubject, isPresent());
FieldSubject fieldSubject2 = bClassSubject.field("java.lang.Object", "f");
assertThat(fieldSubject2, isPresent());
assertThat(fieldSubject2, not(isRenamed()));
FieldSubject fieldSubject3 = bClassSubject.field("java.lang.String", "f");
assertThat(fieldSubject3, isPresent());
if (isR8) {
// TODO(b/128973195): Fields should be given distinct names due to -useuniqueclassmembernames.
assertThat(fieldSubject3, not(isRenamed()));
} else {
assertThat(fieldSubject3, isRenamed());
}
}
}