Search in sources :

Example 26 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration 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)

Example 27 with Declaration

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

the class AnnotationVisitor method visit.

@Override
public void visit(Tree.Annotation that) {
    super.visit(that);
    Tree.MemberOrTypeExpression primary = (Tree.MemberOrTypeExpression) that.getPrimary();
    Declaration dec = primary.getDeclaration();
    /*if (dec!=null && !dec.isToplevel()) {
            that.getPrimary().addError("annotation must be a toplevel function reference");
        }*/
    if (dec != null) {
        if (!dec.isAnnotation()) {
            primary.addError("not an annotation constructor: '" + dec.getName(that.getUnit()) + "'");
        } else {
            String pname = dec.getUnit().getPackage().getNameAsString();
            String name = dec.getName();
            switch(pname) {
                case "java.lang":
                    switch(name) {
                        case "deprecated":
                            that.addError("illegal Java annotation (use 'deprecated' in 'ceylon.language')");
                            break;
                        case "override":
                            that.addError("illegal Java annotation (use 'actual' in 'ceylon.language')");
                            break;
                    }
                    break;
                case "java.lang.annotation":
                    switch(name) {
                        case "target":
                        case "retention":
                            that.addError("illegal Java annotation");
                    }
            }
            checkAnnotationArguments(null, (Tree.InvocationExpression) that);
        }
    }
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 28 with Declaration

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

the class AnnotationVisitor method checkAnnotations.

private void checkAnnotations(Tree.AnnotationList annotationList, Type declarationType, Type modelType, Node that) {
    Unit unit = annotationList.getUnit();
    List<Tree.Annotation> annotations = annotationList.getAnnotations();
    for (Tree.Annotation annotation : annotations) {
        Type t = annotation.getTypeModel();
        if (t != null) {
            TypeDeclaration cad = unit.getConstrainedAnnotationDeclaration();
            Type cat = t.getSupertype(cad);
            if (cat != null) {
                // check *Ceylon* annotation constraints
                List<Type> args = cat.getTypeArgumentList();
                if (args.size() > 2) {
                    Type constraint = args.get(2);
                    checkAssignable(declarationType, constraint, annotation, "annotated program element does not satisfy annotation constraint");
                }
                if (args.size() > 3) {
                    Type constraint = args.get(3);
                    if (!constraint.isAnything()) {
                        checkAssignable(modelType, constraint, annotation, "annotated program element does not satisfy annotation constraint");
                    }
                }
            }
            EnumSet<AnnotationTarget> target = null;
            Tree.Primary primary = annotation.getPrimary();
            if (primary instanceof Tree.MemberOrTypeExpression) {
                Declaration ac = ((Tree.MemberOrTypeExpression) primary).getDeclaration();
                if (ac instanceof TypedDeclaration) {
                    target = ((TypedDeclaration) ac).getAnnotationTargets();
                }
            }
            if (target != null) {
                // check the *Java* annotation constraints
                boolean ok = false;
                if (that instanceof Tree.PackageDescriptor) {
                    if (target.contains(PACKAGE)) {
                        ok = true;
                    }
                }
                if (that instanceof Tree.InterfaceDefinition) {
                    if (target.contains(TYPE)) {
                        ok = true;
                    }
                }
                if (that instanceof Tree.ClassDefinition) {
                    Tree.ClassDefinition c = (Tree.ClassDefinition) that;
                    boolean initializer = c.getParameterList() != null;
                    if (target.contains(TYPE)) {
                        // it always goes on the class,
                        // not on the constructor
                        ok = true;
                    }
                    if (target.contains(CONSTRUCTOR) && initializer) {
                        // it goes on the constructor
                        ok = true;
                    }
                    if (target.contains(ANNOTATION_TYPE) && c.getDeclarationModel().isAnnotation()) {
                        // it goes on the annotation type
                        ok = true;
                    }
                }
                if (that instanceof Tree.ObjectDefinition) {
                    if (target.contains(FIELD)) {
                        ok = true;
                    }
                }
                if (that instanceof Tree.Constructor || that instanceof Tree.Enumerated) {
                    if (target.contains(CONSTRUCTOR)) {
                        ok = true;
                    }
                }
                if (that instanceof Tree.MethodDefinition || that instanceof Tree.MethodDeclaration || that instanceof Tree.AttributeGetterDefinition || that instanceof Tree.AttributeSetterDefinition) {
                    if (target.contains(METHOD)) {
                        // it goes on the method, getter,
                        // or setter, unambiguously
                        ok = true;
                    }
                }
                if (that instanceof Tree.AttributeDeclaration) {
                    Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) that;
                    Value model = ad.getDeclarationModel();
                    boolean parameter = model.isParameter();
                    boolean classMember = model.isClassMember();
                    boolean toplevel = model.isToplevel();
                    boolean local = !toplevel && !model.isClassOrInterfaceMember();
                    if (target.contains(PARAMETER) && parameter) {
                        // in this case there is a parameter,
                        // so the annotation *never* goes on
                        // the field, getter, nor setter
                        ok = true;
                    }
                    Tree.SpecifierOrInitializerExpression se = ad.getSpecifierOrInitializerExpression();
                    if (se instanceof Tree.LazySpecifierExpression || model.isFormal()) {
                        if (target.contains(METHOD)) {
                            // there is no field, so it
                            // goes on the getter
                            ok = true;
                        }
                    } else {
                        // if it's cannot go on the field
                        if (classMember || toplevel) {
                            if (target.contains(FIELD)) {
                                ok = true;
                            } else if (target.contains(METHOD)) {
                                ok = true;
                            }
                        }
                        if (target.contains(LOCAL_VARIABLE) && !parameter && local) {
                            ok = true;
                        }
                    }
                }
                if (!ok) {
                    StringBuilder message = new StringBuilder();
                    for (AnnotationTarget at : target) {
                        if (message.length() > 0) {
                            message.append(", ");
                        }
                        message.append(at);
                    }
                    annotation.addError("annotated program element does not satisfy annotation constraint: the annotation is declared 'target {" + message + "}'");
                }
            }
        }
    }
    TypeDeclaration od = unit.getOptionalAnnotationDeclaration();
    for (int i = 0; i < annotations.size(); i++) {
        Tree.Annotation ann = annotations.get(i);
        Type t = ann.getTypeModel();
        if (t != null) {
            TypeDeclaration td = t.getDeclaration();
            // this implicitly excludes Java annotations but they are checked in the backend for duplicates
            if (td.inherits(od)) {
                for (int j = 0; j < i; j++) {
                    Tree.Annotation other = annotations.get(j);
                    Type ot = other.getTypeModel();
                    if (ot != null) {
                        TypeDeclaration otd = ot.getDeclaration();
                        if (otd.equals(td)) {
                            ann.addError("duplicate annotation: there are multiple annotations of type '" + td.getName() + "'");
                            break;
                        }
                    }
                }
            }
        }
    }
}
Also used : Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) AnnotationTarget(org.eclipse.ceylon.model.loader.model.AnnotationTarget) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Type(org.eclipse.ceylon.model.typechecker.model.Type) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 29 with Declaration

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

