use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class TypeArgumentInference method getInferredTypeArgsForStaticReference.
/**
* Infer type arguments for the qualifying type in a
* static method reference that is directly invoked.
* This method does not correctly handle stuff like
* constructors or Java static methods.
*
* @param that the invocation
* @param type the type whose type arguments we're
* inferring (the qualifying type)
* @param receiverType
*/
List<Type> getInferredTypeArgsForStaticReference(Tree.InvocationExpression that, TypeDeclaration type, Type receiverType, Tree.MemberOrTypeExpression primary) {
Tree.PositionalArgumentList pal = that.getPositionalArgumentList();
Declaration invoked = primary.getDeclaration();
if (pal == null) {
return null;
} else {
if (invoked instanceof Functional) {
List<PositionalArgument> args = pal.getPositionalArguments();
Functional fun = (Functional) invoked;
List<ParameterList> parameterLists = fun.getParameterLists();
if (args.isEmpty() || parameterLists.isEmpty()) {
return null;
} else {
// a static method ref invocation has exactly
// one meaningful argument (the instance of
// the receiving type)
Tree.PositionalArgument arg = args.get(0);
if (arg == null) {
return null;
} else {
Type at = arg.getTypeModel();
Type tt = type.getType();
List<TypeParameter> typeParams = type.getTypeParameters();
List<Type> typeArgs = new ArrayList<Type>(typeParams.size());
for (TypeParameter tp : typeParams) {
Type it = inferTypeArg(tp, tt, at, // TODO: is this 100% correct?
false, arg);
if (it == null || it.containsUnknowns()) {
that.addError("could not infer type argument from given arguments: type parameter '" + tp.getName() + "' could not be inferred");
}
typeArgs.add(it);
}
return constrainInferredTypes(typeParams, typeArgs, receiverType, invoked);
}
}
} else {
return null;
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class ExpressionVisitor method visitDirectInvocation.
/**
* Typecheck a direct invocation.
*/
private void visitDirectInvocation(Tree.InvocationExpression that) {
Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
if (primary == null) {
return;
}
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) primary;
Reference prf = mte.getTarget();
Declaration dec = mte.getDeclaration();
Functional fun = (Functional) dec;
if (dec != null) {
if (!(primary instanceof Tree.ExtendedTypeExpression)) {
if (dec instanceof Class) {
Class c = (Class) dec;
if (c.isAbstract()) {
that.addError("abstract class may not be instantiated: '" + dec.getName(unit) + "'");
}
}
}
Tree.NamedArgumentList nal = that.getNamedArgumentList();
if (nal != null && dec.isAbstraction()) {
// TODO: this is not really right - it's the fact
// that we're calling Java and don't have
// meaningful parameter names that is the
// real problem, not the overload
that.addError("overloaded declarations may not be called using named arguments: '" + dec.getName(unit) + "'");
}
// that.setTypeModel(prf.getType());
Type ct = primary.getTypeModel();
if (ct != null) {
List<Type> tal = ct.getTypeArgumentList();
if (!tal.isEmpty()) {
// pull the return type out of the Callable
that.setTypeModel(tal.get(0));
}
}
if (nal != null) {
List<ParameterList> parameterLists = fun.getParameterLists();
if (!parameterLists.isEmpty() && !parameterLists.get(0).isNamedParametersSupported()) {
that.addError("named invocations of Java methods not supported");
}
}
if (dec.isAbstraction()) {
// nothing to check the argument types against
// that.addError("no matching overloaded declaration");
} else {
// typecheck arguments using the parameter list
// of the target declaration
checkInvocationArguments(that, prf, fun);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class ExpressionVisitor method inferParameterTypesDirectly.
/**
* Infer parameter types of anonymous function arguments
* in a direct invocation with positional arguments.
*/
private boolean[] inferParameterTypesDirectly(Tree.PositionalArgumentList pal, Tree.MemberOrTypeExpression mte, Declaration dec, boolean error) {
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
int argCount = args.size();
boolean[] delayed = new boolean[argCount];
Functional fun = (Functional) dec;
List<ParameterList> pls = fun.getParameterLists();
if (!pls.isEmpty()) {
List<Parameter> params = pls.get(0).getParameters();
Reference reference = getInvokedProducedReference(dec, mte);
int paramsSize = params.size();
for (int i = 0, j = 0; i < argCount && j < paramsSize; i++) {
Parameter param = params.get(j);
Tree.PositionalArgument arg = args.get(i);
arg.setParameter(param);
if (arg instanceof Tree.ListedArgument) {
Tree.ListedArgument la = (Tree.ListedArgument) arg;
delayed[i] = !inferParameterTypes(reference, param, la.getExpression(), param.isSequenced(), error);
}
if (!param.isSequenced()) {
j++;
}
}
}
return delayed;
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class ExpressionVisitor method createAnonymousFunctionParameters.
/**
* Create the parameter list of the given
* anonymous function with a missing argument
* list, from the given parameter list of a
* functional parameter to which it is assigned.
*/
private void createAnonymousFunctionParameters(List<Parameter> parameters, Tree.Term term, Tree.FunctionArgument anon) {
Function model = anon.getDeclarationModel();
if (anon.getParameterLists().isEmpty()) {
Tree.ParameterList pl = new Tree.ParameterList(null);
ParameterList mpl = new ParameterList();
for (Parameter parameter : parameters) {
Tree.InitializerParameter ip = new Tree.InitializerParameter(null);
CommonToken token = new CommonToken(LIDENTIFIER, parameter.getName());
token.setStartIndex(term.getStartIndex());
Token tok = term.getToken();
token.setLine(tok.getLine());
token.setCharPositionInLine(tok.getCharPositionInLine());
Tree.Identifier id = new Tree.Identifier(token);
ip.setIdentifier(id);
pl.addParameter(ip);
ip.setUnit(unit);
ip.setScope(model);
id.setUnit(unit);
id.setScope(model);
Parameter mp = new Parameter();
mp.setDeclaration(model);
mp.setName(parameter.getName());
ip.setParameterModel(mp);
mpl.getParameters().add(mp);
pl.setModel(mpl);
}
pl.setUnit(unit);
pl.setScope(model);
model.addParameterList(mpl);
anon.addParameterList(pl);
}
}
use of org.eclipse.ceylon.model.typechecker.model.ParameterList in project ceylon by eclipse.
the class FunctionalUtil method getParameters.
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Sequential<FunctionOrValueDeclaration> getParameters(Functional declaration) {
ParameterList parameterList = ((Functional) declaration).getFirstParameterList();
if (parameterList == null)
return (Sequential) empty_.get_();
List<Parameter> modelParameters = parameterList.getParameters();
ceylon.language.meta.declaration.FunctionOrValueDeclaration[] parameters = new ceylon.language.meta.declaration.FunctionOrValueDeclaration[modelParameters.size()];
int i = 0;
for (Parameter modelParameter : modelParameters) {
parameters[i] = (ceylon.language.meta.declaration.FunctionOrValueDeclaration) Metamodel.getOrCreateMetamodel(modelParameter.getModel());
i++;
}
return Util.sequentialWrapper(ceylon.language.meta.declaration.FunctionOrValueDeclaration.$TypeDescriptor$, parameters);
}
Aggregations