Search in sources :

Example 6 with Constructor

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.ClassDeclaration that) {
    super.visit(that);
    Class alias = that.getDeclarationModel();
    Type et = alias.getExtendedType();
    Tree.ClassSpecifier cs = that.getClassSpecifier();
    if (cs != null && et != null) {
        TypeDeclaration etd = et.getDeclaration();
        if (etd instanceof Constructor) {
            etd = etd.getExtendedType().getDeclaration();
        }
        if (etd instanceof Class) {
            // TODO: some of this belongs in InheritanceVisitor!
            Class c = (Class) etd;
            if (c.isAbstract()) {
                if (!alias.isFormal() && !alias.isAbstract()) {
                    that.addError("alias of abstract class must be annotated abstract", 310);
                }
            }
            if (c.isAbstraction()) {
                that.addError("class alias may not alias overloaded class");
            } else {
                Tree.InvocationExpression ie = cs.getInvocationExpression();
                if (ie != null) {
                    checkClassAliasParameters(alias, that, ie);
                }
            }
        }
    }
}
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) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ModelUtil.findMatchingOverloadedClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.findMatchingOverloadedClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) 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 7 with Constructor

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.QualifiedType that) {
    super.visit(that);
    TypeDeclaration type = that.getDeclarationModel();
    if (type != null) {
        type = (TypeDeclaration) handleNativeHeader(type, that, true);
        if (!type.isVisible(that.getScope())) {
            if (type instanceof Constructor) {
                that.addError("constructor is not visible: " + qualifiedDescription(that), 400);
            } else {
                that.addError("member type is not visible: " + qualifiedDescription(that), 400);
            }
        } else if (type.isPackageVisibility() && !declaredInPackage(type, unit)) {
            that.addError("member type is not visible: " + qualifiedDescription(that) + " is package private");
        } else // in fact this restriction is OK
        if (type.isProtectedVisibility() && !declaredInPackage(type, unit)) {
            that.addError("member type is not visible: " + qualifiedDescription(that) + " is protected");
        }
        // Note: we should remove this check if we ever
        // make qualified member types like T.Member
        // into a sort of virtual type
        Tree.StaticType outerType = that.getOuterType();
        if (outerType instanceof Tree.SimpleType) {
            Tree.SimpleType st = (Tree.SimpleType) outerType;
            TypeDeclaration std = st.getDeclarationModel();
            if (std.isAlias()) {
                Type et = std.getExtendedType();
                if (et != null) {
                    std = et.resolveAliases().getDeclaration();
                }
            }
            if (std instanceof TypeParameter) {
                outerType.addError("type parameter should not occur as qualifying type: '" + std.getName(unit) + "' is a type parameter");
            }
        }
    }
}
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) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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 8 with Constructor

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.Enumerated that) {
    Constructor e = new Constructor();
    that.setEnumerated(e);
    visitDeclaration(that, e, false);
    Type at;
    if (scope instanceof Class) {
        Class clazz = (Class) scope;
        Type ot = clazz.getType();
        e.setExtendedType(ot);
        at = e.appliedType(ot, NO_TYPE_ARGS);
        clazz.setEnumerated(true);
        if (clazz.isAnonymous()) {
            that.addError("anonymous class may not have a value constructor: '" + clazz.getName() + "' is an anonymous class");
        } else if (clazz.isAbstract()) {
            that.addError("abstract class may not have a value constructor: '" + clazz.getName() + "' is abstract");
        } else if (!clazz.getTypeParameters().isEmpty()) {
            that.addError("generic class may not have a value constructor: '" + clazz.getName() + "' is generic");
        } else if (scope.getContainer() instanceof Interface) {
            that.addError("class nested inside an interface may not have a value constructor: '" + clazz.getName() + "' belongs to an interface");
        }
    } else {
        at = null;
        that.addError("value constructor declaration must occur directly in the body of a class");
    }
    Value v = new Value();
    v.setType(at);
    that.setDeclarationModel(v);
    visitDeclaration(that, v);
    Scope o = enterScope(e);
    super.visit(that);
    exitScope(o);
    v.setImplemented(that.getBlock() != null);
}
Also used : IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypeVisitor.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeVisitor.getTupleType) 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.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) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) 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) 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 9 with Constructor

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

the class ClassTransformer method makeDelegateToCompanion.

/**
 * Generates a method which delegates to the companion instance $Foo$impl
 */