the class AnnotationVisitor method checkServiceAnnotations.

private void checkServiceAnnotations(Class clazz, Tree.AnnotationList annotationList) {
    for (Tree.Annotation ann : annotationList.getAnnotations()) {
        Tree.BaseMemberExpression p = (Tree.BaseMemberExpression) ann.getPrimary();
        Declaration pd = p.getDeclaration();
        if (pd != null) {
            Declaration sd = ann.getUnit().getLanguageModuleDeclaration("service");
            if (pd.equals(sd)) {
                checkServiceImplementation(clazz, getService(ann), ann);
            }
        }
    }
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 30 with Declaration

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

the class ExpressionVisitor method handleStaticReferenceImplicitTypeArguments.

/**
 * Validate the type arguments to the qualifying type
 * in a static reference when no type arguments are
 * given explicitly.
 *
 * This is called later than usual because the type args
 * might be inferrable from an invocation of the whole
 * static reference.
 *
 * @param that the static reference
 */
private void handleStaticReferenceImplicitTypeArguments(Tree.QualifiedMemberOrTypeExpression that) {
    Declaration member = that.getDeclaration();
    Tree.TypeArguments tas = that.getTypeArguments();
    // without type arguments to the qualifying type
    if (isStaticReference(that)) {
        if (member != null && !explicitTypeArguments(member, tas)) {
            that.addError("type arguments could not be inferred: '" + member.getName(unit) + "' is generic");
        }
        // the reference to the qualifying type
        Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) that.getPrimary();
        // we have to get the type args from the tree
        // here because the calling code doesn't know
        // them (it is walking the qualifying reference)
        Tree.TypeArguments typeArgs = smte.getTypeArguments();
        TypeDeclaration type = (TypeDeclaration) smte.getDeclaration();
        if (type != null && !explicitTypeArguments(type, typeArgs) && typeArgs.getTypeModels() == null) {
            // nothing inferred
            Declaration declaration = smte.getDeclaration();
            smte.addError("missing type arguments to generic type qualifying static reference: '" + declaration.getName(unit) + "' declares type parameters " + typeParameterList(declaration));
        }
    }
    Tree.Primary primary = that.getPrimary();
    if (!that.getDirectlyInvoked() && (member.isStatic() || isConstructor(member)) && primary instanceof Tree.StaticMemberOrTypeExpression) {
        Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) primary;
        Declaration qualifyingType = smte.getDeclaration();
        Tree.TypeArguments qtas = smte.getTypeArguments();
        if (qualifyingType != null && qualifyingType.isParameterized() && !qualifyingType.isJava() && !explicitTypeArguments(qualifyingType, qtas)) {
            if (explicitTypeArguments(member, tas)) {
                Type functionType = genericFunctionType(qualifyingType, that.getScope(), member, that.getTarget(), unit);
                that.setTypeModel(functionType);
                checkNotJvm(that, "type functions are not supported on the JVM: '" + qualifyingType.getName(unit) + "' is generic (specify explicit type arguments)");
            } else {
                that.addError("missing explicit type arguments to generic qualifying type: '" + qualifyingType.getName(unit) + "' declares type parameters " + typeParameterList(qualifyingType));
            }
        }
    }
}
Also used : 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) 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) 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

Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)370 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)309 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)264 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)129 Type (org.eclipse.ceylon.model.typechecker.model.Type)100 Class (org.eclipse.ceylon.model.typechecker.model.Class)78 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)74 Value (org.eclipse.ceylon.model.typechecker.model.Value)73 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)72 Function (org.eclipse.ceylon.model.typechecker.model.Function)71 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)71 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)63 ArrayList (java.util.ArrayList)61 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)60 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)60 ModelUtil.getNativeDeclaration (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration)57 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)51 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)50 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)48 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)45