* <code>subType</code> and <code>superType</code>. The returned type
* must have the same base type as <code>subType</code>. If there are
* definitely no such values, return <code>null</code>.
*/
public JClassType constrainTypeBy(JClassType subType, JClassType superType) {
JParameterizedType superAsParameterized = superType.isParameterized();
if (superAsParameterized == null) {
// If the supertype is not parameterized, it will not be possible to
// constrain
// the subtype further.
return subType;
}
// Replace each wildcard in the subType with a fresh type variable.
// These type variables will be the ones that are constrained.
Map<JTypeParameter, JClassType> constraints = new HashMap<JTypeParameter, JClassType>();
JClassType subWithWildcardsReplaced = replaceWildcardsWithFreshTypeVariables(
subType, constraints);
// Rewrite subType so that it has the same base type as superType.
JParameterizedType subAsParameterized = subWithWildcardsReplaced.asParameterizationOf(superAsParameterized.getBaseType());
if (subAsParameterized == null) {
// The subtype's base does not inherit from the supertype's base,
// so again no constraint will be possible.
return subType;
}