use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue 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.FunctionOrValue 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.FunctionOrValue in project ceylon by eclipse.
the class ExpressionVisitor method checkClassAliasParameters.
private void checkClassAliasParameters(Class alias, Tree.ClassDeclaration that, Tree.InvocationExpression ie) {
Tree.Primary primary = ie.getPrimary();
Tree.ExtendedTypeExpression smte = (Tree.ExtendedTypeExpression) primary;
Functional classOrConstructor = (Functional) smte.getDeclaration();
ParameterList cpl = classOrConstructor.getFirstParameterList();
ParameterList apl = alias.getParameterList();
if (cpl != null && apl != null) {
List<Parameter> cplps = cpl.getParameters();
List<Parameter> aplps = apl.getParameters();
int cps = cplps.size();
int aps = aplps.size();
if (cps != aps) {
that.getParameterList().addUnsupportedError("wrong number of initializer parameters declared by class alias: '" + alias.getName() + "'");
}
for (int i = 0; i < cps && i < aps; i++) {
Parameter ap = aplps.get(i);
Parameter cp = cplps.get(i);
Reference target = smte.getTarget();
FunctionOrValue apm = ap.getModel();
if (apm != null && target != null) {
Type pt = target.getTypedParameter(cp).getFullType();
Type apt = apm.getReference().getFullType();
if (!isTypeUnknown(pt) && !isTypeUnknown(apt) && !apt.isSubtypeOf(pt)) {
that.addUnsupportedError("alias parameter '" + ap.getName() + "' must be assignable to corresponding class parameter '" + cp.getName() + "'" + notAssignableMessage(apt, pt, that));
}
}
}
// temporary restrictions
checkAliasedClass(that, cpl, apl);
}
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.SpecifierStatement that) {
super.visit(that);
Tree.SpecifierExpression rhs = that.getSpecifierExpression();
Tree.Term lhs = that.getBaseMemberExpression();
boolean hasParams = false;
Tree.Term me = lhs;
while (me instanceof Tree.ParameterizedExpression) {
hasParams = true;
Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
me = pe.getPrimary();
}
if (!(me instanceof Tree.StaticMemberOrTypeExpression)) {
me.addError("illegal specification statement: only a function or value may be specified");
return;
}
assign(me);
Declaration d = that.getDeclaration();
if (d == null && me instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) me;
d = mte.getDeclaration();
}
if (d instanceof TypedDeclaration) {
TypedDeclaration td = (TypedDeclaration) d;
if (that.getRefinement()) {
// refinement of an inherited member
if (d instanceof Value) {
refineAttribute(that);
} else if (d instanceof Function) {
refineMethod(that);
}
Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) me;
smte.setDeclaration(d);
} else if (d instanceof FunctionOrValue && !lhs.hasErrors()) {
FunctionOrValue mv = (FunctionOrValue) d;
if (mv.isShortcutRefinement()) {
String desc = d instanceof Value ? "value" : "function";
me.addError(desc + " already specified by shortcut refinement: '" + d.getName(unit) + "'");
} else if (d instanceof Value && ((Value) d).isInferred()) {
me.addError("value is not a variable: '" + d.getName() + "'");
} else if (!mv.isVariable() && !mv.isLate()) {
String desc;
desc = d instanceof Value ? "value is neither variable nor late and" : "function";
if (mv.isToplevel()) {
me.addError("toplevel " + desc + " may not be specified: '" + d.getName(unit) + "'", 803);
} else if (!mv.isDefinedInScope(that.getScope())) {
me.addError(desc + " may not be specified here: '" + d.getName(unit) + "'", 803);
}
}
}
if (hasParams && d instanceof Function) {
Function f = (Function) d;
Tree.Expression se = rhs.getExpression();
if (f.isDeclaredVoid() && !isSatementExpression(se)) {
rhs.addError("function is declared void so specified expression must be a statement: '" + d.getName(unit) + "' is declared 'void'");
}
}
if (rhs instanceof Tree.LazySpecifierExpression && d instanceof Value) {
Value v = (Value) d;
v.setTransient(true);
}
Type lhst = lhs.getTypeModel();
if (!isTypeUnknown(lhst)) {
if (lhs == me && d instanceof Function && !lhst.isTypeConstructor()) {
// if the declaration of the method has
// defaulted parameters, we should ignore
// that when determining if the RHS is
// an acceptable implementation of the
// method
// TODO: this is a pretty nasty way to
// handle the problem
lhst = eraseDefaultedParameters(lhst);
}
TypedDeclaration member = that.getRefinement() ? that.getRefined() : td;
checkType(lhst, member, rhs, 2100);
}
}
if (lhs instanceof Tree.ParameterizedExpression) {
if (!(rhs instanceof Tree.LazySpecifierExpression)) {
rhs.addError("functions with parameters must be specified using =>");
}
} else {
if (rhs instanceof Tree.LazySpecifierExpression && d instanceof Function) {
rhs.addError("functions without parameters must be specified using =");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.
the class SelfReferenceVisitor method visit.
@Override
public void visit(Tree.SpecifierStatement that) {
if (inBody()) {
Tree.Term lt = that.getBaseMemberExpression();
Tree.SpecifierExpression se = that.getSpecifierExpression();
if (lt instanceof Tree.MemberOrTypeExpression && se != null) {
Tree.Expression e = se.getExpression();
if (e != null) {
if (e.getTerm() instanceof Tree.This) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) lt;
Declaration d = mte.getDeclaration();
if (d instanceof FunctionOrValue) {
FunctionOrValue fov = (FunctionOrValue) d;
if (fov.isLate()) {
lt.visit(this);
// NOTE: EARLY EXIT!!
return;
}
}
}
}
}
}
super.visit(that);
}
Aggregations