use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class InvocationGenerator method getTypeArguments.
private Map<TypeParameter, Type> getTypeArguments(Tree.Primary p) {
if (p instanceof Tree.StaticMemberOrTypeExpression) {
Tree.StaticMemberOrTypeExpression smote = (Tree.StaticMemberOrTypeExpression) p;
final Declaration d = smote.getDeclaration();
final boolean hasTargs = d != null && d.getContainer() instanceof Generic && ((Generic) d.getContainer()).isParameterized();
final boolean hasParentTargs = TypeUtils.isStaticWithGenericContainer(d);
if (hasTargs && ModelUtil.isConstructor(d)) {
return smote.getTarget().getTypeArguments();
} else if (hasParentTargs) {
if (smote.getTypeArguments() != null && !smote.getTypeArguments().getTypeModels().isEmpty()) {
// If the type is static AND has type arguments of its own, we need to merge them
Map<TypeParameter, Type> targs = new HashMap<>();
targs.putAll(smote.getTarget().getTypeArguments());
targs.putAll(smote.getTarget().getQualifyingType().getTypeArguments());
return targs;
}
return smote.getTarget().getQualifyingType().getTypeArguments();
} else if (d instanceof Functional) {
Map<TypeParameter, Type> targs = TypeUtils.matchTypeParametersWithArguments(d.getTypeParameters(), smote.getTypeArguments() == null ? null : smote.getTypeArguments().getTypeModels());
if (targs == null) {
gen.out("/*TARGS != TPARAMS!!!!*/");
}
return targs;
}
} else if (p instanceof Tree.ExtendedTypeExpression) {
Tree.ExtendedTypeExpression ete = (Tree.ExtendedTypeExpression) p;
return ete.getTarget().getTypeArguments();
}
return null;
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method isCapturableMplParameter.
/**
* Because methods with MPL use nested anonymous AbstractCallables
* if the declaration is a parameter in all but the last parameter list
* it should be captured.
*/
private boolean isCapturableMplParameter(Declaration d) {
if (!(d instanceof FunctionOrValue)) {
return false;
}
org.eclipse.ceylon.model.typechecker.model.Parameter param = ((FunctionOrValue) d).getInitializerParameter();
if (param == null) {
return false;
}
Declaration paramDecl = param.getDeclaration();
if (paramDecl instanceof Functional) {
List<org.eclipse.ceylon.model.typechecker.model.ParameterList> parameterLists = ((Functional) paramDecl).getParameterLists();
for (int i = 0; i < parameterLists.size() - 1; i++) {
if (parameterLists.get(i).getParameters().contains(param)) {
return true;
}
}
}
return false;
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class JvmBackendUtil method getTopmostRefinedDeclaration.
public static Declaration getTopmostRefinedDeclaration(Declaration decl, Map<Function, Function> methodOverrides) {
if (decl instanceof FunctionOrValue && ((FunctionOrValue) decl).isParameter() && decl.getContainer() instanceof Class) {
// Parameters in a refined class are not considered refinements themselves
// We have in find the refined attribute
Class c = (Class) decl.getContainer();
boolean isAlias = c.isAlias();
boolean isActual = c.isActual();
// boxing and stuff
if (isAlias || isActual) {
Functional ctor = null;
int index = c.getParameterList().getParameters().indexOf(findParamForDecl(((TypedDeclaration) decl)));
// Note(Stef): not entirely sure about that one, what about aliases of actual classes?
while ((isAlias && c.isAlias()) || (isActual && c.isActual())) {
ctor = (isAlias && c.isAlias()) ? (Functional) ((ClassAlias) c).getConstructor() : c;
Type et = c.getExtendedType();
c = et != null && et.isClass() ? (Class) et.getDeclaration() : null;
// handle compile errors
if (c == null)
return null;
}
if (isActual) {
ctor = c;
}
// be safe
if (ctor == null || ctor.getParameterLists() == null || ctor.getParameterLists().isEmpty() || ctor.getFirstParameterList() == null || ctor.getFirstParameterList().getParameters() == null || ctor.getFirstParameterList().getParameters().size() <= index)
return null;
decl = ctor.getFirstParameterList().getParameters().get(index).getModel();
}
if (decl.isShared()) {
Declaration refinedDecl = c.getRefinedMember(decl.getName(), getSignature(decl), isVariadic(decl));
if (refinedDecl != null && !ModelUtil.equal(refinedDecl, decl)) {
return getTopmostRefinedDeclaration(refinedDecl, methodOverrides);
}
}
return decl;
} else if (decl instanceof FunctionOrValue && // a parameter
((FunctionOrValue) decl).isParameter() && (// that's not parameter of a functional parameter
(decl.getContainer() instanceof Function && !(((Function) decl.getContainer()).isParameter())) || // or is a parameter in a specification
decl.getContainer() instanceof Specification || (decl.getContainer() instanceof Function && ((Function) decl.getContainer()).isParameter() && createMethod((Function) decl.getContainer())))) {
// or is a class functional parameter
// Parameters in a refined method are not considered refinements themselves
// so we have to look up the corresponding parameter in the container's refined declaration
Functional func = (Functional) getParameterized((FunctionOrValue) decl);
if (func == null)
return decl;
Declaration kk = getTopmostRefinedDeclaration((Declaration) func, methodOverrides);
// error recovery
if (kk instanceof Functional == false)
return decl;
Functional refinedFunc = (Functional) kk;
// shortcut if the functional doesn't override anything
if (ModelUtil.equal((Declaration) refinedFunc, (Declaration) func)) {
return decl;
}
if (func.getParameterLists().size() != refinedFunc.getParameterLists().size()) {
// invalid input
return decl;
}
for (int ii = 0; ii < func.getParameterLists().size(); ii++) {
if (func.getParameterLists().get(ii).getParameters().size() != refinedFunc.getParameterLists().get(ii).getParameters().size()) {
// invalid input
return decl;
}
// find the index of the parameter in the declaration
int index = 0;
for (Parameter px : func.getParameterLists().get(ii).getParameters()) {
if (px.getModel() == null || px.getModel().equals(decl)) {
// And return the corresponding parameter from the refined declaration
return refinedFunc.getParameterLists().get(ii).getParameters().get(index).getModel();
}
index++;
}
continue;
}
} else if (methodOverrides != null && decl instanceof Function && ModelUtil.equal(decl.getRefinedDeclaration(), decl) && decl.getContainer() instanceof Specification && ((Specification) decl.getContainer()).getDeclaration() instanceof Function && ((Function) ((Specification) decl.getContainer()).getDeclaration()).isShortcutRefinement() && // hash lookup we do next to make sure it is really one of those cases
methodOverrides.containsKey(decl)) {
// special case for class X() extends T(){ m = function() => e; } which we inline
decl = methodOverrides.get(decl);
}
Declaration refinedDecl = decl.getRefinedDeclaration();
if (refinedDecl != null && !ModelUtil.equal(refinedDecl, decl))
return getTopmostRefinedDeclaration(refinedDecl);
return decl;
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method inferrableAnyway.
private static boolean inferrableAnyway(Declaration dec) {
if (dec != null && dec.isParameterized() && dec instanceof Functional) {
Functional fd = (Functional) dec;
ParameterList list = fd.getFirstParameterList();
return list != null && list.getParameters().isEmpty();
} else {
return false;
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method inferParameterTypesFromCallableParameter.
private boolean inferParameterTypesFromCallableParameter(Reference pr, Parameter param, Tree.FunctionArgument anon, boolean error) {
boolean result = true;
Declaration declaration = param.getDeclaration();
Functional fun = (Functional) param.getModel();
List<ParameterList> fpls = fun.getParameterLists();
List<Tree.ParameterList> apls = anon.getParameterLists();
if (!fpls.isEmpty() && !apls.isEmpty()) {
List<Parameter> fps = fpls.get(0).getParameters();
List<Tree.Parameter> aps = apls.get(0).getParameters();
for (int j = 0; j < fps.size() && j < aps.size(); j++) {
Parameter fp = fps.get(j);
Tree.Parameter ap = aps.get(j);
if (isInferrableParameter(ap)) {
result = result & createInferredParameter(anon, declaration, ap, ap.getParameterModel(), pr.getTypedParameter(fp).getType(), fp.getModel(), error);
}
}
}
return result;
}
Aggregations