use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method createAnonymousFunctionParameters.
/**
* Iterate over the arguments of an invocation
* looking for anonymous functions with missing
* parameter lists, and create the parameter
* lists from the type of the parameters to
* which the arguments are assigned.
*/
private void createAnonymousFunctionParameters(Tree.InvocationExpression that) {
Tree.Primary primary = that.getPrimary();
Tree.PositionalArgumentList argList = that.getPositionalArgumentList();
if (argList != null && primary instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) primary;
List<Tree.PositionalArgument> args = argList.getPositionalArguments();
Declaration dec = mte.getDeclaration();
if (dec instanceof Functional) {
Functional fun = (Functional) dec;
ParameterList paramList = fun.getFirstParameterList();
if (paramList != null) {
List<Parameter> params = paramList.getParameters();
for (int i = 0, asz = args.size(), psz = params.size(); i < asz && i < psz; i++) {
Tree.PositionalArgument arg = args.get(i);
Parameter param = params.get(i);
if (arg instanceof Tree.ListedArgument && param != null) {
Tree.ListedArgument larg = (Tree.ListedArgument) arg;
List<Parameter> fpl = inferrableParameters(param);
Tree.Expression ex = larg.getExpression();
if (ex != null && fpl != null) {
Tree.Term term = ex.getTerm();
if (term instanceof Tree.FunctionArgument) {
Tree.FunctionArgument anon = (Tree.FunctionArgument) term;
createAnonymousFunctionParameters(fpl, term, anon);
}
}
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method checkForMissingNamedParameters.
private void checkForMissingNamedParameters(ParameterList pl, Reference pr, Tree.NamedArgumentList nal, Set<Parameter> foundParameters) {
StringBuilder missing = null;
int count = 0;
for (Parameter p : pl.getParameters()) {
if (!foundParameters.contains(p) && !p.isDefaulted() && (!p.isSequenced() || p.isAtLeastOne())) {
count++;
Type type = pr.getTypedParameter(p).getFullType();
if (missing == null) {
missing = new StringBuilder();
} else {
missing.append(", ");
}
if (type != null) {
missing.append(type.asString(unit)).append(" ");
}
missing.append(p.getName());
}
}
if (count == 1) {
nal.addError("missing named argument to required parameter '" + missing + "' of '" + pr.getDeclaration().getName(unit) + "'", 11000);
} else if (count > 1) {
nal.addError("missing named arguments to " + count + " required parameters '" + missing + "' of '" + pr.getDeclaration().getName(unit) + "'", 11000);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method checkNamedArguments.
private void checkNamedArguments(ParameterList pl, Reference pr, Tree.NamedArgumentList nal) {
Set<Parameter> foundParameters = new HashSet<Parameter>();
List<Tree.NamedArgument> na = nal.getNamedArguments();
for (Tree.NamedArgument a : na) {
checkNamedArg(a, pl, pr, foundParameters);
}
Tree.SequencedArgument sa = nal.getSequencedArgument();
if (sa != null) {
checkSequencedArg(sa, pl, pr, foundParameters);
} else {
Parameter param = getUnspecifiedParameter(pr, pl, foundParameters);
if (param != null && !unit.isNonemptyIterableType(param.getType())) {
foundParameters.add(param);
}
}
checkForMissingNamedParameters(pl, pr, nal, foundParameters);
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method checkPositionalArguments.
private void checkPositionalArguments(ParameterList pl, Reference pr, Tree.PositionalArgumentList pal, Tree.InvocationExpression that) {
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
List<Parameter> params = pl.getParameters();
Declaration target = pr.getDeclaration();
int argCount = args.size();
int paramsSize = params.size();
for (int i = 0; i < paramsSize; i++) {
Parameter param = params.get(i);
if (i >= argCount) {
if (isRequired(param)) {
Node errorNode = that instanceof Tree.Annotation && args.isEmpty() ? that : pal;
StringBuilder message = new StringBuilder();
if (i + 1 < paramsSize && isRequired(params.get(i + 1))) {
message.append("missing arguments to required parameters '");
appendParam(pr, param, message);
int count = 1;
for (int j = i + 1; j < paramsSize; j++) {
Parameter p = params.get(j);
if (p.isDefaulted() || p.isSequenced() && !p.isAtLeastOne()) {
break;
}
message.append(", ");
appendParam(pr, p, message);
count++;
}
message.append("'").insert(20, " " + count);
} else {
message.append("missing argument to required parameter '");
appendParam(pr, param, message);
message.append("'");
}
message.append(" of '").append(target.getName(unit)).append("'");
errorNode.addError(message.toString());
break;
}
} else {
Tree.PositionalArgument arg = args.get(i);
Type pt = param.getType();
if (!dynamic && isTypeUnknown(pt)) {
arg.addError("parameter type could not be determined: " + paramdesc(param) + getTypeUnknownError(pt));
}
if (arg instanceof Tree.SpreadArgument) {
checkSpreadArgument(pr, param, arg, (Tree.SpreadArgument) arg, params.subList(i, paramsSize));
break;
} else if (arg instanceof Tree.Comprehension) {
if (param.isSequenced()) {
checkComprehensionPositionalArgument(param, pr, (Tree.Comprehension) arg, param.isAtLeastOne());
} else {
arg.addError("not a variadic parameter: parameter '" + param.getName() + "' of '" + target.getName() + "'");
}
break;
} else {
if (param.isSequenced()) {
checkSequencedPositionalArgument(param, pr, args.subList(i, argCount));
// Note: early return!
return;
} else {
checkPositionalArgument(param, pr, (Tree.ListedArgument) arg);
}
}
}
}
for (int i = paramsSize; i < argCount; i++) {
Tree.PositionalArgument arg = args.get(i);
if (arg instanceof Tree.SpreadArgument) {
if (unit.isEmptyType(arg.getTypeModel())) {
continue;
}
}
arg.addError("no matching parameter declared by '" + target.getName(unit) + "': '" + target.getName(unit) + "' has " + paramsSize + " parameters", 2000);
}
checkJavaAnnotationElements(args, params, target);
}
use of org.eclipse.ceylon.model.typechecker.model.Parameter in project ceylon by eclipse.
the class ExpressionVisitor method refineMethod.
private void refineMethod(Tree.SpecifierStatement that) {
Function refinedMethod = (Function) that.getRefined();
Function method = (Function) that.getDeclaration();
ClassOrInterface ci = (ClassOrInterface) method.getContainer();
Declaration root = method.getRefinedDeclaration();
TypeDeclaration td = (TypeDeclaration) root.getContainer();
List<Declaration> interveningRefinements = getInterveningRefinements(method, root, ci, td);
if (interveningRefinements.isEmpty()) {
that.getBaseMemberExpression().addError("shortcut refinement does not exactly refine any overloaded inherited member");
} else {
Reference refinedProducedReference = accountForIntermediateRefinements(that, refinedMethod, method, ci, interveningRefinements);
List<Tree.ParameterList> parameterLists;
Tree.Term me = that.getBaseMemberExpression();
if (me instanceof Tree.ParameterizedExpression) {
Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
parameterLists = pe.getParameterLists();
} else {
parameterLists = emptyList();
}
List<ParameterList> refinedParamLists = refinedMethod.getParameterLists();
List<ParameterList> methodParamLists = method.getParameterLists();
Map<TypeParameter, Type> subs = substitutions(refinedMethod, method);
for (int i = 0; i < refinedParamLists.size() && i < methodParamLists.size(); i++) {
ParameterList refinedParameters = refinedParamLists.get(i);
ParameterList parameters = methodParamLists.get(i);
Tree.ParameterList parameterList = parameterLists.size() <= i ? null : parameterLists.get(i);
List<Parameter> rps = refinedParameters.getParameters();
for (int j = 0; j < rps.size(); j++) {
Parameter refinedParameter = rps.get(j);
Type refinedParameterType = refinedProducedReference.getTypedParameter(refinedParameter).getFullType().substitute(subs, null);
Parameter parameter;
if (parameterList == null || parameterList.getParameters().size() <= j) {
parameter = parameters.getParameters().get(j);
parameter.getModel().setType(refinedParameterType);
parameter.setSequenced(refinedParameter.isSequenced());
} else {
Tree.Parameter param = parameterList.getParameters().get(j);
parameter = param.getParameterModel();
Type parameterType = parameter.getModel().getTypedReference().getFullType();
Node typeNode = param;
if (param instanceof Tree.ParameterDeclaration) {
Tree.ParameterDeclaration pd = (Tree.ParameterDeclaration) param;
Tree.Type type = pd.getTypedDeclaration().getType();
if (type != null) {
typeNode = type;
}
}
checkIsExactlyIgnoringNull(refinedParameters.isNamedParametersSupported(), parameterType, refinedParameterType, typeNode, "type of parameter '" + parameter.getName() + "' of '" + method.getName() + "' declared by '" + ci.getName() + "' is different to type of corresponding parameter " + message(refinedMethod, refinedParameter), 9200);
if (refinedParameter.isSequenced() && !parameter.isSequenced()) {
param.addError("parameter must be variadic: parameter " + message(refinedMethod, refinedParameter) + " is variadic");
}
if (!refinedParameter.isSequenced() && parameter.isSequenced()) {
param.addError("parameter may not be variadic: parameter " + message(refinedMethod, refinedParameter) + " is not variadic");
}
}
}
}
}
}
Aggregations