use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class RefinementVisitor method visit.
@Override
public void visit(Tree.ParameterList that) {
super.visit(that);
boolean foundSequenced = false;
boolean foundDefault = false;
ParameterList pl = that.getModel();
for (Tree.Parameter p : that.getParameters()) {
if (p != null) {
Parameter pm = p.getParameterModel();
if (pm != null) {
if (pm.isDefaulted()) {
if (foundSequenced) {
p.addError("defaulted parameter must occur before variadic parameter");
}
foundDefault = true;
if (!pl.isFirst()) {
p.addError("only the first parameter list may have defaulted parameters");
}
} else if (pm.isSequenced()) {
if (foundSequenced) {
p.addError("parameter list may have at most one variadic parameter");
}
foundSequenced = true;
if (!pl.isFirst()) {
p.addError("only the first parameter list may have a variadic parameter");
}
if (foundDefault && pm.isAtLeastOne()) {
p.addError("parameter list with defaulted parameters may not have a nonempty variadic parameter");
}
} else {
if (foundDefault) {
p.addError("required parameter must occur before defaulted parameters");
}
if (foundSequenced) {
p.addError("required parameter must occur before variadic parameter");
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class RefinementVisitor method checkOverloadedParameters.
private void checkOverloadedParameters(Tree.Declaration that, Declaration member) {
String name = member.getName();
Declaration abstraction = member.getScope().getDirectMember(name, null, false);
if (abstraction != null) {
Functional fun = (Functional) member;
List<Parameter> parameters = fun.getFirstParameterList().getParameters();
for (Parameter param : parameters) {
if (param.isDefaulted()) {
that.addError("overloaded function parameter must be required: parameter '" + param.getName() + "' is defaulted");
}
}
Unit unit = that.getUnit();
for (Declaration dec : abstraction.getOverloads()) {
if (dec == member)
break;
Functional other = (Functional) dec;
List<Parameter> otherParams = other.getFirstParameterList().getParameters();
if (otherParams.size() == parameters.size()) {
boolean allSame = true;
for (int i = 0; i < parameters.size(); i++) {
TypeDeclaration paramType = erasedType(parameters.get(i), unit);
TypeDeclaration otherType = erasedType(otherParams.get(i), unit);
if (paramType != null && otherType != null && !paramType.equals(otherType)) {
allSame = false;
break;
}
}
if (allSame) {
that.addError("non-unique parameter list erasure for overloaded function: each overloaded declaration of '" + name + "' must have a distinct parameter list erasure");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class RefinementVisitor method visit.
@Override
public void visit(Tree.SpecifierStatement that) {
super.visit(that);
List<Type> sig = new ArrayList<Type>();
Tree.Term term = that.getBaseMemberExpression();
while (term instanceof Tree.ParameterizedExpression) {
sig.clear();
Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) term;
Tree.TypeParameterList typeParameterList = pe.getTypeParameterList();
if (typeParameterList != null) {
// TODO: remove this for #1329
typeParameterList.addError("specification statements may not have type parameters");
}
Tree.ParameterList pl = pe.getParameterLists().get(0);
for (Tree.Parameter p : pl.getParameters()) {
if (p == null) {
sig.add(null);
} else {
Parameter model = p.getParameterModel();
if (model != null) {
sig.add(model.getType());
} else {
sig.add(null);
}
}
}
term = pe.getPrimary();
}
if (term instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
Unit unit = that.getUnit();
TypedDeclaration td = getTypedDeclaration(bme.getScope(), name(bme.getIdentifier()), sig, false, unit);
if (td != null) {
that.setDeclaration(td);
Scope scope = that.getScope();
Scope container = scope.getContainer();
Scope realScope = getRealScope(container);
if (realScope instanceof ClassOrInterface) {
ClassOrInterface ci = (ClassOrInterface) realScope;
Scope tdcontainer = td.getContainer();
if (td.isClassOrInterfaceMember()) {
ClassOrInterface tdci = (ClassOrInterface) tdcontainer;
if (!tdcontainer.equals(realScope) && ci.inherits(tdci)) {
boolean lazy = that.getSpecifierExpression() instanceof Tree.LazySpecifierExpression;
if (!lazy && td.isVariable() && td.isJava()) {
// allow assignment to variable
// member of Java supertype
} else // refinement of an inherited member
if (tdcontainer == scope) {
that.addError("parameter declaration hides refining member: '" + td.getName(unit) + "' (rename parameter)");
} else if (td instanceof Value) {
refineAttribute((Value) td, bme, that, ci);
} else if (td instanceof Function) {
refineMethod((Function) td, bme, that, ci);
} else {
// TODO!
bme.addError("not a reference to a formal attribute: '" + td.getName(unit) + "'");
}
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class RefinementVisitor method createRefiningParameterList.
private void createRefiningParameterList(Reference rm, Function method, Tree.ParameterList params, Unit unit, Map<TypeParameter, Type> subs, ParameterList pl) {
ParameterList list = new ParameterList();
int j = 0;
for (Parameter p : pl.getParameters()) {
// TODO: meaningful errors when parameters don't line up
// currently this is handled elsewhere, but we can
// probably do it better right here
createRefiningParameter(rm, method, p, list, params, j++, subs, unit);
}
method.getParameterLists().add(list);
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class TypeArgumentInference method inferTypeArgumentFromPositionalArgs.
private Type inferTypeArgumentFromPositionalArgs(TypeParameter tp, ParameterList parameters, Type receiverType, Tree.PositionalArgumentList pal, Declaration invoked) {
boolean findingUpperBounds = isEffectivelyContravariant(tp, invoked, specifiedParameters(pal, parameters), false);
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
List<Type> inferredTypes = new ArrayList<Type>(args.size());
List<Parameter> params = parameters.getParameters();
for (int i = 0, len = params.size(); i < len; i++) {
Parameter parameter = params.get(i);
if (args.size() > i) {
Tree.PositionalArgument arg = args.get(i);
if (arg instanceof Tree.SpreadArgument) {
inferTypeArgFromSpreadArg(tp, receiverType, arg, i, invoked, findingUpperBounds, inferredTypes, params, pal);
} else if (arg instanceof Tree.Comprehension) {
if (parameter.isSequenced()) {
Tree.Comprehension c = (Tree.Comprehension) arg;
inferTypeArgFromComprehension(tp, parameter, c, findingUpperBounds, inferredTypes);
}
} else {
if (parameter.isSequenced()) {
inferTypeArgFromPositionalArgs(tp, parameter, args.subList(i, args.size()), findingUpperBounds, inferredTypes);
break;
} else {
Type parameterType = parameterType(receiverType, parameter, invoked);
Type argType = arg.getTypeModel();
addToUnionOrIntersection(findingUpperBounds, inferredTypes, inferTypeArg(tp, parameterType, argType, findingUpperBounds, pal));
}
}
}
}
return unionOrIntersection(findingUpperBounds, inferredTypes);
}
Aggregations