blob: 118a75a6da77ea9ff07aa08430ef5b179d3198c5 [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.ir.analysis.type;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import java.util.Arrays;
import org.junit.BeforeClass;
import org.junit.Test;
public class TypeLatticeTest {
private static final String IO_EXCEPTION = "Ljava/io/IOException;";
private static final String NOT_FOUND = "Ljava/io/FileNotFoundException;";
private static final String INTERRUPT = "Ljava/io/InterruptedIOException;";
private static DexItemFactory factory;
private static AppInfoWithSubtyping appInfo;
@BeforeClass
public static void makeAppInfo() throws Exception {
InternalOptions options = new InternalOptions();
DexApplication application =
new ApplicationReader(
AndroidApp.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.build(),
options,
new Timing(TypeLatticeTest.class.getName()))
.read()
.toDirect();
factory = options.itemFactory;
appInfo = new AppInfoWithSubtyping(application);
}
private Top top() {
return Top.getInstance();
}
private Bottom bottom() {
return Bottom.getInstance();
}
private TypeLatticeElement element(DexType type) {
return TypeLatticeElement.fromDexType(type, true);
}
private ArrayTypeLatticeElement array(int nesting, DexType base) {
return (ArrayTypeLatticeElement) element(factory.createArrayType(nesting, base));
}
private TypeLatticeElement join(TypeLatticeElement... elements) {
assertTrue(elements.length > 1);
return TypeLatticeElement.join(appInfo, Arrays.stream(elements));
}
private boolean strictlyLessThan(TypeLatticeElement l1, TypeLatticeElement l2) {
return TypeLatticeElement.strictlyLessThan(appInfo, l1, l2);
}
private boolean lessThanOrEqual(TypeLatticeElement l1, TypeLatticeElement l2) {
return TypeLatticeElement.lessThanOrEqual(appInfo, l1, l2);
}
@Test
public void joinTopIsTop() {
assertEquals(
top(),
join(element(factory.stringType), element(factory.stringBuilderType), top()));
assertEquals(
top(),
join(top(), element(factory.stringType), element(factory.stringBuilderType)));
assertEquals(
top(),
join(element(factory.stringType), top(), element(factory.stringBuilderType)));
}
@Test
public void joinBottomIsUnit() {
assertEquals(
element(factory.objectType),
join(element(factory.stringType), element(factory.stringBuilderType), bottom()));
assertEquals(
element(factory.objectType),
join(bottom(), element(factory.stringType), element(factory.stringBuilderType)));
assertEquals(
element(factory.objectType),
join(element(factory.stringType), bottom(), element(factory.stringBuilderType)));
}
@Test
public void joinClassTypes() {
assertEquals(
element(factory.objectType),
join(element(factory.stringType), element(factory.stringBuilderType)));
}
@Test
public void joinToNonJavaLangObject() {
assertEquals(
element(factory.createType(IO_EXCEPTION)),
join(
element(factory.createType(NOT_FOUND)),
element(factory.createType(INTERRUPT))));
}
@Test
public void joinSamePrimitiveArrays() {
assertEquals(
array(3, factory.intType),
join(
array(3, factory.intType),
array(3, factory.intType)));
}
@Test
public void joinDistinctTypesPrimitiveArrays() {
assertEquals(
array(2, factory.objectType),
join(
array(3, factory.intType),
array(3, factory.floatType)));
}
@Test
public void joinDistinctTypesNestingOnePrimitiveArrays() {
assertEquals(
element(factory.objectType),
join(
array(1, factory.intType),
array(1, factory.floatType)));
}
@Test
public void joinDistinctTypesNestingOneRightPrimitiveArrays() {
assertEquals(
element(factory.objectType),
join(
array(5, factory.intType),
array(1, factory.floatType)));
}
@Test
public void joinDistinctTypesNestingOneLeftPrimitiveArrays() {
assertEquals(
element(factory.objectType),
join(
array(1, factory.intType),
array(5, factory.floatType)));
}
@Test
public void joinDistinctNestingPrimitiveArrays() {
assertEquals(
array(2, factory.objectType),
join(
array(3, factory.intType),
array(4, factory.intType)));
}
@Test
public void joinPrimitiveAndClassArrays() {
assertEquals(
array(3, factory.objectType),
join(
array(4, factory.intType),
array(3, factory.stringType)));
}
@Test
public void joinSameClassArrays() {
assertEquals(
array(3, factory.stringType),
join(
array(3, factory.stringType),
array(3, factory.stringType)));
}
@Test
public void joinDistinctTypesClassArrays() {
assertEquals(
array(3, factory.objectType),
join(
array(3, factory.stringType),
array(3, factory.stringBuilderType)));
}
@Test
public void joinDistinctNestingClassArrays() {
assertEquals(
array(3, factory.objectType),
join(
array(3, factory.stringType),
array(4, factory.stringType)));
}
@Test
public void testPartialOrders() {
assertTrue(lessThanOrEqual(
element(factory.objectType),
element(factory.objectType)));
assertFalse(strictlyLessThan(
element(factory.objectType),
element(factory.objectType)));
assertTrue(strictlyLessThan(
element(factory.createType(NOT_FOUND)),
element(factory.createType(IO_EXCEPTION))));
assertTrue(strictlyLessThan(
element(factory.createType(INTERRUPT)),
element(factory.createType(IO_EXCEPTION))));
assertFalse(lessThanOrEqual(
element(factory.createType(NOT_FOUND)),
element(factory.createType(INTERRUPT))));
assertFalse(lessThanOrEqual(
element(factory.createType(INTERRUPT)),
element(factory.createType(NOT_FOUND))));
assertTrue(strictlyLessThan(
array(1, factory.stringType),
array(1, factory.objectType)));
assertFalse(lessThanOrEqual(
array(1, factory.stringType),
array(2, factory.objectType)));
assertTrue(strictlyLessThan(
array(2, factory.stringType),
array(1, factory.objectType)));
assertFalse(lessThanOrEqual(
array(3, factory.stringType),
array(4, factory.stringType)));
assertFalse(lessThanOrEqual(
array(4, factory.stringType),
array(3, factory.stringType)));
assertTrue(strictlyLessThan(
array(2, factory.objectType),
array(1, factory.objectType)));
assertTrue(strictlyLessThan(
NullLatticeElement.getInstance(),
array(1, factory.classType)));
}
}