/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.frontend.typechecker;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import abs.frontend.ast.Annotation;
import abs.frontend.ast.InterfaceDecl;
import abs.frontend.ast.InterfaceTypeUse;
import abs.frontend.ast.List;
import abs.frontend.ast.MethodSig;
public class InterfaceType extends ReferenceType {
private final java.util.List<Type> supertypes;
private final InterfaceDecl decl;
public InterfaceType(InterfaceDecl decl) {
this.decl = decl;
this.supertypes = new java.util.ArrayList<Type>();
for (InterfaceTypeUse i : decl.getExtendedInterfaceUses()) {
supertypes.add(i.getType());
}
}
public InterfaceDecl getDecl() {
return decl;
}
@Override
public boolean isInterfaceType() {
return true;
}
@Override
public boolean isDeploymentComponentType() {
// KLUDGE: we need a proper subtyping check here -- but it's all
// contained in abslang.abs so we make do for now
return getQualifiedName().equals("ABS.DC.DeploymentComponent")
|| getQualifiedName().equals("ABS.DC.DC")
|| getQualifiedName().equals("ABS.DC.DeploymentComponentForCloudProvider");
}
@Override
public boolean equals(Object o) {
if (!(o instanceof InterfaceType))
return false;
InterfaceType t = (InterfaceType) o;
return t.decl.equals(this.decl);
}
@Override
public int hashCode() {
return decl.hashCode();
}
@Override
public boolean isAssignableTo(Type t, boolean considerSubtyping) {
if (super.isAssignableTo(t))
return true;
if (considerSubtyping) {
if (isAssignable(t,new HashSet<Type>()))
return true;
}
return false;
}
private boolean isAssignable(Type t, Set<Type> visitedTypes) {
if (visitedTypes.contains(this))
return false;
visitedTypes.add(this);
if (super.isAssignableTo(t))
return true;
for (Type it : supertypes) {
if (it.isInterfaceType()) { // maybe UnkownType
if (((InterfaceType)it).isAssignable(t, visitedTypes))
return true;
}
}
return false;
}
@Override
public boolean isAssignableTo(Type t) {
return this.isAssignableTo(t, true);
}
@Override
public String toString() {
return decl.getName();
}
@Override
public String getModuleName() {
return decl.getModuleDecl().getName();
}
@Override
public String getSimpleName() {
return decl.getName();
}
@Override
public MethodSig lookupMethod(String name) {
return decl.lookupMethod(name);
}
@Override
public Type copy() {
return new InterfaceType(decl);
}
@Override
public Collection<MethodSig> getAllMethodSigs() {
return decl.getAllMethodSigs();
}
@Override
public InterfaceTypeUse toUse() {
return new InterfaceTypeUse(getQualifiedName(), new List<Annotation>());
}
}