use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class ExpressionVisitor method setFunctionType.
private void setFunctionType(Tree.FunctionModifier local, Type et, Tree.MethodArgument that, Tree.Expression e) {
Function dec = that.getDeclarationModel();
handleUncheckedNulls(local, e, dec);
Type t = inferrableType(et);
local.setTypeModel(t);
dec.setType(t);
}
use of org.eclipse.ceylon.model.typechecker.model.Function 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.Function in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.MethodArgument that) {
Tree.SpecifierExpression se = that.getSpecifierExpression();
Function fun = that.getDeclarationModel();
Tree.Type type = that.getType();
if (se == null) {
Declaration od = beginReturnDeclaration(fun);
Tree.Type rt = beginReturnScope(type);
super.visit(that);
endReturnScope(rt, fun);
endReturnDeclaration(od);
} else {
super.visit(that);
Tree.Expression e = se.getExpression();
if (e != null) {
inferFunctionType(that, e);
if (type != null && !(type instanceof Tree.DynamicModifier)) {
checkFunctionType(e, type, se);
}
if (fun.isDeclaredVoid() && !isSatementExpression(e)) {
se.addError("functional argument is declared void so specified expression must be a statement: '" + fun.getName() + "' is declared 'void'");
}
}
}
if (type instanceof Tree.LocalModifier) {
if (isTypeUnknown(type.getTypeModel())) {
if (se == null || hasError(type)) {
Node node = type.getToken() == null ? that : type;
node.addError("argument type could not be inferred");
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.FunctionArgument that) {
Tree.Expression e = that.getExpression();
Function fun = that.getDeclarationModel();
Tree.Type type = that.getType();
if (e == null) {
Tree.Type ret = type instanceof Tree.VoidModifier || !fun.isDeclaredVoid() ? type : new Tree.VoidModifier(null);
Declaration od = beginReturnDeclaration(fun);
Tree.Type rt = beginReturnScope(ret);
super.visit(that);
endReturnScope(rt, fun);
endReturnDeclaration(od);
} else {
super.visit(that);
Type returnType = unit.denotableType(e.getTypeModel());
fun.setType(returnType);
// if (that.getType() instanceof Tree.FunctionModifier) {
type.setTypeModel(returnType);
/*}
else {
checkAssignable(t, that.getType().getTypeModel(), e,
"expression type must be assignable to specified return type");
}*/
if (type instanceof Tree.VoidModifier && !isSatementExpression(e)) {
e.addError("anonymous function is declared void so specified expression must be a statement");
}
}
if (fun.isDeclaredVoid()) {
fun.setType(unit.getAnythingType());
}
that.setTypeModel(funType(that, fun));
Tree.TypeParameterList tpl = that.getTypeParameterList();
if (tpl != null) {
checkNotJvm(tpl, "type functions are not supported on the JVM: anonymous function is generic (remove type parameters)");
}
}
use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.Return that) {
super.visit(that);
if (returnType == null) {
// misplaced return statements are already handled by ControlFlowVisitor
// missing return types declarations already handled by TypeVisitor
// that.addError("could not determine expected return type");
} else {
that.setDeclaration(returnDeclaration);
Tree.Expression e = that.getExpression();
if (e == null) {
if (!(returnType instanceof Tree.VoidModifier)) {
if (returnDeclaration instanceof Function) {
that.addError("function must return a value: " + returndesc() + " is not a 'void' function", 12000);
} else {
that.addError("getter must return a value: " + returndesc() + " is a getter");
}
}
} else {
if (returnType instanceof Tree.VoidModifier) {
if (returnDeclaration instanceof Function) {
that.addError("function may not return a value: " + returndesc() + " is a 'void' function", 13000);
} else if (returnDeclaration instanceof TypedDeclaration) {
that.addError("setter may not return a value: " + returndesc() + " is a setter");
} else {
that.addError("class initializer may not return a value");
}
} else {
Type at = e.getTypeModel();
if (at != null) {
Type et = returnType.getTypeModel();
if (returnType instanceof Tree.LocalModifier) {
if (returnDeclaration.isActual()) {
// & RV.checkRefinedMemberTypeAssignable()
if (!isTypeUnknown(et) && !isTypeUnknown(at)) {
checkAssignable(at, et, e, "returned expression must be assignable to inferred return type of " + returndesc(), 2100);
}
} else {
inferReturnType(et, at, e);
}
} else {
if (!isTypeUnknown(et) && !isTypeUnknown(at)) {
checkAssignable(at, et, e, "returned expression must be assignable to return type of " + returndesc(), 2100);
}
}
}
}
}
}
}
Aggregations