use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.
the class ExpressionTransformer method needsCast.
boolean needsCast(Type exprType, Type expectedType, boolean expectedTypeNotRaw, boolean expectedTypeHasConstrainedTypeParameters, boolean downCast) {
// error handling
if (exprType == null)
return false;
// make sure we work on definite types
exprType = simplifyType(exprType);
expectedType = simplifyType(expectedType);
// abort if both types are the same
if (exprType.isExactly(expectedType)) {
// really trust the expected type
if (!expectedTypeHasConstrainedTypeParameters)
return false;
}
// now see about erasure
boolean eraseExprType = willEraseToObject(exprType);
boolean eraseExpectedType = willEraseToObject(expectedType);
// if we erase expected type we need no cast
if (eraseExpectedType) {
// unless the expected type is parameterised with bounds that erasure to Object can't possibly satisfy
if (!expectedTypeHasConstrainedTypeParameters)
return false;
}
// if we erase the expr type we need a cast
if (eraseExprType)
return true;
// find their common type
Type commonType = exprType.getSupertype(expectedType.getDeclaration());
if (commonType == null || !(commonType.getDeclaration() instanceof ClassOrInterface)) {
// we did not find any common type, but we may be downcasting, in which case we need a cast
return downCast;
}
// some times we can lose info due to an erased type parameter somewhere in the inheritance graph
if (lostTypeParameterInInheritance(exprType, commonType))
return true;
if (!expectedTypeNotRaw) {
// if we know for sure that the expected type is NOT raw. if it's false we've no idea but we can check:
if (isTurnedToRaw(expectedType)) {
return false;
}
// the common type could be erased
if (commonType.isExactly(expectedType))
return false;
}
//special case for Callable because only the first type param exists in Java, the rest is completely suppressed
boolean isCallable = isCeylonCallable(commonType);
// now see if the type parameters match
java.util.List<Type> commonTypeArgs = commonType.getTypeArgumentList();
java.util.List<TypeParameter> commonTps = commonType.getDeclaration().getTypeParameters();
java.util.List<Type> expectedTypeArgs = expectedType.getTypeArgumentList();
java.util.List<TypeParameter> expectedTps = expectedType.getDeclaration().getTypeParameters();
// check that we got them all otherwise we just don't know
if (commonTypeArgs.size() != expectedTypeArgs.size())
return false;
for (int i = 0, n = commonTypeArgs.size(); i < n; i++) {
// apply the same logic to each type param: see if they would require a raw cast
Type commonTypeArg = commonTypeArgs.get(i);
Type expectedTypeArg = expectedTypeArgs.get(i);
if (hasDependentTypeParameters(commonTps, commonTps.get(i)) || hasDependentTypeParameters(expectedTps, expectedTps.get(i))) {
// if the type parameters are not identical:
if (!simplifyType(commonTypeArg).isExactly(simplifyType(expectedTypeArg))) {
return true;
}
}
if (needsCast(commonTypeArg, expectedTypeArg, expectedTypeNotRaw, expectedTypeHasConstrainedTypeParameters, downCast))
return true;
// stop after the first one for Callable
if (isCallable)
break;
}
return false;
}
use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.
the class ForcedCaptureVisitor method isForcedCapture.
private boolean isForcedCapture(Tree.TypedDeclaration that) {
if (that.getAnnotationList() == null)
return false;
for (Annotation anno : that.getAnnotationList().getAnnotations()) {
Type type = anno.getTypeModel();
if (type == null || !type.isClassOrInterface())
continue;
TypeDeclaration decl = type.getDeclaration();
if (decl == null)
continue;
Module module = Decl.getModule(decl);
if (module == null)
continue;
if (module.getLanguageModule() == module)
continue;
// does not come from the language module
return true;
}
return false;
}
use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.
the class TypeFactory method isTupleOfVariadicCallable.
/**
* Copy of Unit.isTupleLengthUnbounded which is more strict on what we consider variadic. For example
* we do not consider Args|[] as a variadic tuple in a Callable. See https://github.com/ceylon/ceylon-compiler/issues/1908
*/
public boolean isTupleOfVariadicCallable(Type args) {
if (args != null) {
/*Boolean simpleTupleLengthUnbounded =
isSimpleTupleLengthUnbounded(args);
if (simpleTupleLengthUnbounded != null) {
return simpleTupleLengthUnbounded.booleanValue();
}*/
if (isEmptyType(args)) {
return false;
} else if (isVariadicElement(args)) {
return true;
}
Class td = getTupleDeclaration();
Type tuple = nonemptyArgs(args).getSupertype(td);
if (tuple == null) {
return false;
} else {
while (true) {
java.util.List<Type> tal = tuple.getTypeArgumentList();
if (tal.size() >= 3) {
Type rest = tal.get(2);
if (rest == null) {
return false;
} else if (isEmptyType(rest)) {
return false;
} else if (isVariadicElement(rest)) {
return true;
} else {
tuple = nonemptyArgs(rest).getSupertype(td);
if (tuple == null) {
return false;
}
//else continue the loop!
}
} else {
return false;
}
}
}
}
return false;
}
use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.
the class TypeFactory method getReferenceType.
public Type getReferenceType(Type value) {
final Type serializedValueType;
TypeDeclaration referenceTypeDecl = (TypeDeclaration) getLanguageModuleSerializationDeclaration("Reference");
serializedValueType = referenceTypeDecl.appliedType(null, Collections.singletonList(value));
return serializedValueType;
}
use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.
the class UnknownTypeCollector method collectUnknownTypes.
private void collectUnknownTypes(Type type, Map<Declaration, Declaration> visited) {
if (type != null) {
type = type.resolveAliases();
if (type.isUnknown()) {
UnknownType ut = (UnknownType) type.getDeclaration();
ut.reportErrors();
// don't report it twice
ut.setErrorReporter(null);
} else if (type.isUnion()) {
for (Type t : type.getCaseTypes()) {
collectUnknownTypesResolved(t, visited);
}
} else if (type.isIntersection()) {
for (Type t : type.getSatisfiedTypes()) {
collectUnknownTypesResolved(t, visited);
}
} else if (type.isUnknown() || type.isTypeParameter()) {
// do nothing
} else {
TypeDeclaration declaration = type.getDeclaration();
if (visited.put(declaration, declaration) != null)
return;
if (type.isClassOrInterface()) {
// these are not resolved
if (type.getExtendedType() != null)
collectUnknownTypes(type.getExtendedType(), visited);
for (Type t : type.getSatisfiedTypes()) collectUnknownTypes(t, visited);
}
}
}
}
Aggregations