use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method setArgumentParameters.
/**
* Set up references from positional arguments to
* parameters for later use during type inference. This
* is only necessary here because in the case of an
* overloaded Java function or constructors, the
* overload has not been resolved the first time we
* visit the arguments. So we need to revisit them here
* with the fully-resolved overloaded version.
*
* @param that an invocation
* @param invoked the thing being invoked
*/
private void setArgumentParameters(Tree.InvocationExpression that, Declaration invoked) {
if (invoked instanceof Functional) {
Functional fun = (Functional) invoked;
List<ParameterList> pls = fun.getParameterLists();
if (!pls.isEmpty()) {
ParameterList pl = pls.get(0);
// no need to do named arg lists because
// they can't be used with overloaded decs
Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
if (pal != null) {
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
List<Parameter> params = pl.getParameters();
for (int i = 0, j = 0; i < args.size() && j < params.size(); i++) {
Tree.PositionalArgument arg = args.get(i);
Parameter param = params.get(j);
if (arg != null && param != null) {
arg.setParameter(param);
}
if (param == null || !param.isSequenced()) {
j++;
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.QualifiedMemberOrTypeExpression that) {
super.visit(that);
Tree.Term p = that.getPrimary();
while (p instanceof Tree.Expression && p.getMainToken() == null) {
// this hack allows actual parenthesized expressions through
Tree.Expression e = (Tree.Expression) p;
p = e.getTerm();
}
if (p instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) p;
Declaration pd = mte.getDeclaration();
if (!that.getStaticMethodReference()) {
if (pd instanceof Functional && !pd.isDynamic()) {
// this is a direct function ref
// it's not a type, it can't have members
that.addError("direct function references do not have members");
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional 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.Functional in project ceylon by eclipse.
the class RefinementVisitor method checkRefinedTypeAndParameterTypes.
/*private boolean refinesOverloaded(Declaration dec,
Declaration refined, Type st) {
Functional fun1 = (Functional) dec;
Functional fun2 = (Functional) refined;
if (fun1.getParameterLists().size()!=1 ||
fun2.getParameterLists().size()!=1) {
return false;
}
List<Parameter> pl1 = fun1.getParameterLists()
.get(0).getParameters();
List<Parameter> pl2 = fun2.getParameterLists()
.get(0).getParameters();
if (pl1.size()!=pl2.size()) {
return false;
}
for (int i=0; i<pl1.size(); i++) {
Parameter p1 = pl1.get(i);
Parameter p2 = pl2.get(i);
if (p1==null || p2==null ||
p1.getType()==null ||
p2.getType()==null) {
return false;
}
else {
Type p2st = p2.getType()
.substitute(st.getTypeArguments());
if (!matches(p1.getType(), p2st, dec.getUnit())) {
return false;
}
}
}
return true;
}*/
private void checkRefinedTypeAndParameterTypes(Tree.Declaration that, Declaration refining, ClassOrInterface ci, Declaration refined) {
List<TypeParameter> refinedTypeParams = refined.getTypeParameters();
List<TypeParameter> refiningTypeParams = refining.getTypeParameters();
checkRefiningMemberTypeParameters(that, refining, refined, refinedTypeParams, refiningTypeParams);
List<Type> typeArgs = checkRefiningMemberUpperBounds(that, ci, refined, refinedTypeParams, refiningTypeParams);
Type cit = ci.getType();
Reference refinedMember = cit.getTypedReference(refined, typeArgs);
Reference refiningMember = cit.getTypedReference(refining, typeArgs);
Declaration refinedMemberDec = refinedMember.getDeclaration();
Declaration refiningMemberDec = refiningMember.getDeclaration();
Node typeNode = getTypeErrorNode(that);
if (refinedMemberIsDynamicallyTyped(refinedMemberDec, refiningMemberDec)) {
checkRefiningMemberDynamicallyTyped(refined, refiningMemberDec, typeNode);
} else if (refiningMemberIsDynamicallyTyped(refinedMemberDec, refiningMemberDec)) {
checkRefinedMemberDynamicallyTyped(refined, refinedMemberDec, typeNode);
} else if (refinedMemberIsVariable(refinedMemberDec)) {
checkRefinedMemberTypeExactly(refiningMember, refinedMember, typeNode, refined, refining);
} else {
// note: this version checks return type and parameter types in one shot, but the
// resulting error messages aren't as friendly, so do it the hard way instead!
// checkAssignable(refiningMember.getFullType(), refinedMember.getFullType(), that,
checkRefinedMemberTypeAssignable(refiningMember, refinedMember, typeNode, refined, refining);
}
if (refining instanceof Functional && refined instanceof Functional) {
checkRefiningMemberParameters(that, refining, refined, refinedMember, refiningMember, false);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class RefinementVisitor method checkMember.
private void checkMember(Tree.Declaration that, Declaration member) {
String name = member.getName();
if (name == null) {
return;
}
if (member instanceof Setter) {
Setter setter = (Setter) member;
Value getter = setter.getGetter();
Declaration rd = getter.getRefinedDeclaration();
member.setRefinedDeclaration(rd);
return;
}
ClassOrInterface type = (ClassOrInterface) member.getContainer();
if (member.isFormal() && type instanceof Class) {
Class c = (Class) type;
if (!c.isAbstract() && !c.isFormal()) {
if (c.isClassOrInterfaceMember()) {
that.addError("formal member belongs to concrete nested class: '" + member.getName() + "' is a member of class '" + c.getName() + "' which is neither 'abstract' nor 'formal'", 1100);
} else {
that.addError("formal member belongs to concrete class: '" + member.getName() + "' is a member of class '" + c.getName() + "' which is not annotated 'abstract'", 1100);
}
}
}
if (member.isStatic() && !type.isToplevel()) {
that.addError("static member belongs to a nested class: '" + member.getName() + "' is a member of nested type '" + type.getName() + "'");
}
if (type.isDynamic()) {
if (member instanceof Class) {
that.addError("member class belongs to dynamic interface");
} else if (!member.isFormal()) {
that.addError("non-formal member belongs to dynamic interface");
}
}
if (member instanceof Functional && !that.hasErrors() && isOverloadedVersion(member)) {
checkOverloadedAnnotation(that, member);
checkOverloadedParameters(that, member);
}
checkRefinement(that, member, type);
}
Aggregations