blob: 00318856de3f2a5ad33dfaca547e6f80d4ab9763 [file] [log] [blame]
// Copyright (c) 2020, 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.inspection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.inspector.Inspector;
import com.android.tools.r8.inspector.ValueInspector;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class FieldValueTypesInspectionTest extends TestBase {
static final String EXPECTED =
StringUtils.lines(
"" + TestClass.z,
"" + TestClass.b,
"" + TestClass.c,
"" + TestClass.s,
"" + TestClass.i,
"" + TestClass.j,
"" + TestClass.f,
"" + TestClass.d,
"foo");
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public FieldValueTypesInspectionTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testD8() throws Exception {
if (parameters.isCfRuntime()) {
testForJvm()
.addProgramClasses(TestClass.class)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
return;
}
testForD8()
.addProgramClasses(TestClass.class)
.setMinApi(parameters.getApiLevel())
.apply(b -> b.getBuilder().addOutputInspection(this::inspection))
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
assertFound();
}
@Test
public void testR8() throws Exception {
testForR8(parameters.getBackend())
.addProgramClasses(TestClass.class)
.addKeepClassAndMembersRules(TestClass.class)
.setMinApi(parameters.getApiLevel())
.apply(b -> b.getBuilder().addOutputInspection(this::inspection))
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
assertFound();
}
private int foundFields = 0;
private void inspection(Inspector inspector) {
inspector.forEachClass(
classInspector -> {
classInspector.forEachField(
fieldInspector -> {
foundFields++;
FieldReference reference = fieldInspector.getFieldReference();
ValueInspector value = fieldInspector.getInitialValue().get();
assertEquals(reference.getFieldType(), value.getTypeReference());
String name = reference.getFieldName();
boolean isBoolean = name.equals("z");
boolean isByte = name.equals("b");
boolean isChar = name.equals("c");
boolean isShort = name.equals("s");
boolean isInt = name.equals("i");
boolean isLong = name.equals("j");
boolean isFloat = name.equals("f");
boolean isDouble = name.equals("d");
boolean isString = name.equals("str");
assertEquals(isBoolean, value.isBooleanValue());
assertEquals(isByte, value.isByteValue());
assertEquals(isChar, value.isCharValue());
assertEquals(isShort, value.isShortValue());
assertEquals(isInt, value.isIntValue());
assertEquals(isLong, value.isLongValue());
assertEquals(isFloat, value.isFloatValue());
assertEquals(isDouble, value.isDoubleValue());
assertEquals(isString, value.isStringValue());
if (isBoolean) {
assertEquals(Reference.BOOL, reference.getFieldType());
assertEquals(TestClass.z, value.asBooleanValue().getBooleanValue());
} else {
assertNull(value.asBooleanValue());
}
if (isByte) {
assertEquals(Reference.BYTE, reference.getFieldType());
assertEquals(TestClass.b, value.asByteValue().getByteValue());
} else {
assertNull(value.asByteValue());
}
if (isChar) {
assertEquals(Reference.CHAR, reference.getFieldType());
assertEquals(TestClass.c, value.asCharValue().getCharValue());
} else {
assertNull(value.asCharValue());
}
if (isShort) {
assertEquals(Reference.SHORT, reference.getFieldType());
assertEquals(TestClass.s, value.asShortValue().getShortValue());
} else {
assertNull(value.asShortValue());
}
if (isInt) {
assertEquals(Reference.INT, reference.getFieldType());
assertEquals(TestClass.i, value.asIntValue().getIntValue());
} else {
assertNull(value.asIntValue());
}
if (isLong) {
assertEquals(Reference.LONG, reference.getFieldType());
assertEquals(TestClass.j, value.asLongValue().getLongValue());
} else {
assertNull(value.asLongValue());
}
if (isFloat) {
assertEquals(Reference.FLOAT, reference.getFieldType());
assertEquals(
Float.floatToRawIntBits(TestClass.f),
Float.floatToRawIntBits(value.asFloatValue().getFloatValue()));
} else {
assertNull(value.asFloatValue());
}
if (isDouble) {
assertEquals(Reference.DOUBLE, reference.getFieldType());
assertEquals(
Double.doubleToRawLongBits(TestClass.d),
Double.doubleToRawLongBits(value.asDoubleValue().getDoubleValue()));
} else {
assertNull(value.asDoubleValue());
}
if (isString) {
assertEquals(Reference.classFromClass(String.class), reference.getFieldType());
assertEquals(TestClass.str, value.asStringValue().getStringValue());
} else {
assertNull(value.asStringValue());
}
});
});
}
private void assertFound() {
assertEquals(9, foundFields);
}
static class TestClass {
public static final boolean z = true;
public static final byte b = 2;
public static final char c = 4;
public static final short s = 8;
public static final int i = 16;
public static final long j = 32L;
public static final float f = 64.1F;
public static final double d = 128.1D;
public static final String str = "foo";
public static void main(String[] args) {
System.out.println(z);
System.out.println(b);
System.out.println(c);
System.out.println(s);
System.out.println(i);
System.out.println(j);
System.out.println(f);
System.out.println(d);
System.out.println(str);
}
}
}