use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class TypeArgumentInference method inferTypeArgumentFromPositionalArgs.
private Type inferTypeArgumentFromPositionalArgs(TypeParameter tp, ParameterList parameters, Type receiverType, Tree.PositionalArgumentList pal, Declaration invoked) {
boolean findingUpperBounds = isEffectivelyContravariant(tp, invoked, specifiedParameters(pal, parameters), false);
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
List<Type> inferredTypes = new ArrayList<Type>(args.size());
List<Parameter> params = parameters.getParameters();
for (int i = 0, len = params.size(); i < len; i++) {
Parameter parameter = params.get(i);
if (args.size() > i) {
Tree.PositionalArgument arg = args.get(i);
if (arg instanceof Tree.SpreadArgument) {
inferTypeArgFromSpreadArg(tp, receiverType, arg, i, invoked, findingUpperBounds, inferredTypes, params, pal);
} else if (arg instanceof Tree.Comprehension) {
if (parameter.isSequenced()) {
Tree.Comprehension c = (Tree.Comprehension) arg;
inferTypeArgFromComprehension(tp, parameter, c, findingUpperBounds, inferredTypes);
}
} else {
if (parameter.isSequenced()) {
inferTypeArgFromPositionalArgs(tp, parameter, args.subList(i, args.size()), findingUpperBounds, inferredTypes);
break;
} else {
Type parameterType = parameterType(receiverType, parameter, invoked);
Type argType = arg.getTypeModel();
addToUnionOrIntersection(findingUpperBounds, inferredTypes, inferTypeArg(tp, parameterType, argType, findingUpperBounds, pal));
}
}
}
}
return unionOrIntersection(findingUpperBounds, inferredTypes);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class TypeArgumentInference method inferFunctionRefTypeArgs.
/**
* Infer the type arguments for a reference to a
* generic function that occurs as a parameter in
* an invocation. This implementation is used when
* have an indirect ref whose type is a type
* constructor. This version is also used for
* static references.
*/
private List<Type> inferFunctionRefTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, boolean secondList, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
Reference arg = appliedReference(smte);
// this is the type of the parameter list
// of the function ref itself, which
// involves the type parameters we are
// trying to infer
Type parameterListType;
Type fullType;
Type argType;
if (smte.getStaticMethodReferencePrimary()) {
argType = arg.getType();
parameterListType = appliedType(unit.getTupleDeclaration(), argType, argType, unit.getEmptyType());
fullType = appliedType(unit.getCallableDeclaration(), argType, parameterListType);
} else {
fullType = arg.getFullType();
if (secondList) {
fullType = unit.getCallableReturnType(fullType);
}
parameterListType = unit.getCallableTuple(fullType);
argType = unit.getCallableReturnType(fullType);
}
// this is the type of the parameter list
// of the callable parameter that the
// function ref is being passed to (these
// parameters are going to be assigned to
// the parameters of the function ref)
Type argumentListType = unit.getCallableTuple(paramType);
Type returnType = unit.getCallableReturnType(paramType);
int argCount = unit.getTupleElementTypes(argumentListType).size();
List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
for (TypeParameter tp : typeParameters) {
boolean findUpperBounds = isEffectivelyContravariant(tp, fullType, argCount);
Type type = inferFunctionRefTypeArg(smte, tp, parameterizedDec, parameterListType, argumentListType, argType, returnType, findUpperBounds);
inferredTypes.add(type);
}
return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class TypeArgumentInference method inferNullaryFunctionCallTypeArgs.
/**
* Infer type arguments for the invocation of a
* nullary function that occurs as an argument.
* The parameter to which it is an argument isn't
* a callable parameter.
*/
private List<Type> inferNullaryFunctionCallTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
Reference arg = appliedReference(smte);
List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
Type argType = arg.getType();
TypeDeclaration ptd = paramType.getDeclaration();
Type template = // all supertypes of argType?
ptd instanceof ClassOrInterface ? argType.getSupertype(ptd) : argType;
for (TypeParameter tp : typeParameters) {
boolean covariant = template.occursCovariantly(tp) && !template.occursContravariantly(tp);
boolean contravariant = template.occursContravariantly(tp) && !template.occursCovariantly(tp);
Type it = inferNullaryFunctionCallTypeArg(smte, tp, paramType, parameterizedDec, template, covariant, contravariant);
inferredTypes.add(it);
}
return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class TypeArgumentInference method inferNullaryFunctionCallTypeArg.
private Type inferNullaryFunctionCallTypeArg(Tree.StaticMemberOrTypeExpression smte, TypeParameter tp, Type paramType, Declaration parameterizedDec, Type template, boolean covariant, boolean contravariant) {
// if (covariant) {
// it = unit.getNothingType();
// }
// else if (contravariant) {
// it = intersectionOfSupertypes(tp);
// }
// else {
List<Type> list = new ArrayList<Type>(1);
Type rt = inferTypeArg(tp, template, paramType, !covariant, !contravariant, false, new ArrayList<TypeParameter>(), smte);
if (!isTypeUnknown(rt) && !involvesTypeParams(parameterizedDec, rt)) {
addToUnionOrIntersection(contravariant, list, rt);
}
return unionOrIntersection(contravariant, list);
// }
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class InheritanceVisitor method validateEnumeratedSupertypeArgument.
private void validateEnumeratedSupertypeArgument(Node that, TypeDeclaration type, Type supertype, TypeParameter tp, Type arg) {
Unit unit = that.getUnit();
if (arg.isTypeParameter()) {
TypeParameter atp = (TypeParameter) arg.getDeclaration();
if (atp.getDeclaration().equals(type)) {
// parameter of the enumerated supertype
if (tp.isCovariant() && !atp.isCovariant()) {
that.addError("argument to covariant type parameter of enumerated supertype must be covariant: " + typeDescription(tp, unit));
}
if (tp.isContravariant() && !atp.isContravariant()) {
that.addError("argument to contravariant type parameter of enumerated supertype must be contravariant: " + typeDescription(tp, unit));
}
} else {
that.addError("argument to type parameter of enumerated supertype must be a type parameter of '" + type.getName() + "': " + typeDescription(tp, unit));
}
} else if (tp.isCovariant()) {
if (!(arg.isNothing())) {
// TODO: let it be the union of the lower bounds on p
that.addError("argument to covariant type parameter of enumerated supertype must be a type parameter or 'Nothing': " + typeDescription(tp, unit));
}
} else if (tp.isContravariant()) {
List<Type> sts = tp.getSatisfiedTypes();
// TODO: do I need to do type arg substitution here??
Type ub = intersectionOfSupertypes(tp);
if (!(arg.isExactly(ub))) {
that.addError("argument to contravariant type parameter of enumerated supertype must be a type parameter or '" + typeNamesAsIntersection(sts, unit) + "': " + typeDescription(tp, unit));
}
} else {
that.addError("argument to type parameter of enumerated supertype must be a type parameter: " + typeDescription(tp, unit));
}
}
Aggregations