Search in sources :

Example 6 with Functional

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);
}
Also used : AnnotationTarget(org.eclipse.ceylon.model.loader.model.AnnotationTarget) AnnotationProxyMethod(org.eclipse.ceylon.model.loader.model.AnnotationProxyMethod) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Value(org.eclipse.ceylon.model.typechecker.model.Value) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Package(org.eclipse.ceylon.model.typechecker.model.Package) Module(org.eclipse.ceylon.model.typechecker.model.Module) Interface(org.eclipse.ceylon.model.typechecker.model.Interface)

Example 7 with Functional

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);
                    }
                }
            }
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) HashSet(java.util.HashSet)

Example 8 with Functional

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);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 9 with Functional

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);
        }
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 10 with Functional

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++;
            }
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Aggregations

Functional (org.eclipse.ceylon.model.typechecker.model.Functional)58 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)30 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)28 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)28 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)25 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)24 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)24 Type (org.eclipse.ceylon.model.typechecker.model.Type)22 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)13 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)13 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)12 Value (org.eclipse.ceylon.model.typechecker.model.Value)12 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)11 Class (org.eclipse.ceylon.model.typechecker.model.Class)11 Function (org.eclipse.ceylon.model.typechecker.model.Function)11 Reference (org.eclipse.ceylon.model.typechecker.model.Reference)11 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)10 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)9 AnalyzerUtil.checkCasesDisjoint (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint)8