Search in sources :

Example 16 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class AnnotationModelVisitor method visit.

@Override
public void visit(Tree.BaseMemberExpression bme) {
    if (annotationConstructor != null) {
        Declaration declaration = bme.getDeclaration();
        if (checkingInvocationPrimary && isAnnotationConstructor(bme.getDeclaration())) {
            Function ctor = (Function) bme.getDeclaration();
            instantiation.setPrimary(ctor);
            if (ctor.getAnnotationConstructor() != null && ctor.getAnnotationConstructor() != instantiation) {
                for (AnnotationConstructorParameter p : ((AnnotationInvocation) ctor.getAnnotationConstructor()).getConstructorParameters()) {
                    instantiation.addConstructorParameter(p);
                }
            }
        } else if (checkingArguments || checkingDefaults) {
            if (declaration instanceof Value && ((Value) declaration).isParameter()) {
                Value constructorParameter = (Value) declaration;
                ParameterAnnotationTerm a = new ParameterAnnotationTerm();
                a.setSpread(spread);
                // XXX Is this right?
                a.setSourceParameter(constructorParameter.getInitializerParameter());
                this.term = a;
            } else if (isBooleanTrue(declaration)) {
                LiteralAnnotationTerm argument = new BooleanLiteralAnnotationTerm(true);
                appendLiteralArgument(bme, argument);
            } else if (isBooleanFalse(declaration)) {
                LiteralAnnotationTerm argument = new BooleanLiteralAnnotationTerm(false);
                appendLiteralArgument(bme, argument);
            } else if (bme.getUnit().isEmptyType(bme.getTypeModel()) && bme.getUnit().isIterableType(bme.getTypeModel()) && elements == null) {
                // If we're dealing with an iterable, empty means empty collection, not object
                endCollection(startCollection(bme), bme);
            } else if (Decl.isAnonCaseOfEnumeratedType(bme)) {
                LiteralAnnotationTerm argument = new ObjectLiteralAnnotationTerm(bme.getTypeModel());
                appendLiteralArgument(bme, argument);
            } else {
                bme.addError("compiler bug: unsupported base member expression in annotation constructor", Backend.Java);
            }
        } else {
            bme.addError("compiler bug: unsupported base member expression in annotation constructor", Backend.Java);
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 17 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function 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 18 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class ExpressionVisitor method setMetamodelType.

private void setMetamodelType(Tree.MemberLiteral that, Declaration result) {
    Type outerType;
    if (result.isClassOrInterfaceMember()) {
        Tree.StaticType type = that.getType();
        outerType = type == null ? that.getScope().getDeclaringType(result) : type.getTypeModel();
    } else {
        outerType = null;
    }
    boolean constructor = isConstructor(result);
    if (result instanceof Function) {
        Function method = (Function) result;
        if (method.isAbstraction()) {
            that.addError("method is overloaded");
        } else {
            Tree.TypeArgumentList tal = that.getTypeArgumentList();
            if (explicitTypeArguments(method, tal)) {
                List<Type> typeArgs = getTypeArguments(tal, outerType, method.getTypeParameters());
                if (tal != null) {
                    tal.setTypeModels(typeArgs);
                }
                if (acceptsTypeArguments(method, outerType, typeArgs, tal, that) || true) {
                    TypedReference pr = outerType == null ? method.appliedTypedReference(null, typeArgs) : outerType.getTypedMember(method, typeArgs);
                    that.setTarget(pr);
                    Type metatype = constructor ? unit.getConstructorMetatype(pr) : unit.getFunctionMetatype(pr);
                    that.setTypeModel(metatype);
                }
            } else {
                that.addError("missing type arguments to generic declaration: '" + method.getName(unit) + "'");
            }
        }
    } else if (result instanceof Value) {
        Value value = (Value) result;
        if (that.getTypeArgumentList() != null) {
            that.addError("does not accept type arguments: '" + result.getName(unit) + "' is a value");
        } else {
            TypedReference reference = value.appliedTypedReference(outerType, NO_TYPE_ARGS);
            that.setTarget(reference);
            Type metatype = constructor ? unit.getValueConstructorMetatype(reference) : unit.getValueMetatype(reference);
            that.setTypeModel(metatype);
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 19 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class ExpressionVisitor method substitutions.

private static Map<TypeParameter, Type> substitutions(FunctionOrValue refined, FunctionOrValue member) {
    if (refined instanceof Function) {
        Function refinedMethod = (Function) refined;
        Function method = (Function) member;
        List<TypeParameter> refinedParams = refinedMethod.getTypeParameters();
        List<TypeParameter> params = method.getTypeParameters();
        Map<TypeParameter, Type> result = new HashMap<TypeParameter, Type>(params.size());
        for (int i = 0; i < refinedParams.size() && i < params.size(); i++) {
            result.put(refinedParams.get(i), params.get(i).getType());
        }
        return result;
    } else {
        return NO_SUBSTITUTIONS;
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) HashMap(java.util.HashMap) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint)

Example 20 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function 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");
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) Function(org.eclipse.ceylon.model.typechecker.model.Function) 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) 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) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) 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) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Aggregations

Function (org.eclipse.ceylon.model.typechecker.model.Function)167 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)70 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)69 Type (org.eclipse.ceylon.model.typechecker.model.Type)68 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)62 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)57 Value (org.eclipse.ceylon.model.typechecker.model.Value)50 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)46 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)43 Class (org.eclipse.ceylon.model.typechecker.model.Class)39 ArrayList (java.util.ArrayList)32 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)29 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)23 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)23 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21