blob: f4ac73f690c55737381fc738ddefae3ee9aafd2d [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs;
import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JTypeOracle;
import com.google.gwt.dev.jjs.ast.JTypeOracle.ImmediateTypeRelations;
import com.google.gwt.dev.jjs.ast.JTypeOracle.StandardTypes;
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import junit.framework.TestCase;
import org.junit.Assert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Test basic operations on the types used by the JJS compiler. See
* {@link com.google.gwt.dev.jjs.ast.JType}.
*/
public class JjsTypeTest extends TestCase {
private JArrayType arrayOfA;
private JArrayType arrayOfArrayOfB;
private JReferenceType arrayOfArrayOfInt;
private JArrayType arrayOfB;
private JArrayType arrayOfBase;
private JArrayType arrayOfBSub;
private JArrayType arrayOfJso1;
private JArrayType arrayOfJso2;
private JArrayType arrayOfIntfJ;
private JArrayType arrayOfIntfK;
private JArrayType arrayOfJso;
private JArrayType arrayOfC;
private JArrayType arrayOfIntfSerializable;
private JArrayType arrayOfIntfClonable;
private JReferenceType arrayOfInt;
private JArrayType arrayOfIntfI;
private JArrayType arrayOfIntfIBase;
private JArrayType arrayOfObject;
private JClassType classA;
private JClassType classArrayList;
private JClassType classB;
private JClassType classBase;
private JReferenceType classBaseNn;
private JReferenceType classBnn;
private JClassType classBSub;
private JClassType classC;
private JClassType classJso;
private JClassType classJso1;
private JClassType classJso2;
private JClassType classFinalJso1;
private JClassType classFinalJso2;
private JClassType classObject;
private JClassType classString;
private JReferenceType intfCloneable;
private JInterfaceType intfCollection;
private JInterfaceType intfI;
private JInterfaceType intfIBase;
private JInterfaceType intfIterable;
private JInterfaceType intfJ;
private JInterfaceType intfK;
private JInterfaceType intfL;
private JInterfaceType intfList;
private JReferenceType intfSerializable;
private JProgram program;
private SourceInfo synthSource;
private JReferenceType typeNull;
private JTypeOracle typeOracle;
private JArrayType arrayOfArrayOfBase;
private JArrayType arrayOfArrayOfObject;
private JArrayType arrayOfArrayOfIntfI;
private JArrayType arrayOfArrayOfIntfIBase;
private static final Collection<String> EMPTY_LIST = Collections.<String>emptySet();
public void testCrossCasts() {
JClassType[] jsoClasses =
new JClassType[] { classJso, classJso1, classJso2, classFinalJso1, classFinalJso2 };
for (JClassType thisJsoClass : jsoClasses) {
for (JClassType thatJsoClass : jsoClasses) {
assertCrossCasts(thisJsoClass, thatJsoClass);
}
}
}
public void testCastFailsTrivially() {
assertShouldFailTrivially(classBnn, typeNull);
assertShouldNotFailTrivially(classBSub, classB);
assertShouldNotFailTrivially(classB, classBSub);
assertShouldNotFailTrivially(classB, classBnn);
assertShouldNotFailTrivially(classBnn, classB);
assertShouldNotFailTrivially(classB, classB);
assertShouldNotFailTrivially(classObject, arrayOfB);
assertShouldFailTrivially(arrayOfA, arrayOfArrayOfB);
assertShouldNotFailTrivially(arrayOfObject, arrayOfArrayOfB);
assertShouldNotFailTrivially(arrayOfB, arrayOfBSub);
assertShouldNotFailTrivially(classBase, intfI);
assertShouldFailTrivially(classA, intfJ);
assertShouldNotFailTrivially(intfIBase, intfI);
assertShouldNotFailTrivially(intfIBase, classBase);
assertShouldFailTrivially(intfJ, classA);
assertShouldNotFailTrivially(arrayOfA, intfSerializable);
assertShouldNotFailTrivially(intfSerializable, arrayOfA);
assertShouldNotFailTrivially(arrayOfA, intfCloneable);
assertShouldNotFailTrivially(intfCloneable, arrayOfA);
assertShouldNotFailTrivially(intfList, intfIterable);
assertShouldNotFailTrivially(classArrayList, intfIterable);
assertShouldNotFailTrivially(classJso1, classJso2);
assertShouldNotFailTrivially(classJso2, classJso1);
assertShouldNotFailTrivially(classJso1, intfK);
assertShouldNotFailTrivially(intfK, classJso1);
assertShouldNotFailTrivially(intfJ, intfK);
assertShouldNotFailTrivially(intfK, intfJ);
assertShouldNotFailTrivially(classB, intfL);
assertShouldFailTrivially(classB.strengthenToExact(), intfL);
}
public void testCastSucceedsTrivially() {
assertShouldSucceedTrivially(classB, classB);
assertShouldSucceedTrivially(classBSub, classB);
assertShouldNotSucceedTrivially(classB, classBSub);
assertShouldNotSucceedTrivially(classC, classA);
assertShouldNotSucceedTrivially(classA, classC);
assertShouldSucceedTrivially(classB, intfI);
assertShouldNotSucceedTrivially(intfI, classB);
assertShouldSucceedTrivially(classB, classObject);
assertShouldNotSucceedTrivially(classObject, classB);
assertShouldSucceedTrivially(classB, intfI);
assertShouldNotSucceedTrivially(intfI, classB);
assertShouldSucceedTrivially(classBnn, classB);
assertShouldNotSucceedTrivially(classB, classBnn);
assertShouldSucceedTrivially(typeNull, classB);
assertShouldNotSucceedTrivially(classB, typeNull);
assertShouldSucceedTrivially(arrayOfA, classObject);
assertShouldSucceedTrivially(arrayOfBSub, arrayOfB);
assertShouldNotSucceedTrivially(arrayOfB, arrayOfBSub);
assertShouldNotSucceedTrivially(arrayOfA, arrayOfB);
assertShouldNotSucceedTrivially(arrayOfB, arrayOfA);
assertShouldNotSucceedTrivially(arrayOfArrayOfB, arrayOfB);
assertShouldNotSucceedTrivially(arrayOfB, arrayOfArrayOfB);
assertShouldSucceedTrivially(arrayOfArrayOfB, arrayOfObject);
assertShouldNotSucceedTrivially(arrayOfObject, arrayOfArrayOfB);
assertShouldSucceedTrivially(classJso1, classJso);
assertShouldSucceedTrivially(arrayOfA, intfSerializable);
assertShouldNotSucceedTrivially(intfSerializable, arrayOfA);
assertShouldSucceedTrivially(arrayOfA, intfCloneable);
assertShouldNotSucceedTrivially(intfCloneable, arrayOfA);
/*
* Test that two types cannot both be trivially castable to each other,
* unless they are the same type.
*/
for (JReferenceType type1 : severalTypes()) {
for (JReferenceType type2 : severalTypes()) {
if (type1 != type2) {
assertFalse(type1.toString() + " and " + type2 + " should not be castable to each other",
typeOracle.castSucceedsTrivially(type1, type2)
&& typeOracle.castSucceedsTrivially(type2, type1));
}
}
}
}
public void testGeneralizeTypes() {
assertSame(classA, generalizeTypes(classA, classA));
assertSame(classB, generalizeTypes(classB, classBnn));
assertSame(classB, generalizeTypes(classBnn, classB));
assertSame(classBaseNn, generalizeTypes(classBnn, classBaseNn));
assertSame(classB, generalizeTypes(classB, typeNull));
assertSame(classB, generalizeTypes(typeNull, classB));
assertSame(intfIBase, generalizeTypes(intfI, intfIBase));
assertSame(intfIBase, generalizeTypes(intfIBase, intfI));
assertSame(classObject, generalizeTypes(intfJ, intfI));
assertSame(classObject, generalizeTypes(arrayOfB, arrayOfInt));
assertSame(classObject, generalizeTypes(arrayOfC, arrayOfArrayOfB));
assertSame(arrayOfObject, generalizeTypes(arrayOfC, arrayOfB));
assertSame(arrayOfObject, generalizeTypes(arrayOfObject, arrayOfArrayOfInt));
assertSame(intfI, generalizeTypes(classB, intfI));
assertSame(classObject, generalizeTypes(classB, intfJ));
assertSame(classObject, generalizeTypes(intfI, arrayOfInt));
assertSame(intfSerializable, generalizeTypes(intfSerializable, arrayOfA));
assertSame(intfCloneable, generalizeTypes(intfCloneable, arrayOfA));
for (JReferenceType type1 : severalTypes()) {
for (JReferenceType type2 : severalTypes()) {
JReferenceType generalized = generalizeTypes(type1, type2);
assertShouldSucceedTrivially(type1, generalized);
assertShouldSucceedTrivially(type2, generalized);
}
}
}
public void testCastableDestinationTypes() {
assertCastableDestinationTypes(classObject, classObject);
assertCastableDestinationTypes(classString, classString, classObject);
assertCastableDestinationTypes(classJso, classJso, classObject);
assertCastableDestinationTypes(intfSerializable, intfSerializable, classObject);
assertCastableDestinationTypes(intfCloneable, intfCloneable, classObject);
assertCastableDestinationTypes(intfIBase, intfIBase, classObject);
assertCastableDestinationTypes(intfI, intfI, intfIBase, classObject);
assertCastableDestinationTypes(intfJ, intfJ, classObject);
assertCastableDestinationTypes(intfK, intfK, classObject);
assertCastableDestinationTypes(classBase, classBase, classObject);
assertCastableDestinationTypes(classA, classA, classObject, classBase);
assertCastableDestinationTypes(classB, classB, classObject, classBase, intfIBase, intfI);
assertCastableDestinationTypes(classC, classC, classObject, intfIBase, intfI);
assertCastableDestinationTypes(classBSub, classBSub, classObject, classBase, classB, intfIBase,
intfI, intfL);
assertCastableDestinationTypes(classJso1, classObject, classJso, intfJ);
assertCastableDestinationTypes(classJso2, classObject, classJso, intfK);
assertCastableDestinationTypes(arrayOfJso, classObject, intfCloneable, intfSerializable,
arrayOfJso, arrayOfObject);
assertCastableDestinationTypes(arrayOfJso1, classObject, intfCloneable, intfSerializable,
arrayOfJso, arrayOfObject, arrayOfIntfJ);
assertCastableDestinationTypes(arrayOfJso2, classObject, intfCloneable, intfSerializable,
arrayOfJso, arrayOfObject, arrayOfIntfK);
assertCastableDestinationTypes(intfIterable, intfIterable, classObject);
assertCastableDestinationTypes(intfCollection, intfCollection, intfIterable, classObject);
assertCastableDestinationTypes(intfList, intfList, intfIterable, intfCollection, classObject);
assertCastableDestinationTypes(classArrayList, classArrayList, intfList, classObject,
intfIterable,
intfCollection);
assertCastableDestinationTypes(arrayOfB, arrayOfB, arrayOfBase, arrayOfObject, arrayOfIntfI,
arrayOfIntfIBase, classObject, arrayOfObject, intfCloneable, intfSerializable);
assertCastableDestinationTypes(arrayOfArrayOfB, arrayOfArrayOfB, arrayOfArrayOfBase,
arrayOfArrayOfObject, arrayOfArrayOfIntfI, arrayOfArrayOfIntfIBase, classObject,
arrayOfObject, intfCloneable, arrayOfIntfClonable, intfSerializable,
arrayOfIntfSerializable);
assertCastableDestinationTypes(arrayOfInt, arrayOfInt, classObject, intfCloneable,
intfSerializable);
intfCollection = createInterface("java.util.Collection");
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(),
Sets.<JDeclaredType> newHashSet(classArrayList, intfList, intfCollection, classObject),
Lists.newArrayList(intfIterable.getName()));
assertCastableDestinationTypes(intfCollection, intfCollection, classObject);
assertCastableDestinationTypes(intfList, intfList, intfCollection, classObject);
assertCastableDestinationTypes(classArrayList, classArrayList, intfList, classObject,
intfCollection);
classA = createClass("A", classObject, false, false);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(),
Sets.<JDeclaredType> newHashSet(classA, classObject),
Lists.newArrayList(classBase.getName()));
assertCastableDestinationTypes(classA, classA, classObject);
JClassType classASub = createClass("ASub", classA, false, false);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(),
Sets.<JDeclaredType> newHashSet(classASub, classA, classObject),
EMPTY_LIST);
assertCastableDestinationTypes(classASub, classASub, classA, classObject);
}
public void testJavahSignatures() {
for (JReferenceType type : severalTypes()) {
assertSignaturesMatch(type,
new Function<JReferenceType, String>() {
@Override
public String apply(JReferenceType type) {
return type.getJavahSignatureName();
}
});
}
}
public void testJsniSignatures() {
for (JReferenceType type : severalTypes()) {
assertSignaturesMatch(type,
new Function<JReferenceType, String>() {
@Override
public String apply(JReferenceType type) {
return type.getJsniSignatureName();
}
});
}
}
public void testStrongerType() {
assertSame(classA, strongerType(classA, classA));
assertSame(classBnn, strongerType(classB, classBnn));
assertSame(classB, strongerType(classB, classBase));
assertSame(classB, strongerType(classBase, classB));
assertSame(intfI, strongerType(intfI, intfJ));
assertSame(arrayOfA, strongerType(intfSerializable, arrayOfA));
assertSame(arrayOfA, strongerType(intfCloneable, arrayOfA));
}
public void testUpdateTypeInformation_JSODualImpl() {
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), program.getModuleDeclaredTypes(), EMPTY_LIST);
Assert.assertFalse(program.typeOracle.isDualJsoInterface(intfJ));
JClassType javaIntfImplementor = createClass("JavaImplementor", classObject, false, false);
javaIntfImplementor.addImplements(intfJ);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), Sets.<JDeclaredType> newHashSet(javaIntfImplementor),
EMPTY_LIST);
Assert.assertTrue(program.typeOracle.isDualJsoInterface(intfJ));
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), Collections.<JDeclaredType> emptySet(),
Lists.newArrayList(javaIntfImplementor.getName()));
Assert.assertFalse(program.typeOracle.isDualJsoInterface(intfJ));
}
public void testUpdateTypeInformation_SubClasses() {
JClassType baseAll = createClass("IncrementalBaseAll", classObject, false, false);
JClassType sub1 = createClass("IncrementalSub1", baseAll, false, false);
JClassType sub2 = createClass("IncrementalSub2", baseAll, false, false);
JClassType sub1_2 = createClass("IncrementalSub1_2", sub1, false, false);
Assert.assertFalse(program.typeOracle.isSubClass(baseAll, sub1));
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), Sets.<JDeclaredType> newHashSet(baseAll, sub1, sub2, sub1_2),
EMPTY_LIST);
Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1));
Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub2));
Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1_2));
Assert.assertTrue(program.typeOracle.isSubClass(sub1, sub1_2));
sub1_2 = createClass("IncrementalSub1_2", baseAll, false, false);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), Sets.<JDeclaredType> newHashSet(baseAll, sub2, sub1_2),
Lists.newArrayList(sub1.getName()));
Assert.assertFalse(program.typeOracle.isSubClass(baseAll, sub1));
Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub2));
Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1_2));
}
public void testUpdateTypeInformation_SuperClasses() {
JClassType baseAll = createClass("IncrementalBaseAll", classObject, false, false);
JClassType sub1 = createClass("IncrementalSub1", baseAll, false, false);
JClassType sub2 = createClass("IncrementalSub2", baseAll, false, false);
JClassType sub1_2 = createClass("IncrementalSub1_2", sub1, false, false);
Assert.assertFalse(program.typeOracle.isSuperClass(sub1, baseAll));
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(),
Sets.<JDeclaredType>newHashSet(baseAll, sub1, sub2, sub1_2),
EMPTY_LIST);
Assert.assertTrue(program.typeOracle.isSuperClass(sub1, baseAll));
Assert.assertTrue(program.typeOracle.isSuperClass(sub2, baseAll));
Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, baseAll));
Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, sub1));
sub1_2 = createClass("IncrementalSub1_2", baseAll, false, false);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(),
Sets.<JDeclaredType>newHashSet(baseAll, sub2, sub1_2),
Lists.newArrayList(sub1.getName()));
Assert.assertFalse(program.typeOracle.isSuperClass(sub1, baseAll));
Assert.assertTrue(program.typeOracle.isSuperClass(sub2, baseAll));
Assert.assertFalse(program.typeOracle.isSuperClass(sub1_2, sub1));
Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, baseAll));
}
public void testTypeRelationsBeforeRecompute() {
// Construct a JTypeOracle with some previously cached type relations, but do not recompute();
MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
ImmediateTypeRelations immediateTypeRelations = minimalRebuildCache.getImmediateTypeRelations();
immediateTypeRelations.getImmediateSuperclassesByClass().put("Foo", "java.lang.Object");
JTypeOracle typeOracle = new JTypeOracle(null, minimalRebuildCache);
// Show that the typeOracle can already answer basic type relation questions.
assertEquals("java.lang.Object", typeOracle.getSuperTypeName("Foo"));
}
@Override
protected void setUp() {
createSampleProgram(new MinimalRebuildCache());
}
private void assertCastableDestinationTypes(JReferenceType type,
JReferenceType... superHierarchyTypes) {
assertEquals(Sets.<JReferenceType> newHashSet(superHierarchyTypes),
typeOracle.getCastableDestinationTypes(type));
}
private JClassType createClass(String className, JClassType superClass, boolean isAbstract,
boolean isFinal) {
JClassType x = new JClassType(synthSource, className, isAbstract, isFinal);
program.addType(x);
x.setSuperClass(superClass);
return x;
}
private JInterfaceType createInterface(String className) {
JInterfaceType x = new JInterfaceType(synthSource, className);
program.addType(x);
return x;
}
private void createSampleProgram(MinimalRebuildCache minimalRebuildCache) {
// Make the program itself
program = new JProgram(minimalRebuildCache);
typeOracle = program.typeOracle;
synthSource = SourceOrigin.UNKNOWN;
classObject = createClass("java.lang.Object", null, false, false);
classString = createClass("java.lang.String", classObject, false, true);
createClass("com.google.gwt.lang.Array", classObject, false, true);
classJso =
createClass("com.google.gwt.core.client.JavaScriptObject", classObject, false, false);
intfSerializable = createInterface("java.io.Serializable");
intfCloneable = createInterface("java.lang.Cloneable");
intfIBase = createInterface("IBase");
intfI = createInterface("I");
intfI.addImplements(intfIBase);
intfJ = createInterface("J");
intfK = createInterface("K");
intfL = createInterface("L");
classBase = createClass("Base", classObject, false, false);
classA = createClass("A", classBase, false, false);
classB = createClass("B", classBase, false, false);
classB.addImplements(intfI);
classC = createClass("C", classObject, false, false);
classC.addImplements(intfI);
classBSub = createClass("BSub", classB, false, false);
classBSub.addImplements(intfL);
classJso1 = createClass("Jso1", classJso, false, false);
classJso1.addImplements(intfJ);
classJso2 = createClass("Jso2", classJso, false, false);
classJso2.addImplements(intfK);
classFinalJso1 = createClass("FinalJso1", classJso, false, true);
classFinalJso2 = createClass("FinalJso2", classJso, false, true);
intfIterable = createInterface("java.util.Iterable");
intfCollection = createInterface("java.util.Collection");
intfCollection.addImplements(intfIterable);
intfList = createInterface("java.util.List");
intfList.addImplements(intfCollection);
classArrayList = createClass("java.util.ArrayList", classObject, false, false);
classArrayList.addImplements(intfList);
classBnn = classB.strengthenToNonNull();
classBaseNn = classBase.strengthenToNonNull();
// 1 dimensional
arrayOfObject = program.getTypeArray(classObject);
arrayOfBase = program.getTypeArray(classBase);
arrayOfA = program.getTypeArray(classA);
arrayOfB = program.getTypeArray(classB);
arrayOfBSub = program.getTypeArray(classBSub);
arrayOfIntfIBase = program.getTypeArray(intfIBase);
arrayOfIntfI = program.getTypeArray(intfI);
arrayOfC = program.getTypeArray(classC);
arrayOfInt = program.getTypeArray(program.getTypePrimitiveInt());
arrayOfJso = program.getTypeArray(classJso);
arrayOfJso1 = program.getTypeArray(classJso1);
arrayOfJso2 = program.getTypeArray(classJso2);
arrayOfIntfJ = program.getTypeArray(intfJ);
arrayOfIntfK = program.getTypeArray(intfK);
arrayOfIntfClonable = program.getTypeArray(intfCloneable);
arrayOfIntfSerializable = program.getTypeArray(intfSerializable);
// 2 dimensional
arrayOfArrayOfBase = program.getOrCreateArrayType(classBase, 2);
arrayOfArrayOfObject = program.getOrCreateArrayType(classObject, 2);
arrayOfArrayOfIntfI = program.getOrCreateArrayType(intfI, 2);
arrayOfArrayOfIntfIBase = program.getOrCreateArrayType(intfIBase, 2);
arrayOfArrayOfInt = program.getOrCreateArrayType(program.getTypePrimitiveInt(), 2);
arrayOfArrayOfB = program.getOrCreateArrayType(classB, 2);
program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
program.getDeclaredTypes(), program.getModuleDeclaredTypes(), EMPTY_LIST);
// Save off some miscellaneous types to test against
typeNull = JReferenceType.NULL_TYPE;
}
private JReferenceType strongerType(JReferenceType type1, JReferenceType type2) {
return program.strengthenType(type1, program.generalizeTypes(Arrays.asList(type2)));
}
private JReferenceType generalizeTypes(JReferenceType type1, JReferenceType type2) {
return program.strengthenType(program.getTypeJavaLangObject(),
program.generalizeTypes(Arrays.asList(type1, type2)));
}
private void assertCrossCasts(JClassType thisType, JClassType thatType) {
// Uncomment the following once the JSO/non-JSO semantics issue is sorted, Ideally
// castXXXTrivially should be more precise and include casting JSO types; however in the current
// architecture the results of these tests are used to remove casts and change return types
// which in turn might affect the liveness computation for JSOs.
//
// assertShouldSucceedTrivially(thisType, thatType));
// assertShouldSucceedTrivially(thatType, thisType));
assertShouldNotFailTrivially(thisType, thatType);
assertShouldNotFailTrivially(thatType, thisType);
assertTrue(typeOracle.canBeJavaScriptObject(thisType));
assertTrue(typeOracle.canBeJavaScriptObject(thatType));
}
private void assertShouldNotFailTrivially(JReferenceType thisType, JReferenceType thatType) {
assertFalse("Casting " + thisType + " to " + thatType + " should not fail trivially",
typeOracle.castFailsTrivially(thisType, thatType));
}
private void assertShouldFailTrivially(JReferenceType thisType, JReferenceType thatType) {
assertTrue("Casting " + thisType + " to " + thatType + " should fail trivially",
typeOracle.castFailsTrivially(thisType, thatType));
}
private void assertShouldNotSucceedTrivially(JReferenceType thisType, JReferenceType thatType) {
assertFalse("Casting " + thisType + " to " + thatType + " should not succeed trivially",
typeOracle.castSucceedsTrivially(thisType, thatType));
}
private void assertShouldSucceedTrivially(JReferenceType thisType, JReferenceType thatType) {
assertTrue("Casting " + thisType + " to " + thatType + " should succeed trivially",
typeOracle.castSucceedsTrivially(thisType, thatType));
}
private void assertSignaturesMatch(
JReferenceType type, Function<JReferenceType, String> signatureForType) {
if (type.isNullType()) {
return;
}
assertEquals(signatureForType.apply(type), signatureForType.apply(type.strengthenToNonNull()));
assertEquals(signatureForType.apply(type), signatureForType.apply(type.weakenToNullable()));
}
/**
* Return several types, for exhaustively testing basic properties.
*/
private Collection<JReferenceType> severalTypes() {
List<JReferenceType> types = new ArrayList<JReferenceType>();
types.add(arrayOfA);
types.add(arrayOfB);
types.add(arrayOfArrayOfB);
types.add(arrayOfBSub);
types.add(arrayOfObject);
types.add(classA);
types.add(classB);
types.add(classBSub);
types.add(classBnn);
types.add(classBase);
types.add(classC);
types.add(classObject);
types.add(classString);
types.add(intfI);
types.add(intfJ);
types.add(intfK);
types.add(intfIBase);
types.add(classJso1);
types.add(classJso2);
types.add(classJso);
types.add(typeNull);
return types;
}
}