if (max==0) {
return emptyList();
}
List<ProducedType> typeArgs = new ArrayList<ProducedType>(max);
for (int i=0; i<max; i++) {
TypeParameter refinedTypeParam = refinedTypeParams.get(i);
TypeParameter refiningTypeParam = refiningTypeParams.get(i);
ProducedType refinedProducedType = refinedTypeParam.getType();
Map<TypeParameter, ProducedType> args = ci.getType()
.getSupertype((TypeDeclaration)refined.getContainer())
.getTypeArguments();
for (ProducedType t: refiningTypeParam.getSatisfiedTypes()) {
ProducedType bound =
t.substitute(singletonMap(refiningTypeParam, refinedProducedType));
//for every type constraint of the refining member, there must
//be at least one type constraint of the refined member which
//is assignable to it, guaranteeing that the intersection of
//the refined member bounds is assignable to the intersection
//of the refining member bounds
//TODO: would it be better to just form the intersections and
// test assignability directly (the error messages might
// not be as helpful, but it might be less restrictive)
boolean ok = false;
for (ProducedType st: refinedTypeParam.getSatisfiedTypes()) {
if (st.substitute(args).isSubtypeOf(bound)) {
ok = true;
}
}
if (!ok) {
that.addError("member type parameter '" + refiningTypeParam.getName() +
"' has upper bound which refined member type parameter '" +
refinedTypeParam.getName() + "' of " + message(refined) +
" does not satisfy: '" + t.getProducedTypeName(that.getUnit()) + "'");
}
}
for (ProducedType st: refinedTypeParam.getSatisfiedTypes()) {
boolean ok = false;
for (ProducedType t: refiningTypeParam.getSatisfiedTypes()) {
ProducedType bound =
t.substitute(singletonMap(refiningTypeParam, refinedProducedType));
if (st.substitute(args).isSubtypeOf(bound)) {
ok = true;
}
}
if (!ok) {
that.addUnsupportedError("refined member type parameter " +
refinedTypeParam.getName() + " of " + message(refined) +
" with upper bound which member type parameter " + refiningTypeParam.getName() +
" does not satisfy not yet supported: '" + st.getProducedTypeName(that.getUnit()) + "'");
}
}
typeArgs.add(refinedProducedType);
}