use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class AnnotationUtil method isNaturalTarget.
/**
* Whether an annotation (with the given {@code annotationCtorDecl}
* annotation constructor) used on the given declaration ({@code useSite})
* should be added to the Java annotations of the given generated program
* elements ({@code target})
* @param annotationCtorDecl
* @param useSite
* @param target
* @return
*/
public static boolean isNaturalTarget(// use site is either a Declaration, or a Package, or a Module,
Function annotationCtorDecl, // module imports
Object useSite, OutputElement target) {
EnumSet<AnnotationTarget> interopTargets;
if (annotationCtorDecl instanceof AnnotationProxyMethod) {
AnnotationProxyMethod annotationProxyMethod = (AnnotationProxyMethod) annotationCtorDecl;
if (annotationProxyMethod.getAnnotationTarget() == target) {
// Foo__WHATEVER, so honour the WHATEVER
return true;
}
interopTargets = annotationProxyMethod.getAnnotationTargets();
} else {
interopTargets = null;
}
if (useSite instanceof Declaration) {
if (ModelUtil.isConstructor((Declaration) useSite)) {
if (useSite instanceof Functional) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof Value) {
// If the constructor has a getter we can't annotate, let's
// put the annotations on the constructor
Class constructedClass = ModelUtil.getConstructedClass((Declaration) useSite);
// See CeylonVisitor.transformSingletonConstructor for those tests
if (constructedClass.isToplevel() || constructedClass.isClassMember())
return target == OutputElement.GETTER;
return target == OutputElement.CONSTRUCTOR;
}
} else if (useSite instanceof Class) {
if (((Class) useSite).getParameterList() != null && interopTargets != null && interopTargets.contains(AnnotationTarget.CONSTRUCTOR) && !interopTargets.contains(AnnotationTarget.TYPE)) {
return target == OutputElement.CONSTRUCTOR;
}
return target == OutputElement.TYPE;
} else if (useSite instanceof Interface) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Value) {
Value value = (Value) useSite;
boolean p = value.isParameter() && target == OutputElement.PARAMETER;
if (annotationCtorDecl instanceof AnnotationProxyMethod) {
if (!value.isTransient() && (interopTargets == null || interopTargets.contains(AnnotationTarget.FIELD))) {
return target == OutputElement.FIELD;
} else {
return target == OutputElement.GETTER;
}
} else {
return p || target == OutputElement.GETTER;
}
} else if (useSite instanceof Setter) {
return target == OutputElement.SETTER;
} else if (useSite instanceof Function) {
return target == OutputElement.METHOD;
} else if (useSite instanceof Constructor) {
return target == OutputElement.CONSTRUCTOR;
} else if (useSite instanceof TypeAlias) {
return target == OutputElement.TYPE;
}
} else if (useSite instanceof Package) {
return (annotationCtorDecl instanceof AnnotationProxyMethod) ? target == OutputElement.PACKAGE : target == OutputElement.TYPE;
} else if (useSite instanceof Module) {
return target == OutputElement.TYPE;
} else if (useSite instanceof Tree.ImportModule) {
return target == OutputElement.FIELD;
}
throw new RuntimeException("" + useSite);
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method inferParameterTypesDirectly.
/**
* Infer parameter types of anonymous function arguments
* in a direct invocation with named arguments.
*
* Also sets references from arguments back to parameters
* by side effect.
*/
private void inferParameterTypesDirectly(Tree.NamedArgumentList nal, Tree.MemberOrTypeExpression mte, Declaration dec) {
Reference reference = getInvokedProducedReference(dec, mte);
Functional fun = (Functional) dec;
List<ParameterList> pls = fun.getParameterLists();
if (!pls.isEmpty()) {
Set<Parameter> foundParameters = new HashSet<Parameter>();
ParameterList pl = pls.get(0);
List<Tree.NamedArgument> args = nal.getNamedArguments();
for (int i = 0; i < args.size(); i++) {
Tree.NamedArgument arg = args.get(i);
Parameter param = getMatchingParameter(pl, arg, foundParameters);
if (param != null) {
foundParameters.add(param);
arg.setParameter(param);
if (arg instanceof Tree.SpecifiedArgument) {
Tree.SpecifiedArgument sa = (Tree.SpecifiedArgument) arg;
Tree.SpecifierExpression se = sa.getSpecifierExpression();
if (se != null) {
setupTargetParameters(reference, param, se.getExpression());
inferParameterTypes(reference, param, se.getExpression(), false, true);
}
}
}
}
Tree.SequencedArgument sa = nal.getSequencedArgument();
if (sa != null) {
Parameter param = getUnspecifiedParameter(reference, pl, foundParameters);
if (param != null) {
sa.setParameter(param);
for (Tree.PositionalArgument pa : sa.getPositionalArguments()) {
if (pa instanceof Tree.ListedArgument) {
Tree.ListedArgument la = (Tree.ListedArgument) pa;
la.setParameter(param);
setupTargetParameters(reference, param, la.getExpression());
inferParameterTypes(reference, param, la.getExpression(), true, true);
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional 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.Functional in project ceylon by eclipse.
the class ExpressionVisitor method inferParameterTypes.
/**
* Infer parameter types for anonymous functions in a
* named argument list, and set up references from
* arguments back to parameter models.
*/
private void inferParameterTypes(Tree.Primary p, Tree.NamedArgumentList nal) {
Tree.Term term = unwrapExpressionUntilTerm(p);
if (term instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) term;
Declaration dec = mte.getDeclaration();
if (dec instanceof Functional) {
inferParameterTypesDirectly(nal, mte, dec);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Functional in project ceylon by eclipse.
the class ExpressionVisitor method setupTargetParametersDirectly.
/**
* Sets references from arguments back to parameters
* in a direct invocation with positional arguments,
* special casing "coercion points" generated by the
* model loader.
*/
private void setupTargetParametersDirectly(Tree.PositionalArgumentList pal, Tree.MemberOrTypeExpression mte, Declaration dec, boolean error) {
// coercion point and use that instead
if (!error && isOverloadedVersion(dec) && !dec.isCoercionPoint()) {
Declaration abstraction = dec.getContainer().getDirectMember(dec.getName(), null, false);
if (abstraction.isAbstraction()) {
List<Declaration> overloads = abstraction.getOverloads();
if (overloads.size() == 2) {
for (Declaration overload : overloads) {
if (overload.isCoercionPoint()) {
dec = overload;
break;
}
}
}
}
}
List<Tree.PositionalArgument> args = pal.getPositionalArguments();
int argCount = args.size();
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;
setupTargetParameters(reference, param, la.getExpression());
}
if (!param.isSequenced()) {
j++;
}
}
}
}
Aggregations