use of com.redhat.ceylon.model.typechecker.model.Generic in project ceylon-compiler by ceylon.
the class ExpressionTransformer method erasesTypeArguments.
boolean erasesTypeArguments(Reference producedReference) {
java.util.List<TypeParameter> tps = null;
Declaration declaration = producedReference.getDeclaration();
if (declaration instanceof Generic) {
tps = ((Generic) declaration).getTypeParameters();
}
if (tps != null) {
for (TypeParameter tp : tps) {
Type ta = producedReference.getTypeArguments().get(tp);
java.util.List<Type> bounds = null;
boolean needsCastForBounds = false;
if (!tp.getSatisfiedTypes().isEmpty()) {
bounds = new ArrayList<Type>(tp.getSatisfiedTypes().size());
for (Type bound : tp.getSatisfiedTypes()) {
// substitute the right type arguments
bound = substituteTypeArgumentsForTypeParameterBound(producedReference, bound);
bounds.add(bound);
needsCastForBounds |= needsCast(ta, bound, false, false, false);
}
}
if (willEraseToObject(ta) || needsCastForBounds) {
return true;
}
}
}
return false;
}
use of com.redhat.ceylon.model.typechecker.model.Generic in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformTypeArguments.
private final void transformTypeArguments(CallBuilder callBuilder, Tree.StaticMemberOrTypeExpression mte) {
java.util.List<TypeParameter> tps = null;
Declaration declaration = mte.getDeclaration();
if (declaration instanceof Generic) {
tps = ((Generic) declaration).getTypeParameters();
}
if (mte.getTypeModel().isTypeConstructor()) {
for (TypeParameter tp : tps) {
callBuilder.typeArgument(makeJavaType(tp.getType(), JT_TYPE_ARGUMENT));
}
return;
}
if (tps != null) {
for (TypeParameter tp : tps) {
Type ta = mte.getTarget().getTypeArguments().get(tp);
java.util.List<Type> bounds = null;
boolean needsCastForBounds = false;
if (!tp.getSatisfiedTypes().isEmpty()) {
bounds = new ArrayList<Type>(tp.getSatisfiedTypes().size());
for (Type bound : tp.getSatisfiedTypes()) {
// substitute the right type arguments
bound = substituteTypeArgumentsForTypeParameterBound(mte.getTarget(), bound);
bounds.add(bound);
needsCastForBounds |= needsCast(ta, bound, false, false, false);
}
}
boolean hasMultipleBounds;
Type firstBound;
if (bounds != null) {
hasMultipleBounds = bounds.size() > 1;
firstBound = bounds.isEmpty() ? null : bounds.get(0);
} else {
hasMultipleBounds = false;
firstBound = null;
}
if (willEraseToObject(ta) || needsCastForBounds) {
boolean boundsSelfDependent = isBoundsSelfDependant(tp);
if (hasDependentTypeParameters(tps, tp) || // and we cannot represent the intersection type in Java so give up
hasMultipleBounds || // if we are going to use the first bound and it is self-dependent, we will make it raw
boundsSelfDependent || (firstBound != null && willEraseToObject(firstBound))) {
// so at some point we'll have to introduce an intersection type AST node to satisfy multiple bounds
if (hasMultipleBounds) {
callBuilder.typeArguments(List.<JCExpression>nil());
return;
}
// if we have a bound
if (firstBound != null) {
// if it's self-dependent we cannot satisfy it without a raw type
if (boundsSelfDependent)
callBuilder.typeArgument(makeJavaType(firstBound, JT_TYPE_ARGUMENT | JT_RAW));
else
callBuilder.typeArgument(makeJavaType(firstBound, JT_TYPE_ARGUMENT));
} else {
// no bound, let's go with Object then
callBuilder.typeArgument(makeJavaType(typeFact().getObjectType(), JT_TYPE_ARGUMENT));
}
} else if (firstBound == null) {
callBuilder.typeArgument(makeJavaType(ta, JT_TYPE_ARGUMENT));
} else {
callBuilder.typeArgument(makeJavaType(firstBound, JT_TYPE_ARGUMENT));
}
} else {
callBuilder.typeArgument(makeJavaType(ta, JT_TYPE_ARGUMENT));
}
}
}
}
Aggregations