blob: d75d47b6b579166fe8e442b3f8772a49dd6a01c9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 NumberFour AG
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* NumberFour AG - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.javascript.internal.core;
import java.util.List;
import org.eclipse.dltk.internal.javascript.ti.IValue;
import org.eclipse.dltk.javascript.typeinfo.IRMember;
import org.eclipse.dltk.javascript.typeinfo.IRType;
import org.eclipse.dltk.javascript.typeinfo.IRTypeDeclaration;
import org.eclipse.dltk.javascript.typeinfo.ITypeSystem;
import org.eclipse.dltk.javascript.typeinfo.TypeCompatibility;
import org.eclipse.dltk.javascript.typeinfo.model.GenericType;
import org.eclipse.dltk.javascript.typeinfo.model.Type;
import org.eclipse.dltk.javascript.typeinfo.model.TypeVariable;
import org.eclipse.emf.common.util.EList;
public class RParameterizedTypeDeclaration extends RTypeDeclaration implements
ITypeSystem {
private final List<IRType> typeArguments;
public RParameterizedTypeDeclaration(ITypeSystem typeSystem,
GenericType type, List<IRType> typeArguments) {
super(typeSystem, type);
this.typeArguments = typeArguments;
}
@Override
protected ITypeSystem getEffectiveTypeSystem() {
return this;
}
@Override
public boolean isGeneric() {
return true;
}
@Override
public boolean isParameterized() {
return true;
}
@Override
public List<IRType> getActualTypeArguments() {
return typeArguments;
}
@Override
public String getName() {
final StringBuilder sb = new StringBuilder();
sb.append(getSource().getName());
sb.append('<');
for (IRType type : getActualTypeArguments()) {
sb.append(type.getName());
}
sb.append('>');
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RParameterizedTypeDeclaration other = (RParameterizedTypeDeclaration) obj;
return type.equals(other.type)
&& typeArguments.equals(other.typeArguments);
}
@Override
public TypeCompatibility isAssignableFrom(IRTypeDeclaration declaration) {
if (declaration instanceof RParameterizedTypeDeclaration) {
final RParameterizedTypeDeclaration other = (RParameterizedTypeDeclaration) declaration;
if (type.equals(other.type)) {
return isAssignableFrom(typeArguments, other.typeArguments) ? TypeCompatibility.TRUE
: TypeCompatibility.UNPARAMETERIZED;
}
}
return super.isAssignableFrom(declaration);
}
@Override
protected boolean _equals(RTypeDeclaration other) {
if (this.equals(other)) {
return true;
} else if (type.equals(other.type)) {
if (other instanceof RParameterizedTypeDeclaration) {
return isAssignableFrom(typeArguments,
((RParameterizedTypeDeclaration) other).typeArguments);
} else {
return true;
}
} else {
return false;
}
}
private static boolean isAssignableFrom(List<IRType> dest, List<IRType> src) {
if (dest.size() == src.size()) {
for (int i = 0; i < dest.size(); ++i) {
if (dest.get(i).isAssignableFrom(src.get(i)) != TypeCompatibility.TRUE) {
return false;
}
}
return true;
}
return false;
}
// ITypeSystem methods
public Type getKnownType(String typeName) {
return typeSystem.getKnownType(typeName);
}
public Type resolveType(Type type) {
return typeSystem.resolveType(type);
}
public IValue valueOf(IRMember member) {
return typeSystem.valueOf(member);
}
public IRTypeDeclaration convert(Type type) {
return typeSystem.convert(type);
}
public <E extends IRMember> E contextualize(E member, IRTypeDeclaration type) {
return typeSystem.contextualize(member, type);
}
public IRTypeDeclaration parameterize(Type target,
List<? extends IRType> parameters) {
return typeSystem.parameterize(target, parameters);
}
public IRType getTypeVariable(TypeVariable variable) {
final EList<TypeVariable> vars = ((GenericType) getSource())
.getTypeParameters();
for (int i = 0, size = vars.size(); i < size; ++i) {
if (vars.get(i) == variable) {
return typeArguments.get(i);
}
}
return null;
}
public Object getValue(Object key) {
return typeSystem.getValue(key);
}
public void setValue(Object key, Object value) {
typeSystem.setValue(key, value);
}
public ITypeSystem getPrimary() {
return typeSystem;
}
}