/**
* 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.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import abs.frontend.ast.ClassDecl;
import abs.frontend.ast.FieldDecl;
import abs.frontend.ast.InterfaceTypeUse;
import abs.frontend.ast.List;
import abs.frontend.ast.MethodImpl;
import abs.frontend.ast.MethodSig;
public class UnionType extends ReferenceType {
private final java.util.List<InterfaceType> types;
private final ClassDecl originatingClass;
public UnionType(ClassDecl classDecl, List<InterfaceTypeUse> types) {
this.types = new ArrayList<InterfaceType>();
for (InterfaceTypeUse t : types) {
if (t.getType() instanceof InterfaceType) // maybe UnkownType
this.types.add((InterfaceType) t.getType());
}
originatingClass = classDecl;
}
public UnionType(ClassDecl classDecl, InterfaceType... types) {
this.types = new ArrayList<InterfaceType>();
this.types.addAll(Arrays.asList(types));
originatingClass = classDecl;
}
public java.util.List<InterfaceType> getTypes() {
return Collections.unmodifiableList(types);
}
public InterfaceType getType(int i) {
return types.get(i);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof UnionType))
return false;
UnionType t = (UnionType) o;
return t.types.equals(this.types);
}
@Override
public int hashCode() {
return types.hashCode();
}
@Override
public boolean isAssignableTo(Type t) {
if (super.isAssignableTo(t))
return true;
for (InterfaceType it : types) {
if (it.isAssignableTo(t))
return true;
}
return false;
}
@Override
public MethodSig lookupMethod(String name) {
// Check declared type first...
MethodImpl m = originatingClass.lookupMethod(name);
if (m != null)
return m.getMethodSig();
// ... then interfaces.
for (InterfaceType t : types) {
MethodSig s = t.lookupMethod(name);
if (s != null)
return s;
}
return null;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("UnionType{");
boolean first = true;
for (InterfaceType t : types) {
if (!first) {
buf.append(", ");
first = false;
}
buf.append(t.toString());
}
buf.append(" }");
return buf.toString();
}
@Override
public boolean isUnionType() {
return true;
}
@Override
public boolean isDeploymentComponentType() {
for (InterfaceType i : getTypes()) {
if (i.isDeploymentComponentType()) return true;
}
return false;
}
public ClassDecl getOriginatingClass() {
return originatingClass;
}
// Use the name of the originating class
@Override
public String getModuleName() {
return originatingClass.getModuleDecl().getName();
}
@Override
public String getSimpleName() {
return originatingClass.getName();
}
@Override
public Type copy() {
return new UnionType(originatingClass,types.toArray(new InterfaceType[0]));
}
@Override
public Collection<MethodSig> getAllMethodSigs() {
return originatingClass.getAllMethodSigs();
}
@Override
public Collection<FieldDecl> getAllFieldDecls() {
ArrayList<FieldDecl> res = new ArrayList<FieldDecl>();
for (FieldDecl d : originatingClass.getFieldList()) {
res.add(d);
}
return res;
}
}