use of org.eclipse.ceylon.compiler.typechecker.tree.Node in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.IfStatement that) {
Node ois = ifStatementOrExpression;
Node oss = switchStatementOrExpression;
ifStatementOrExpression = that;
switchStatementOrExpression = null;
super.visit(that);
ifStatementOrExpression = ois;
switchStatementOrExpression = oss;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Node in project ceylon by eclipse.
the class ExpressionVisitor method checkNamedArgument.
private void checkNamedArgument(Tree.NamedArgument arg, Reference reference, Parameter param) {
arg.setParameter(param);
Type argType = null;
if (arg instanceof Tree.SpecifiedArgument) {
Tree.SpecifiedArgument sa = (Tree.SpecifiedArgument) arg;
Tree.Expression e = sa.getSpecifierExpression().getExpression();
if (e != null) {
argType = e.getTypeModel();
}
} else if (arg instanceof Tree.TypedArgument) {
Tree.TypedArgument typedArg = (Tree.TypedArgument) arg;
TypedDeclaration argDec = typedArg.getDeclarationModel();
argType = argumentType(arg.getScope(), argDec);
checkArgumentToVoidParameter(param, typedArg);
if (!dynamic && isTypeUnknown(argType) && !hasError(arg)) {
arg.addError("could not determine type of named argument: the type of '" + param.getName() + "' is not known");
}
}
FunctionOrValue paramModel = param.getModel();
if (paramModel != null) {
TypedReference paramRef = reference.getTypedParameter(param);
Type paramType = paramType(arg.getScope(), paramRef, paramModel);
if (!isTypeUnknown(argType) && !isTypeUnknown(paramType)) {
Node node;
if (arg instanceof Tree.SpecifiedArgument) {
Tree.SpecifiedArgument specifiedArg = (Tree.SpecifiedArgument) arg;
node = specifiedArg.getSpecifierExpression();
} else {
node = arg;
}
checkAssignable(argType, paramType, node, "named argument must be assignable to parameter " + argdesc(param, reference), 2100);
}
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Node in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.SwitchStatement that) {
Node oss = switchStatementOrExpression;
Node ois = ifStatementOrExpression;
ifStatementOrExpression = null;
switchStatementOrExpression = that;
super.visit(that);
checkSwitch(that.getSwitchClause(), that.getSwitchCaseList());
switchStatementOrExpression = oss;
ifStatementOrExpression = ois;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Node 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.compiler.typechecker.tree.Node 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