use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class NamedArgumentInvocation method makeVarRefArgumentList.
// Make a list of ($arg0, $arg1, ... , $argN)
// or ($arg$this$, $arg0, $arg1, ... , $argN)
private List<JCExpression> makeVarRefArgumentList(Parameter param) {
ListBuffer<JCExpression> names = new ListBuffer<JCExpression>();
if (!Strategy.defaultParameterMethodStatic(getPrimaryDeclaration()) && Strategy.defaultParameterMethodTakesThis(param.getModel())) {
names.append(varBaseName.suffixedBy(Suffix.$argthis$).makeIdent());
}
// put all the required reified type args too
Reference ref = gen.resolveAliasesForReifiedTypeArguments(producedReference);
int tpCount = gen.getTypeParameters(ref).size();
for (int tpIndex = 0; tpIndex < tpCount; tpIndex++) {
names.append(reifiedTypeArgName(tpIndex).makeIdent());
}
final int parameterIndex = parameterIndex(param);
for (int ii = 0; ii < parameterIndex; ii++) {
names.append(this.argsNamesByIndex.get(ii).makeIdent());
}
return names.toList();
}
use of org.eclipse.ceylon.model.typechecker.model.Reference 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.Reference 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.Reference in project ceylon by eclipse.
the class TypeArgumentInference method constrainInferredTypes.
private List<Type> constrainInferredTypes(List<TypeParameter> typeParameters, List<Type> inferredTypeArgs, Type qualifyingType, Declaration declaration) {
int size = inferredTypeArgs.size();
boolean found = false;
for (int i = 0; i < size; i++) {
TypeParameter tp = typeParameters.get(i);
// if (!tp.isCovariant()) {
List<Type> bounds = tp.getSatisfiedTypes();
if (!bounds.isEmpty()) {
found = true;
}
// }
}
if (found) {
Reference ref;
if (declaration instanceof Value) {
Value value = (Value) declaration;
if (value.getType().isTypeConstructor()) {
if (qualifyingType == null) {
ref = declaration.appliedReference(null, NO_TYPE_ARGS);
} else {
ref = qualifyingType.getTypedReference(declaration, NO_TYPE_ARGS);
}
TypeDeclaration dec = ref.getType().getDeclaration();
ref = dec.appliedReference(null, inferredTypeArgs);
} else {
return inferredTypeArgs;
}
} else {
if (qualifyingType == null) {
ref = declaration.appliedReference(null, inferredTypeArgs);
} else {
ref = qualifyingType.getTypedReference(declaration, inferredTypeArgs);
}
}
Map<TypeParameter, Type> args = ref.getTypeArguments();
ArrayList<Type> result = new ArrayList<Type>(size);
for (int i = 0; i < size; i++) {
TypeParameter tp = typeParameters.get(i);
Type arg = inferredTypeArgs.get(i);
Type constrainedArg = // tp.isCovariant() ? arg :
constrainInferredType(tp, arg, args);
result.add(constrainedArg);
}
return result;
} else {
return inferredTypeArgs;
}
}
use of org.eclipse.ceylon.model.typechecker.model.Reference in project ceylon by eclipse.
the class ExpressionVisitor method visitDirectInvocation.
/**
* Typecheck a direct invocation.
*/
private void visitDirectInvocation(Tree.InvocationExpression that) {
Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
if (primary == null) {
return;
}
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) primary;
Reference prf = mte.getTarget();
Declaration dec = mte.getDeclaration();
Functional fun = (Functional) dec;
if (dec != null) {
if (!(primary instanceof Tree.ExtendedTypeExpression)) {
if (dec instanceof Class) {
Class c = (Class) dec;
if (c.isAbstract()) {
that.addError("abstract class may not be instantiated: '" + dec.getName(unit) + "'");
}
}
}
Tree.NamedArgumentList nal = that.getNamedArgumentList();
if (nal != null && dec.isAbstraction()) {
// TODO: this is not really right - it's the fact
// that we're calling Java and don't have
// meaningful parameter names that is the
// real problem, not the overload
that.addError("overloaded declarations may not be called using named arguments: '" + dec.getName(unit) + "'");
}
// that.setTypeModel(prf.getType());
Type ct = primary.getTypeModel();
if (ct != null) {
List<Type> tal = ct.getTypeArgumentList();
if (!tal.isEmpty()) {
// pull the return type out of the Callable
that.setTypeModel(tal.get(0));
}
}
if (nal != null) {
List<ParameterList> parameterLists = fun.getParameterLists();
if (!parameterLists.isEmpty() && !parameterLists.get(0).isNamedParametersSupported()) {
that.addError("named invocations of Java methods not supported");
}
}
if (dec.isAbstraction()) {
// nothing to check the argument types against
// that.addError("no matching overloaded declaration");
} else {
// typecheck arguments using the parameter list
// of the target declaration
checkInvocationArguments(that, prf, fun);
}
}
}
Aggregations