Search in sources :

Example 61 with Interface

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

the class ExpressionVisitor method handleExpressionParameterList.

private Type handleExpressionParameterList(Tree.ParameterizedExpression that, Tree.MemberOrTypeExpression mte, Type pt, Tree.ParameterList pl) {
    Interface cd = unit.getCallableDeclaration();
    Type ct = pt.getSupertype(cd);
    String refName = mte.getDeclaration().getName();
    if (ct == null) {
        pl.addError("no matching parameter list in referenced declaration: '" + refName + "'");
    } else if (ct.getTypeArgumentList().size() >= 2) {
        Type tupleType = ct.getTypeArgumentList().get(1);
        List<Type> argTypes = unit.getTupleElementTypes(tupleType);
        boolean variadic = unit.isTupleLengthUnbounded(tupleType);
        boolean atLeastOne = unit.isTupleVariantAtLeastOne(tupleType);
        List<Tree.Parameter> params = pl.getParameters();
        if (argTypes.size() != params.size()) {
            pl.addError("wrong number of declared parameters: '" + refName + "' has " + argTypes.size() + " parameters");
        }
        for (int i = 0; i < argTypes.size() && i < params.size(); i++) {
            Type at = argTypes.get(i);
            Tree.Parameter param = params.get(i);
            Parameter model = param.getParameterModel();
            // TODO: for #1329 this is not working yet
            // because the parameters of a specification
            // all wind up getting shoved into the
            // namespace of the containing Declaration
            // back in DeclarationVisitor, when by rights
            // they should belong to the Specification,
            // which means they all get muddled up with
            // each other (this is probably causing other
            // bugs too!)
            /*Reference ref = mte.getTarget();
                Declaration fakeDec = model.getDeclaration();
                if (pt.isTypeConstructor()) {
                    List<Type> typeArgs = 
                            typeParametersAsArgList(
                                    pt.getDeclaration());
                    ref = fakeDec.appliedReference(null, typeArgs);
                                
                }
                else {
                    ref = fakeDec.getReference();
                }
                Type paramType = 
                        ref.getTypedParameter(model)
                            .getFullType();*/
            Type paramType = model.getModel().getTypedReference().getFullType();
            if (!isTypeUnknown(paramType) && !isTypeUnknown(at) && !at.isSubtypeOf(paramType)) {
                param.addError("type of parameter '" + model.getName() + "' must be a supertype of corresponding parameter type in declaration of '" + refName + "'");
            }
        }
        if (!params.isEmpty()) {
            Tree.Parameter lastParam = params.get(params.size() - 1);
            Parameter model = lastParam.getParameterModel();
            boolean refSequenced = model.isSequenced();
            boolean refAtLeastOne = model.isAtLeastOne();
            if (refSequenced && !variadic) {
                lastParam.addError("parameter list in declaration of '" + refName + "' does not have a variadic parameter");
            } else if (!refSequenced && variadic) {
                lastParam.addError("parameter list in declaration of '" + refName + "' has a variadic parameter");
            } else if (refAtLeastOne && !atLeastOne) {
                lastParam.addError("variadic parameter in declaration of '" + refName + "' is optional");
            } else if (!refAtLeastOne && atLeastOne) {
                lastParam.addError("variadic parameter in declaration of '" + refName + "' is not optional");
            }
        }
        pt = ct.getTypeArgumentList().get(0);
        that.setTypeModel(pt);
    }
    return pt;
}
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.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) ArrayList(java.util.ArrayList) ModelUtil.typeParametersAsArgList(org.eclipse.ceylon.model.typechecker.model.ModelUtil.typeParametersAsArgList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) 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)

Example 62 with Interface

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

the class ExpressionVisitor method warnIfCustomEquals.

private void warnIfCustomEquals(Node node, TypeDeclaration dec) {
    // reasonable definitions of equality
    if (!dec.isJavaEnum()) {
        Declaration eq = dec.getMember("equals", Arrays.asList(unit.getObjectType()), false);
        if (eq != null) {
            Scope container = eq.getContainer();
            if (container instanceof TypeDeclaration) {
                TypeDeclaration td = (TypeDeclaration) container;
                Interface id = unit.getIdentifiableDeclaration();
                if (!container.equals(id)) {
                    node.addUsageWarning(Warning.valueEqualityIgnored, "value equality defined by type '" + td.getName(unit) + "' ignored (identity equality is used to match value case)");
                }
            }
        }
    }
}
Also used : NativeUtil.declarationScope(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) 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)

Example 63 with Interface

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.InterfaceDefinition that) {
    Interface i = that.getDeclarationModel();
    Declaration od = beginReturnDeclaration(i);
    Tree.Type rt = beginReturnScope(null);
    super.visit(that);
    endReturnScope(rt, null);
    endReturnDeclaration(od);
}
Also used : 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) 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)