private MethodDefinitionBuilder makeDelegateToCompanion(Interface iface, Reference typedMember, Type currentType, final long mods, final java.util.List<TypeParameter> typeParameters, final java.util.List<java.util.List<Type>> producedTypeParameterBounds, final Type methodType, final String methodName, final java.util.List<Parameter> parameters, boolean typeErased, final String targetMethodName, Parameter defaultedParam, boolean includeBody) {
    final MethodDefinitionBuilder concreteWrapper = MethodDefinitionBuilder.systemMethod(gen(), methodName);
    concreteWrapper.modifiers(mods);
    concreteWrapper.ignoreModelAnnotations();
    if ((mods & PRIVATE) == 0) {
        concreteWrapper.isOverride(true);
    }
    if (typeParameters != null) {
        concreteWrapper.reifiedTypeParametersFromModel(typeParameters);
    }
    Iterator<java.util.List<Type>> iterator = producedTypeParameterBounds.iterator();
    if (typeParameters != null) {
        for (TypeParameter tp : typeParameters) {
            concreteWrapper.typeParameter(tp, iterator.next());
        }
    }
    boolean explicitReturn = false;
    Declaration member = (defaultedParam != null ? typedMember.getTypedParameter(defaultedParam) : typedMember).getDeclaration();
    Type returnType = null;
    if (!isAnything(methodType) || ((member instanceof Function || member instanceof Value) && !Decl.isUnboxedVoid(member)) || (member instanceof Function && Strategy.useBoxedVoid((Function) member))) {
        explicitReturn = true;
        if (CodegenUtil.isHashAttribute(member)) {
            // delegates for hash attributes are int
            concreteWrapper.resultType(new TransformedType(make().Type(syms().intType)));
            returnType = typedMember.getType();
        } else if (typedMember instanceof TypedReference && defaultedParam == null) {
            TypedReference typedRef = (TypedReference) typedMember;
            // This is very much like for method refinement: if the supertype is erased -> go raw.
            // Except for some reason we only need to do it with multiple inheritance with different type
            // arguments, so let's not go overboard
            int flags = 0;
            if (CodegenUtil.hasTypeErased((TypedDeclaration) member.getRefinedDeclaration()) || CodegenUtil.hasTypeErased((TypedDeclaration) member) && isInheritedTwiceWithDifferentTypeArguments(currentType, iface)) {
                flags |= AbstractTransformer.JT_RAW;
            }
            concreteWrapper.resultTypeNonWidening(currentType, typedRef, typedMember.getType(), flags);
            // FIXME: this is redundant with what we computed in the previous line in concreteWrapper.resultTypeNonWidening
            TypedReference nonWideningTypedRef = gen().nonWideningTypeDecl(typedRef, currentType);
            returnType = gen().nonWideningType(typedRef, nonWideningTypedRef);
        } else if (defaultedParam != null) {
            TypedReference typedParameter = typedMember.getTypedParameter(defaultedParam);
            NonWideningParam nonWideningParam = concreteWrapper.getNonWideningParam(typedParameter, currentType.getDeclaration() instanceof Class ? WideningRules.FOR_MIXIN : WideningRules.NONE);
            returnType = nonWideningParam.nonWideningType;
            if (member instanceof Function)
                returnType = typeFact().getCallableType(returnType);
            concreteWrapper.resultType(new TransformedType(makeJavaType(returnType, nonWideningParam.flags)));
        } else {
            concreteWrapper.resultType(new TransformedType(makeJavaType((Type) typedMember)));
            returnType = (Type) typedMember;
        }
    }
    ListBuffer<JCExpression> arguments = new ListBuffer<JCExpression>();
    if (typeParameters != null) {
        for (TypeParameter tp : typeParameters) {
            arguments.add(naming.makeUnquotedIdent(naming.getTypeArgumentDescriptorName(tp)));
        }
    }
    Declaration declaration = typedMember.getDeclaration();
    if (declaration instanceof Constructor && !Decl.isDefaultConstructor((Constructor) declaration) && defaultedParam == null) {
        concreteWrapper.parameter(makeConstructorNameParameter((Constructor) declaration));
        arguments.add(naming.makeUnquotedIdent(Unfix.$name$));
    }
    int ii = 0;
    for (Parameter param : parameters) {
        Parameter parameter;
        if (declaration instanceof Functional) {
            parameter = ((Functional) declaration).getFirstParameterList().getParameters().get(ii++);
        } else if (declaration instanceof Setter) {
            parameter = ((Setter) declaration).getParameter();
        } else {
            throw BugException.unhandledDeclarationCase(declaration);
        }
        final TypedReference typedParameter = typedMember.getTypedParameter(parameter);
        concreteWrapper.parameter(null, param, typedParameter, null, FINAL, WideningRules.FOR_MIXIN);
        arguments.add(naming.makeName(param.getModel(), Naming.NA_MEMBER | Naming.NA_ALIASED));
    }
    if (includeBody) {
        JCExpression qualifierThis = makeUnquotedIdent(getCompanionFieldName(iface));
        // our impl accessor to get the expected bounds of the qualifying type
        if (explicitReturn) {
            Type javaType = getBestSatisfiedType(currentType, iface);
            Type ceylonType = typedMember.getQualifyingType();
            // don't even bother if the impl accessor is turned to raw because casting it to raw doesn't help
            if (!isTurnedToRaw(ceylonType) && // if it's exactly the same we don't need any cast
            !javaType.isExactly(ceylonType))
                // this will add the proper cast to the impl accessor
                qualifierThis = expressionGen().applyErasureAndBoxing(qualifierThis, currentType, false, true, BoxingStrategy.BOXED, ceylonType, ExpressionTransformer.EXPR_WANTS_COMPANION);
        }
        JCExpression expr = make().Apply(// TODO Type args
        null, makeSelect(qualifierThis, (targetMethodName != null) ? targetMethodName : methodName), arguments.toList());
        if (isUnimplementedMemberClass(currentType, typedMember)) {
            concreteWrapper.body(makeThrowUnresolvedCompilationError(// TODO encapsulate the error message
            "formal member '" + declaration.getName() + "' of '" + iface.getName() + "' not implemented in class hierarchy"));
            current().broken();
        } else if (!explicitReturn) {
            concreteWrapper.body(gen().make().Exec(expr));
        } else {
            // deal with erasure and stuff
            BoxingStrategy boxingStrategy;
            boolean exprBoxed;
            if (member instanceof TypedDeclaration) {
                TypedDeclaration typedDecl = (TypedDeclaration) member;
                exprBoxed = !CodegenUtil.isUnBoxed(typedDecl);
                boxingStrategy = CodegenUtil.getBoxingStrategy(typedDecl);
            } else {
                // must be a class or interface
                exprBoxed = true;
                boxingStrategy = BoxingStrategy.UNBOXED;
            }
            // to force an additional cast
            if (isTurnedToRaw(typedMember.getQualifyingType()) || // in invariant locations
            needsRawCastForMixinSuperCall(iface, methodType) || needsCastForErasedInstantiator(iface, methodName, member))
                typeErased = true;
            expr = gen().expressionGen().applyErasureAndBoxing(expr, methodType, typeErased, exprBoxed, boxingStrategy, returnType, 0);
            concreteWrapper.body(gen().make().Return(expr));
        }
    }
    return concreteWrapper;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) NonWideningParam(org.eclipse.ceylon.compiler.java.codegen.MethodDefinitionBuilder.NonWideningParam) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)

