blob: 6cc26a6d22e7d4d27568738cb10b00cd62e0701e [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.shaking.fields.shadow;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.shaking.fields.FieldsTestBase;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import org.junit.Test;
@NeverMerge
class Super {
public int f1;
}
@NeverMerge
class Sub extends Super {
public int f1;
}
@NeverMerge
class SubSub extends Sub {
public int f1;
}
class Main {
private static void printField(Class<?> clazz, String name) {
try {
clazz.getDeclaredField(name);
System.out.println(clazz.getSimpleName() + "." + name + " found");
} catch (NoSuchFieldException e) {
System.out.println(clazz.getSimpleName() + "." + name + " not found");
}
}
public static void main(String[] args) {
printField(Super.class, "f1");
printField(Sub.class, "f1");
printField(SubSub.class, "f1");
}
}
public class ShadowFieldsTest extends FieldsTestBase {
@Override
public Collection<Class<?>> getClasses() {
return ImmutableSet.of(Super.class, Sub.class, SubSub.class, getMainClass());
}
@Override
public Class<?> getMainClass() {
return Main.class;
}
private void checkAllFields(CodeInspector inspector) {
ClassSubject superSubject = inspector.clazz(Super.class);
assertThat(superSubject, isPresent());
assertThat(superSubject.field("int", "f1"), isPresent());
ClassSubject subSubject = inspector.clazz(Sub.class);
assertThat(subSubject, isPresent());
assertThat(subSubject.field("int", "f1"), isPresent());
ClassSubject subSubSubject = inspector.clazz(SubSub.class);
assertThat(subSubSubject, isPresent());
assertThat(subSubSubject.field("int", "f1"), isPresent());
}
@Override
public String allFieldsOutput() {
return StringUtils.lines("Super.f1 found", "Sub.f1 found", "SubSub.f1 found");
}
@Test
public void testKeepAllFieldsWithWildcard() throws Throwable {
runTest("-keep class **.SubSub { *; }", this::checkAllFields, allFieldsOutput());
}
@Test
public void testKeepAllFieldsWithNameWildcard() throws Throwable {
runTest("-keep class **.SubSub { int f*; }", this::checkAllFields, allFieldsOutput());
}
@Test
public void testKeepAllFieldsWithFields() throws Throwable {
runTest("-keep class **.SubSub { <fields>; }", this::checkAllFields, allFieldsOutput());
}
@Test
public void testKeepF1() throws Throwable {
runTest("-keep class **.SubSub { int f1; }", this::checkAllFields, allFieldsOutput());
}
@Test
public void testKeepF1WithExtends() throws Throwable {
runTest("-keep class * extends **.Sub { int f1; }", this::checkAllFields, allFieldsOutput());
}
}