use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method inferrableParameters.
/**
* Get the parameters of a callable parameter, or, if
* the given parameter is a value parameter of type
* X(Y), a single faked parameter with the name 'it'.
*/
private List<Parameter> inferrableParameters(Parameter param) {
FunctionOrValue model = param.getModel();
if (model instanceof Function) {
Function fun = (Function) model;
ParameterList fpl = fun.getFirstParameterList();
return fpl == null ? null : fpl.getParameters();
} else if (model instanceof Value) {
Type type = param.getType();
if (type != null) {
Type callable = intersectionType(type.resolveAliases(), appliedType(unit.getCallableDeclaration(), unit.getAnythingType(), unit.getNothingType()), unit);
if (callable.isCallable()) {
Type tup = unit.getCallableTuple(callable);
int min = unit.getTupleMinimumLength(tup);
int max = unit.getTupleMaximumLength(tup);
if (min == 1 || max == 1) {
Parameter p = new Parameter();
p.setName("it");
return Collections.<Parameter>singletonList(p);
} else if (min == 0) {
return Collections.<Parameter>emptyList();
}
}
}
return null;
} else {
return null;
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.InitializerParameter that) {
super.visit(that);
Parameter p = that.getParameterModel();
FunctionOrValue model = p.getModel();
if (model != null) {
Type type = model.getTypedReference().getFullType();
if (type != null && !isTypeUnknown(type)) {
checkType(type, that.getSpecifierExpression());
}
if (model.isParameterized()) {
checkNotJvm(that, "type functions are not supported on the JVM: '" + model.getName() + "' is generic (remove type parameters)");
}
} else {
Declaration a = that.getScope().getDirectMember(p.getName(), null, false);
if (a == null) {
Declaration fun = p.getDeclaration();
that.addError((fun != null && fun.isAnonymous() ? "parameter is not declared explicitly, and its type cannot be inferred" : "parameter is not declared") + ": '" + p.getName() + "' is not declared anywhere (specify the parameter type explicitly)");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method checkNamedArg.
private void checkNamedArg(Tree.NamedArgument a, ParameterList pl, Reference pr, Set<Parameter> foundParameters) {
Parameter param = getMatchingParameter(pl, a, foundParameters);
if (param == null) {
if (a.getIdentifier() == null) {
a.addError("all parameters specified by named argument list: '" + pr.getDeclaration().getName(unit) + "' does not declare any additional parameters");
} else {
a.addError("no matching parameter for named argument '" + name(a.getIdentifier()) + "' declared by '" + pr.getDeclaration().getName(unit) + "'", 101);
}
} else {
if (!foundParameters.add(param)) {
a.addError("duplicate argument for parameter: '" + param.getName() + "' of '" + pr.getDeclaration().getName(unit) + "'");
} else if (!dynamic && isTypeUnknown(param.getType())) {
a.addError("parameter type could not be determined: " + paramdesc(param) + getTypeUnknownError(param.getType()));
}
checkNamedArgument(a, pr, param);
// TODO: get rid of this nasty thing
if (a.getIdentifier() == null) {
Tree.Identifier node = new Tree.Identifier(null);
node.setScope(a.getScope());
node.setUnit(a.getUnit());
node.setText(param.getName());
a.setIdentifier(node);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method handleExpressionParameterList.
private Type handleExpressionParameterList(Tree.ParameterizedExpression that, Tree.MemberOrTypeExpression mte, Type pt, Tree.ParameterList pl) {
Interface cd = unit.getCallableDeclaration();
Type ct = pt.getSupertype(cd);
String refName = mte.getDeclaration().getName();
if (ct == null) {
pl.addError("no matching parameter list in referenced declaration: '" + refName + "'");
} else if (ct.getTypeArgumentList().size() >= 2) {
Type tupleType = ct.getTypeArgumentList().get(1);
List<Type> argTypes = unit.getTupleElementTypes(tupleType);
boolean variadic = unit.isTupleLengthUnbounded(tupleType);
boolean atLeastOne = unit.isTupleVariantAtLeastOne(tupleType);
List<Tree.Parameter> params = pl.getParameters();
if (argTypes.size() != params.size()) {
pl.addError("wrong number of declared parameters: '" + refName + "' has " + argTypes.size() + " parameters");
}
for (int i = 0; i < argTypes.size() && i < params.size(); i++) {
Type at = argTypes.get(i);
Tree.Parameter param = params.get(i);
Parameter model = param.getParameterModel();
// TODO: for #1329 this is not working yet
// because the parameters of a specification
// all wind up getting shoved into the
// namespace of the containing Declaration
// back in DeclarationVisitor, when by rights
// they should belong to the Specification,
// which means they all get muddled up with
// each other (this is probably causing other
// bugs too!)
/*Reference ref = mte.getTarget();
Declaration fakeDec = model.getDeclaration();
if (pt.isTypeConstructor()) {
List<Type> typeArgs =
typeParametersAsArgList(
pt.getDeclaration());
ref = fakeDec.appliedReference(null, typeArgs);
}
else {
ref = fakeDec.getReference();
}
Type paramType =
ref.getTypedParameter(model)
.getFullType();*/
Type paramType = model.getModel().getTypedReference().getFullType();
if (!isTypeUnknown(paramType) && !isTypeUnknown(at) && !at.isSubtypeOf(paramType)) {
param.addError("type of parameter '" + model.getName() + "' must be a supertype of corresponding parameter type in declaration of '" + refName + "'");
}
}
if (!params.isEmpty()) {
Tree.Parameter lastParam = params.get(params.size() - 1);
Parameter model = lastParam.getParameterModel();
boolean refSequenced = model.isSequenced();
boolean refAtLeastOne = model.isAtLeastOne();
if (refSequenced && !variadic) {
lastParam.addError("parameter list in declaration of '" + refName + "' does not have a variadic parameter");
} else if (!refSequenced && variadic) {
lastParam.addError("parameter list in declaration of '" + refName + "' has a variadic parameter");
} else if (refAtLeastOne && !atLeastOne) {
lastParam.addError("variadic parameter in declaration of '" + refName + "' is optional");
} else if (!refAtLeastOne && atLeastOne) {
lastParam.addError("variadic parameter in declaration of '" + refName + "' is not optional");
}
}
pt = ct.getTypeArgumentList().get(0);
that.setTypeModel(pt);
}
return pt;
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method inferParameterTypesFromCallableType.
private boolean inferParameterTypesFromCallableType(Type paramType, Parameter param, Tree.FunctionArgument anon, boolean error) {
List<Tree.ParameterList> apls = anon.getParameterLists();
boolean result = true;
if (!apls.isEmpty()) {
List<Type> types = unit.getCallableArgumentTypes(paramType);
List<Tree.Parameter> aps = apls.get(0).getParameters();
Declaration declaration = param == null ? null : param.getDeclaration();
for (int j = 0; j < types.size() && j < aps.size(); j++) {
Tree.Parameter ap = aps.get(j);
if (isInferrableParameter(ap)) {
result = result & createInferredParameter(anon, declaration, ap, ap.getParameterModel(), types.get(j), param == null ? null : param.getModel(), error);
}
}
}
return result;
}
Aggregations