package org.eclipse.dltk.javascript.core.tests.typeinfo;
import static java.util.Collections.singletonList;
import static org.eclipse.dltk.javascript.typeinfo.model.TypeInfoModelFactory.eINSTANCE;
import java.lang.reflect.Field;
import java.util.Collections;
import junit.framework.TestCase;
import org.eclipse.dltk.internal.javascript.ti.TypeSystemImpl;
import org.eclipse.dltk.javascript.core.Types;
import org.eclipse.dltk.javascript.typeinfo.IRMethod;
import org.eclipse.dltk.javascript.typeinfo.IRProperty;
import org.eclipse.dltk.javascript.typeinfo.IRTypeDeclaration;
import org.eclipse.dltk.javascript.typeinfo.ITypeSystem;
import org.eclipse.dltk.javascript.typeinfo.RTypeMemberQuery;
import org.eclipse.dltk.javascript.typeinfo.RTypeVariable;
import org.eclipse.dltk.javascript.typeinfo.RTypes;
import org.eclipse.dltk.javascript.typeinfo.TypeUtil;
import org.eclipse.dltk.javascript.typeinfo.model.GenericType;
import org.eclipse.dltk.javascript.typeinfo.model.Method;
import org.eclipse.dltk.javascript.typeinfo.model.Parameter;
import org.eclipse.dltk.javascript.typeinfo.model.ParameterizedType;
import org.eclipse.dltk.javascript.typeinfo.model.Property;
import org.eclipse.dltk.javascript.typeinfo.model.Type;
import org.eclipse.dltk.javascript.typeinfo.model.TypeVariable;
@SuppressWarnings("restriction")
public class TypeParameterizerTests extends TestCase {
private ITypeSystem typeSystem;
@Override
protected void setUp() throws Exception {
super.setUp();
this.typeSystem = new TypeSystemImpl();
}
public void testGenericConvert() {
final IRTypeDeclaration declaration = typeSystem.convert(Types.ARRAY);
final RTypeMemberQuery memberQuery = new RTypeMemberQuery(declaration);
{
final IRMethod pop = (IRMethod) memberQuery.findMember("pop");
assertNotNull(pop);
assertTrue(pop.getType() instanceof RTypeVariable);
}
{
final IRMethod push = (IRMethod) memberQuery.findMember("push");
assertNotNull(push);
assertEquals(RTypes.NUMBER, push.getType());
assertEquals(1, push.getParameterCount());
assertTrue(push.getParameters().get(0).getType() instanceof RTypeVariable);
}
}
public void testParameterize() {
final IRTypeDeclaration declaration = typeSystem.parameterize(
Types.ARRAY, Collections.singletonList(RTypes.STRING));
{
final IRMethod pop = declaration.findMethod("pop", false);
assertNotNull(pop);
assertEquals(RTypes.STRING, pop.getType());
}
{
final IRMethod push = declaration.findMethod("push", false);
assertNotNull(push);
assertEquals(RTypes.simple(typeSystem, Types.NUMBER),
push.getType());
assertEquals(1, push.getParameterCount());
assertEquals(RTypes.STRING, push.getParameters().get(0).getType());
}
{
final IRMethod filter = declaration.findMethod("filter", false);
assertNotNull(filter);
assertEquals(RTypes.arrayOf(typeSystem, RTypes.STRING),
filter.getType());
assertEquals(1, filter.getParameterCount());
assertEquals(RTypes.FUNCTION, filter.getParameters().get(0)
.getType());
}
}
public void testParameterizedEquals() {
final IRTypeDeclaration arrayOfString = typeSystem.parameterize(
Types.ARRAY, singletonList(RTypes.STRING));
final IRTypeDeclaration arrayOfNumber = typeSystem.parameterize(
Types.ARRAY, singletonList(RTypes.NUMBER));
assertFalse(arrayOfString.equals(arrayOfNumber));
assertFalse(arrayOfNumber.equals(arrayOfString));
}
public void testSimpleTypeEquals() {
final GenericType listType = eINSTANCE.createGenericType();
listType.setName("List");
final TypeVariable variable = eINSTANCE.createTypeVariable();
variable.setName("T");
listType.getTypeParameters().add(variable);
final IRTypeDeclaration numberList = typeSystem.parameterize(listType,
Collections.singletonList(RTypes.NUMBER));
final IRTypeDeclaration stringList = typeSystem.parameterize(listType,
Collections.singletonList(RTypes.STRING));
assertFalse((RTypes.simple(numberList)).equals(RTypes
.simple(stringList)));
assertFalse((RTypes.classType(numberList)).equals(RTypes
.classType(stringList)));
}
public void testParameterizeGenericSuperType() {
final GenericType collection = eINSTANCE.createGenericType();
collection.setName("Collection");
final TypeVariable variable = eINSTANCE.createTypeVariable();
variable.setName("T");
collection.getTypeParameters().add(variable);
final Method getItem = eINSTANCE.createMethod();
getItem.setName("getItem");
{
final Parameter parameter = eINSTANCE.createParameter();
parameter.setName("index");
parameter.setType(TypeUtil.ref(Types.NUMBER));
getItem.getParameters().add(parameter);
}
getItem.setType(TypeUtil.reference(variable));
collection.getMembers().add(getItem);
final Type stringList = eINSTANCE.createType();
stringList.setName("StringList");
{
final ParameterizedType superType = eINSTANCE
.createParameterizedType();
superType.setTarget(collection);
superType.getActualTypeArguments().add(TypeUtil.ref(Types.STRING));
stringList.setSuperTypeExpr(superType);
}
final IRTypeDeclaration stringListDeclaration = typeSystem
.convert(stringList);
final IRTypeDeclaration collectionDeclaration = stringListDeclaration
.getSuperType();
assertTrue(collectionDeclaration.isParameterized());
assertEquals(1, collectionDeclaration.getActualTypeArguments().size());
assertEquals(RTypes.STRING, collectionDeclaration
.getActualTypeArguments().get(0));
}
public void testLazyPropertyType() throws Exception {
final GenericType holder = eINSTANCE.createGenericType();
holder.setName("Holder");
final TypeVariable variable = eINSTANCE.createTypeVariable();
variable.setName("T");
holder.getTypeParameters().add(variable);
final Property value = eINSTANCE.createProperty();
value.setName("value");
value.setType(TypeUtil.reference(variable));
holder.getMembers().add(value);
final IRTypeDeclaration declaration = typeSystem.parameterize(holder,
Collections.singletonList(RTypes.STRING));
final RTypeMemberQuery memberQuery = new RTypeMemberQuery(declaration);
final IRProperty prop = (IRProperty) memberQuery.findMember("value");
assertNotNull(prop);
final Field initialized = getField(prop.getClass(), "initialized");
initialized.setAccessible(true);
assertFalse((Boolean) initialized.get(prop));
assertEquals(RTypes.STRING, prop.getType());
assertTrue((Boolean) initialized.get(prop));
}
private static Field getField(Class<?> clazz, String fieldName)
throws NoSuchFieldException {
for (;;) {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
if (clazz == null) {
throw e;
}
}
}
}
public void testX() throws Exception {
final Type amount = eINSTANCE.createType();
amount.setName("Amount");
final ITypeSystem globalTS = RTypes.OBJECT.getDeclaration()
.getTypeSystem();
final IRTypeDeclaration declaration = globalTS.parameterize(
Types.ARRAY,
Collections.singletonList(RTypes.simple(typeSystem, amount)));
// System.out.println(declaration.getTypeSystem().getPrimary());
}
}