Example 10 with Constructor

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

the class ClassTransformer method transformClassAlias.

private void transformClassAlias(final Tree.ClassDeclaration def, ClassDefinitionBuilder classBuilder) {
    ClassAlias model = (ClassAlias) def.getDeclarationModel();
    Type aliasedClass = model.getExtendedType();
    TypeDeclaration classOrCtor = def.getClassSpecifier().getType().getDeclarationModel();
    while (classOrCtor instanceof ClassAlias) {
        classOrCtor = ((ClassAlias) classOrCtor).getConstructor();
    }
    classBuilder.annotations(makeAtAlias(aliasedClass, classOrCtor instanceof Constructor ? (Constructor) classOrCtor : null));
    classBuilder.isAlias(true);
    MethodDefinitionBuilder instantiator = transformClassAliasInstantiator(def, model, aliasedClass);
    ClassDefinitionBuilder cbInstantiator = null;
    switch(Strategy.defaultParameterMethodOwner(model)) {
        case STATIC:
            cbInstantiator = classBuilder;
            break;
        case OUTER:
            cbInstantiator = classBuilder.getContainingClassBuilder();
            break;
        case OUTER_COMPANION:
            cbInstantiator = classBuilder.getContainingClassBuilder().getCompanionBuilder(ModelUtil.getClassOrInterfaceContainer(model, true));
            break;
        default:
            throw BugException.unhandledEnumCase(Strategy.defaultParameterMethodOwner(model));
    }
    cbInstantiator.method(instantiator);
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) Type(org.eclipse.ceylon.model.typechecker.model.Type) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Aggregations

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14