Search in sources :

Example 51 with ClassOrInterface

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

the class RefinementVisitor method checkMember.

private void checkMember(Tree.Declaration that, Declaration member) {
    String name = member.getName();
    if (name == null) {
        return;
    }
    if (member instanceof Setter) {
        Setter setter = (Setter) member;
        Value getter = setter.getGetter();
        Declaration rd = getter.getRefinedDeclaration();
        member.setRefinedDeclaration(rd);
        return;
    }
    ClassOrInterface type = (ClassOrInterface) member.getContainer();
    if (member.isFormal() && type instanceof Class) {
        Class c = (Class) type;
        if (!c.isAbstract() && !c.isFormal()) {
            if (c.isClassOrInterfaceMember()) {
                that.addError("formal member belongs to concrete nested class: '" + member.getName() + "' is a member of class '" + c.getName() + "' which is neither 'abstract' nor 'formal'", 1100);
            } else {
                that.addError("formal member belongs to concrete class: '" + member.getName() + "' is a member of class '" + c.getName() + "' which is not annotated 'abstract'", 1100);
            }
        }
    }
    if (member.isStatic() && !type.isToplevel()) {
        that.addError("static member belongs to a nested class: '" + member.getName() + "' is a member of nested type '" + type.getName() + "'");
    }
    if (type.isDynamic()) {
        if (member instanceof Class) {
            that.addError("member class belongs to dynamic interface");
        } else if (!member.isFormal()) {
            that.addError("non-formal member belongs to dynamic interface");
        }
    }
    if (member instanceof Functional && !that.hasErrors() && isOverloadedVersion(member)) {
        checkOverloadedAnnotation(that, member);
        checkOverloadedParameters(that, member);
    }
    checkRefinement(that, member, type);
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 52 with ClassOrInterface

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

the class RefinementVisitor method refineAttribute.

private void refineAttribute(Value assignedAttribute, Tree.BaseMemberExpression bme, Tree.SpecifierStatement that, ClassOrInterface c) {
    if (!assignedAttribute.isFormal() && !assignedAttribute.isDefault() && !assignedAttribute.isShortcutRefinement()) {
        // this condition is here to squash a dupe message
        that.addError("inherited attribute may not be assigned in initializer and may not be refined: " + message(assignedAttribute) + " is declared neither 'formal' nor 'default'", 510);
    // return;
    } else if (assignedAttribute.isVariable()) {
        that.addError("inherited attribute may not be assigned in initializer and may not be refined by non-variable: " + message(assignedAttribute) + " is declared 'variable'");
    // return;
    }
    ClassOrInterface ci = (ClassOrInterface) assignedAttribute.getContainer();
    String name = assignedAttribute.getName();
    Declaration refined = ci.getRefinedMember(name, null, false);
    Value root = refined instanceof Value ? (Value) refined : assignedAttribute;
    Reference rv = getRefinedMemberReference(assignedAttribute, c);
    boolean lazy = that.getSpecifierExpression() instanceof Tree.LazySpecifierExpression;
    Value attribute = new Value();
    attribute.setName(name);
    attribute.setShared(true);
    attribute.setActual(true);
    attribute.getAnnotations().add(new Annotation("shared"));
    attribute.getAnnotations().add(new Annotation("actual"));
    attribute.setRefinedDeclaration(root);
    Unit unit = that.getUnit();
    attribute.setUnit(unit);
    attribute.setContainer(c);
    attribute.setScope(c);
    attribute.setShortcutRefinement(true);
    attribute.setTransient(lazy);
    Declaration rvd = rv.getDeclaration();
    if (rvd instanceof TypedDeclaration) {
        TypedDeclaration rvtd = (TypedDeclaration) rvd;
        attribute.setUncheckedNullType(rvtd.hasUncheckedNullType());
    }
    ModelUtil.setVisibleScope(attribute);
    c.addMember(attribute);
    that.setRefinement(true);
    that.setDeclaration(attribute);
    that.setRefined(assignedAttribute);
    unit.addDeclaration(attribute);
    setRefiningType(c, ci, name, null, false, root, attribute, unit, NO_SUBSTITUTIONS);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ExpressionVisitor.getRefinedMemberReference(org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor.getRefinedMemberReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation)

Example 53 with ClassOrInterface

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

the class RefinementVisitor method refineMethod.

private void refineMethod(Function assignedMethod, Tree.BaseMemberExpression bme, Tree.SpecifierStatement that, ClassOrInterface c) {
    if (!assignedMethod.isFormal() && !assignedMethod.isDefault() && !assignedMethod.isShortcutRefinement()) {
        // this condition is here to squash a dupe message
        bme.addError("inherited method may not be refined: " + message(assignedMethod) + " is declared neither 'formal' nor 'default'", 510);
    // return;
    }
    ClassOrInterface ci = (ClassOrInterface) assignedMethod.getContainer();
    String name = assignedMethod.getName();
    List<Type> signature = getSignature(assignedMethod);
    boolean variadic = isVariadic(assignedMethod);
    Declaration refined = ci.getRefinedMember(name, signature, variadic);
    Function root = refined instanceof Function ? (Function) refined : assignedMethod;
    Reference rm = getRefinedMemberReference(assignedMethod, c);
    Function method = new Function();
    method.setName(name);
    List<Tree.ParameterList> paramLists;
    List<TypeParameter> typeParams;
    Tree.Term me = that.getBaseMemberExpression();
    if (me instanceof Tree.ParameterizedExpression) {
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
        paramLists = pe.getParameterLists();
        Tree.TypeParameterList typeParameterList = pe.getTypeParameterList();
        if (typeParameterList != null) {
            typeParams = new ArrayList<TypeParameter>();
            for (Tree.TypeParameterDeclaration tpd : typeParameterList.getTypeParameterDeclarations()) {
                typeParams.add(tpd.getDeclarationModel());
            }
        } else {
            typeParams = null;
        }
    } else {
        paramLists = emptyList();
        typeParams = null;
    }
    Unit unit = that.getUnit();
    final Map<TypeParameter, Type> subs;
    if (typeParams != null) {
        // the type parameters are written
        // down in the shortcut refinement
        method.setTypeParameters(typeParams);
        // TODO: check 'em!!
        // no need to check them because
        // this case is actually disallowed
        // elsewhere (specification statements
        // may not have type parameters)
        subs = NO_SUBSTITUTIONS;
    } else if (assignedMethod.isParameterized()) {
        if (me instanceof Tree.ParameterizedExpression) {
            // we have parameters, but no type parameters
            bme.addError("refined method is generic: '" + assignedMethod.getName(unit) + "' declares type parameters");
            subs = NO_SUBSTITUTIONS;
        } else {
            // we're assigning a method reference
            // so we need to magic up some "fake"
            // type parameters
            subs = copyTypeParametersFromRefined(assignedMethod, method, unit);
        }
    } else {
        subs = NO_SUBSTITUTIONS;
    }
    int i = 0;
    for (ParameterList pl : assignedMethod.getParameterLists()) {
        Tree.ParameterList params = paramLists.size() <= i ? null : paramLists.get(i++);
        createRefiningParameterList(rm, method, params, unit, subs, pl);
    }
    method.setShared(true);
    method.setActual(true);
    method.getAnnotations().add(new Annotation("shared"));
    method.getAnnotations().add(new Annotation("actual"));
    method.setRefinedDeclaration(root);
    method.setUnit(unit);
    method.setContainer(c);
    method.setScope(c);
    method.setShortcutRefinement(true);
    method.setDeclaredVoid(assignedMethod.isDeclaredVoid());
    Declaration rmd = rm.getDeclaration();
    if (rmd instanceof TypedDeclaration) {
        TypedDeclaration rmtd = (TypedDeclaration) rmd;
        method.setUncheckedNullType(rmtd.hasUncheckedNullType());
    }
    ModelUtil.setVisibleScope(method);
    c.addMember(method);
    that.setRefinement(true);
    that.setDeclaration(method);
    that.setRefined(root);
    unit.addDeclaration(method);
    Scope scope = that.getScope();
    if (scope instanceof Specification) {
        Specification spec = (Specification) scope;
        spec.setDeclaration(method);
    }
    setRefiningType(c, ci, name, signature, variadic, root, method, unit, subs);
    inheritDefaultedArguments(method);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Function(org.eclipse.ceylon.model.typechecker.model.Function) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) 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.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ExpressionVisitor.getRefinedMemberReference(org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor.getRefinedMemberReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Specification(org.eclipse.ceylon.model.typechecker.model.Specification) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.erasedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.erasedType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList)

Example 54 with ClassOrInterface

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

the class DeclarationVisitor method handleNativeHeader.

private void handleNativeHeader(Declaration model, String name) {
    // Deal with implementations from the ModelLoader
    ArrayList<FunctionOrValue> loadedFunctionsOrValues = null;
    ArrayList<ClassOrInterface> loadedClasses = null;
    ArrayList<Constructor> loadedConstructors = null;
    for (Backend backendToSearch : Backend.getRegisteredBackends()) {
        Declaration overloadFromModelLoader = model.getContainer().getDirectMemberForBackend(name, backendToSearch.asSet());
        if (overloadFromModelLoader instanceof FunctionOrValue) {
            if (loadedFunctionsOrValues == null) {
                loadedFunctionsOrValues = new ArrayList<FunctionOrValue>();
            }
            FunctionOrValue fov = (FunctionOrValue) overloadFromModelLoader;
            loadedFunctionsOrValues.add(fov);
        } else if (overloadFromModelLoader instanceof ClassOrInterface) {
            if (loadedClasses == null) {
                loadedClasses = new ArrayList<ClassOrInterface>();
            }
            ClassOrInterface c = (ClassOrInterface) overloadFromModelLoader;
            loadedClasses.add(c);
        } else if (overloadFromModelLoader instanceof Constructor) {
            if (loadedConstructors == null) {
                loadedConstructors = new ArrayList<Constructor>();
            }
            Constructor c = (Constructor) overloadFromModelLoader;
            loadedConstructors.add(c);
        }
    }
    // Initialize the header's overloads
    if (model instanceof FunctionOrValue) {
        FunctionOrValue m = (FunctionOrValue) model;
        if (loadedFunctionsOrValues != null) {
            m.initOverloads(loadedFunctionsOrValues.toArray(NO_FUNCTIONS_OR_VALUES));
        } else {
            m.initOverloads();
        }
    } else if (model instanceof ClassOrInterface) {
        ClassOrInterface c = (ClassOrInterface) model;
        if (loadedClasses != null) {
            c.initOverloads(loadedClasses.toArray(NO_CLASSES));
        } else {
            c.initOverloads();
        }
    } else if (model instanceof Constructor) {
        Constructor c = (Constructor) model;
        if (loadedConstructors != null) {
            c.initOverloads(loadedConstructors.toArray(NO_CONSTRUCTORS));
        } else {
            c.initOverloads();
        }
    }
}
Also used : ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Backend(org.eclipse.ceylon.common.Backend) TreeUtil.getNativeBackend(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.getNativeBackend) 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) ArrayList(java.util.ArrayList) 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) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 55 with ClassOrInterface

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.AttributeDeclaration that) {
    Value v = new Value();
    that.setDeclarationModel(v);
    Tree.SpecifierOrInitializerExpression sie = that.getSpecifierOrInitializerExpression();
    boolean lazy = sie instanceof Tree.LazySpecifierExpression;
    v.setTransient(lazy);
    v.setImplemented(sie != null);
    visitDeclaration(that, v);
    if (!lazy && v.isVariable() && v.isStatic()) {
        Scope container = v.getContainer();
        if (container instanceof ClassOrInterface) {
            ClassOrInterface ci = (ClassOrInterface) container;
            if (!ci.getTypeParameters().isEmpty()) {
                that.addError("attribute of generic type may not be annotated both 'variable' and 'static'");
            }
        }
    }
    Scope o = null;
    // if (lazy)
    o = enterScope(v);
    super.visit(that);
    // if (lazy)
    exitScope(o);
    if (v.isInterfaceMember() && !v.isFormal() && !v.isNative()) {
        if (sie == null) {
            that.addError("interface attribute must be annotated 'formal'", 1400);
        }
    }
    if (v.isLate()) {
        if (lazy) {
            that.addError("late attribute should specify initial value using '='");
        }
        if (v.isFormal()) {
            that.addError("formal attribute may not be annotated 'late'");
        } else if (v.isDefault()) {
            that.addError("default attribute may not be annotated 'late'");
        } else if (!v.isClassOrInterfaceMember() && !v.isToplevel()) {
            that.addError("block-local value may not be annotated 'late'");
        }
    }
    if (v.isFormal() && sie != null) {
        that.addError("formal attribute may not have a value", 1102);
    }
    Tree.Type type = that.getType();
    if (type instanceof Tree.ValueModifier) {
        if (v.isToplevel()) {
            if (sie == null) {
                type.addError("toplevel value must explicitly specify a type");
            } else {
                type.addError("toplevel value must explicitly specify a type", 200);
            }
        } else if (mustHaveExplicitType(v)) {
            type.addError("shared value must explicitly specify a type", 200);
        }
    }
}
Also used : ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) 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) 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)

Aggregations

ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)102 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)62 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)46 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 Class (org.eclipse.ceylon.model.typechecker.model.Class)24 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)20 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)19 Value (org.eclipse.ceylon.model.typechecker.model.Value)19 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)18 ArrayList (java.util.ArrayList)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)14 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)13 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)12 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)12