Example 64 with Interface

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.AnyInterface that) {
    Interface i = that.getDeclarationModel();
    that.setDeclarationModel(i);
    visitDeclaration(that, i);
    Scope o = enterScope(i);
    super.visit(that);
    exitScope(o);
}
Also used : Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 65 with Interface

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

the class DeclarationVisitor method checkForNativeAnnotation.

private void checkForNativeAnnotation(Tree.Declaration that, Declaration model, Scope scope) {
    Unit unit = model.getUnit();
    if (model.isNative()) {
        Backends mbackends = model.getNativeBackends();
        boolean isHeader = model.isNativeHeader();
        String name = model.getName();
        boolean canBeNative = canBeNative(that);
        if (canBeNative) {
            Backends moduleBackends = unit.getPackage().getModule().getNativeBackends();
            Backends backends = model.getScope().getScopedBackends();
            if (!isHeader && !moduleBackends.none() && !mbackends.supports(moduleBackends)) {
                that.addError("native backend name on declaration conflicts with module descriptor: '\"" + mbackends.names() + "\"' is not '\"" + moduleBackends.names() + "\"' for '" + name + "'");
            } else if (!isHeader && !backends.none() && !backends.supports(mbackends)) {
                that.addError("native backend for declaration conflicts with its scope: native implementation '" + name + "' for '\"" + mbackends.names() + "\"' occurs in a scope which only supports '\"" + backends.names() + "\"'");
            }
            if (isHeader && existImplementations(model)) {
                that.addError("native header must be declared before its implementations: the native header '" + name + "' is declared after an implementation");
            }
            if (model instanceof Interface && ((Interface) model).isAlias()) {
                that.addError("interface alias may not be marked native: '" + name + "' (add a body if a native interface was intended)");
            }
            model.setNativeBackends(mbackends);
            Declaration member = getNativeHeader(model);
            if (member == null || member.isNativeImplementation()) {
                // it's not shared
                if (!isHeader && mustHaveHeader(model) && !moduleBackends.equals(mbackends)) {
                    that.addError("shared native implementation must have a header: '" + model.getName() + "' has no native header");
                }
            }
            if (member == null) {
                if (model.isNativeHeader()) {
                    handleNativeHeader(model, name);
                    if (that instanceof Tree.ObjectDefinition) {
                        Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                        handleNativeHeader(od.getAnonymousClass(), name);
                    } else if (that instanceof Tree.Constructor) {
                        Tree.Constructor c = (Tree.Constructor) that;
                        handleNativeHeader(c.getConstructor(), name);
                    }
                } else {
                    member = model.getContainer().getDirectMemberForBackend(model.getName(), mbackends);
                    if (member != null && member != model) {
                        that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    }
                }
            } else {
                if (member.isNative()) {
                    List<Declaration> overloads = member.getOverloads();
                    if (isHeader && member.isNativeHeader()) {
                        that.addError("duplicate native header: the header for '" + name + "' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    } else {
                        Declaration overload = findOverloadForBackend(mbackends, model, overloads);
                        if (overload != null) {
                            that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                            unit.getDuplicateDeclarations().add(overload);
                        }
                    }
                    if (isAllowedToChangeModel(member) && !hasModelInOverloads(model, overloads)) {
                        overloads.add(model);
                        if (that instanceof Tree.ObjectDefinition) {
                            Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                            Declaration objImplCls = od.getAnonymousClass();
                            Value value = (Value) member;
                            Class objHdrCls = (Class) value.getType().getDeclaration();
                            objHdrCls.getOverloads().add(objImplCls);
                        } else if (that instanceof Tree.Constructor) {
                            Tree.Constructor c = (Tree.Constructor) that;
                            Declaration cd = c.getConstructor();
                            FunctionOrValue fov = (FunctionOrValue) member;
                            Constructor hdr = (Constructor) fov.getType().getDeclaration();
                            hdr.getOverloads().add(cd);
                        }
                    }
                } else {
                    if (isHeader) {
                        that.addError("native header for non-native declaration: '" + name + "' is not declared native");
                    } else {
                        that.addError("native implementation for non-native header: '" + name + "' is not declared native");
                    }
                }
            }
        } else if (!(model instanceof Setter) && !isHeader) {
            if (!canBeNative) {
                that.addError("native declaration is not a class, constructor, method, attribute or object: '" + name + "' may not be annotated 'native'");
            }
        }
    }
}
Also used : ModelUtil.isDefaultConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isDefaultConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Backends(org.eclipse.ceylon.common.Backends) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) ModelUtil.isAnonymousClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isAnonymousClass) 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) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

Interface (org.eclipse.ceylon.model.typechecker.model.Interface)105 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)99 Type (org.eclipse.ceylon.model.typechecker.model.Type)64 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)58 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)40 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)35 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)32 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)32 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)29 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 ModelUtil.getOuterClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface)20 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)20 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)19 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)19 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)18 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)18