}
}
else {
Set<TypeDeclaration> typeSet = new HashSet<TypeDeclaration>();
for (Tree.StaticType st: that.getTypes()) {
ProducedType type = st.getTypeModel();
TypeDeclaration ctd = type.getDeclaration();
if (type!=null && ctd!=null) {
type = type.resolveAliases();
ctd = type.getDeclaration();
if (!typeSet.add(ctd)) {
//this error is not really truly necessary
st.addError("duplicate case type: '" +
ctd.getName(unit) +
"' of '" + td.getName() + "'");
}
if (!(ctd instanceof TypeParameter)) {
//it's not a self type
if (checkDirectSubtype(td, st, type)) {
checkAssignable(type, td.getType(), st,
getCaseTypeExplanation(td, type));
}
//note: this is a better, faster way to call
// validateEnumeratedSupertypeArguments()
// but unfortunately it winds up displaying
// the error on the wrong node, confusing
// the user
/*ProducedType supertype = type.getDeclaration().getType().getSupertype(td);
validateEnumeratedSupertypeArguments(t, type.getDeclaration(), supertype);*/
}
if (ctd instanceof ClassOrInterface && st instanceof Tree.SimpleType) {
Tree.TypeArgumentList tal = ((Tree.SimpleType) st).getTypeArgumentList();
if (tal!=null) {
List<Tree.Type> args = tal.getTypes();
List<TypeParameter> typeParameters = ctd.getTypeParameters();
for (int i=0; i<args.size() && i<typeParameters.size(); i++) {
Tree.Type arg = args.get(i);
TypeParameter typeParameter = ctd.getTypeParameters().get(i);
ProducedType argType = arg.getTypeModel();
if (argType!=null) {
TypeDeclaration argTypeDec = argType.getDeclaration();
if (argTypeDec instanceof TypeParameter) {
if (!((TypeParameter) argTypeDec).getDeclaration().equals(td)) {
arg.addError("type argument is not a type parameter of the enumerated type: '" +
argTypeDec.getName() + "' is not a type parameter of '" + td.getName());
}
}
else if (typeParameter.isCovariant()) {
checkAssignable(typeParameter.getType(), argType, arg,
"type argument not an upper bound of the type parameter");
}
else if (typeParameter.isContravariant()) {
checkAssignable(argType, typeParameter.getType(), arg,
"type argument not a lower bound of the type parameter");
}
else {
arg.addError("type argument is not a type parameter of the enumerated type: '" +
argTypeDec.getName() + "'");
}
}
}
}
}
}
}
Set<Declaration> valueSet = new HashSet<Declaration>();
for (Tree.BaseMemberExpression bme: that.getBaseMemberExpressions()) {
ProducedType type = bme.getTypeModel();
Declaration d = bme.getDeclaration();
if (d!=null && !valueSet.add(d)) {
//this error is not really truly necessary
bme.addError("duplicate case: '" +
d.getName(unit) +
"' of '" + td.getName() + "'");
}
if (d!=null && type!=null &&
!type.getDeclaration().isAnonymous()) {
bme.addError("case must be a toplevel anonymous class: '" +
d.getName(unit) + "' is not an anonymous class");
}
else if (d!=null && !d.isToplevel()) {
bme.addError("case must be a toplevel anonymous class: '" +