Search in sources :

Example 61 with TypedDeclaration

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.SpecifierStatement that) {
    super.visit(that);
    Tree.SpecifierExpression rhs = that.getSpecifierExpression();
    Tree.Term lhs = that.getBaseMemberExpression();
    boolean hasParams = false;
    Tree.Term me = lhs;
    while (me instanceof Tree.ParameterizedExpression) {
        hasParams = true;
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
        me = pe.getPrimary();
    }
    if (!(me instanceof Tree.StaticMemberOrTypeExpression)) {
        me.addError("illegal specification statement: only a function or value may be specified");
        return;
    }
    assign(me);
    Declaration d = that.getDeclaration();
    if (d == null && me instanceof Tree.MemberOrTypeExpression) {
        Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) me;
        d = mte.getDeclaration();
    }
    if (d instanceof TypedDeclaration) {
        TypedDeclaration td = (TypedDeclaration) d;
        if (that.getRefinement()) {
            // refinement of an inherited member
            if (d instanceof Value) {
                refineAttribute(that);
            } else if (d instanceof Function) {
                refineMethod(that);
            }
            Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) me;
            smte.setDeclaration(d);
        } else if (d instanceof FunctionOrValue && !lhs.hasErrors()) {
            FunctionOrValue mv = (FunctionOrValue) d;
            if (mv.isShortcutRefinement()) {
                String desc = d instanceof Value ? "value" : "function";
                me.addError(desc + " already specified by shortcut refinement: '" + d.getName(unit) + "'");
            } else if (d instanceof Value && ((Value) d).isInferred()) {
                me.addError("value is not a variable: '" + d.getName() + "'");
            } else if (!mv.isVariable() && !mv.isLate()) {
                String desc;
                desc = d instanceof Value ? "value is neither variable nor late and" : "function";
                if (mv.isToplevel()) {
                    me.addError("toplevel " + desc + " may not be specified: '" + d.getName(unit) + "'", 803);
                } else if (!mv.isDefinedInScope(that.getScope())) {
                    me.addError(desc + " may not be specified here: '" + d.getName(unit) + "'", 803);
                }
            }
        }
        if (hasParams && d instanceof Function) {
            Function f = (Function) d;
            Tree.Expression se = rhs.getExpression();
            if (f.isDeclaredVoid() && !isSatementExpression(se)) {
                rhs.addError("function is declared void so specified expression must be a statement: '" + d.getName(unit) + "' is declared 'void'");
            }
        }
        if (rhs instanceof Tree.LazySpecifierExpression && d instanceof Value) {
            Value v = (Value) d;
            v.setTransient(true);
        }
        Type lhst = lhs.getTypeModel();
        if (!isTypeUnknown(lhst)) {
            if (lhs == me && d instanceof Function && !lhst.isTypeConstructor()) {
                // if the declaration of the method has
                // defaulted parameters, we should ignore
                // that when determining if the RHS is
                // an acceptable implementation of the
                // method
                // TODO: this is a pretty nasty way to
                // handle the problem
                lhst = eraseDefaultedParameters(lhst);
            }
            TypedDeclaration member = that.getRefinement() ? that.getRefined() : td;
            checkType(lhst, member, rhs, 2100);
        }
    }
    if (lhs instanceof Tree.ParameterizedExpression) {
        if (!(rhs instanceof Tree.LazySpecifierExpression)) {
            rhs.addError("functions with parameters must be specified using =>");
        }
    } else {
        if (rhs instanceof Tree.LazySpecifierExpression && d instanceof Function) {
            rhs.addError("functions without parameters must be specified using =");
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) 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) 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) 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) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 62 with TypedDeclaration

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

the class RefinementVisitor method checkRefinedMemberTypeExactly.

private void checkRefinedMemberTypeExactly(Reference refiningMember, Reference refinedMember, Node that, Declaration refined, Declaration refining) {
    Unit unit = that.getUnit();
    Type refiningType = refiningMember.getType();
    Type refinedType = refinedMember.getType();
    if (!isTypeUnknown(refinedType)) {
        if (that instanceof Tree.LocalModifier) {
            TypedDeclaration td = (TypedDeclaration) refining;
            Tree.LocalModifier mod = (Tree.LocalModifier) that;
            Type t;
            if (isTypeUnknown(refiningType)) {
                t = refinedType;
                td.setType(t);
                mod.setTypeModel(t);
            } else {
                checkIsExactly(refiningType, refinedType, that, "inferred type of member must be exactly the same as type of variable refined member: " + message(refined), 9000);
            }
            return;
        }
        checkIsExactlyIgnoringNull(refined, refiningType, refinedType, that, "type of member must be exactly the same as type of variable refined member: " + message(refined), 9000);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) 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) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Example 63 with TypedDeclaration

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

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

the class RefinementVisitor method checkRefinedMemberTypeAssignable.

private void checkRefinedMemberTypeAssignable(Reference refiningMember, Reference refinedMember, Node that, Declaration refined, Declaration refining) {
    Unit unit = that.getUnit();
    Type refiningType = refiningMember.getType();
    Type refinedType = refinedMember.getType();
    if (!isTypeUnknown(refinedType)) {
        if (that instanceof Tree.LocalModifier) {
            // infer the type of an actual member
            // by taking the intersection of all
            // members it refines
            // NOTE: feature not blessed by the spec!
            TypedDeclaration td = (TypedDeclaration) refining;
            Tree.LocalModifier mod = (Tree.LocalModifier) that;
            Type t;
            t = isTypeUnknown(refiningType) ? refinedType : intersectionType(refinedType, refiningType, unit);
            td.setType(t);
            mod.setTypeModel(t);
            return;
        }
        checkAssignableIgnoringNull(refiningType, refinedType, that, refined, "type of member must be assignable to type of refined member " + message(refined), 9000);
        checkSmallRefinement(that, refiningMember.getDeclaration(), refinedMember.getDeclaration());
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) 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) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Example 65 with TypedDeclaration

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

Aggregations

TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)110 Type (org.eclipse.ceylon.model.typechecker.model.Type)58 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)51 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)50 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Function (org.eclipse.ceylon.model.typechecker.model.Function)34 Value (org.eclipse.ceylon.model.typechecker.model.Value)28 Class (org.eclipse.ceylon.model.typechecker.model.Class)26 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)25 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)20 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)19 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)17 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)15