Search in sources :

Example 46 with Value

use of com.redhat.ceylon.model.typechecker.model.Value in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformMemberReference.

JCExpression transformMemberReference(Tree.QualifiedMemberOrTypeExpression expr, Tree.MemberOrTypeExpression primary) {
    Declaration member = expr.getDeclaration();
    Type qualifyingType = primary.getTypeModel();
    Tree.TypeArguments typeArguments = expr.getTypeArguments();
    boolean prevSyntheticClassBody = withinSyntheticClassBody(true);
    try {
        if (member.isStaticallyImportable()) {
            if (member instanceof Function) {
                Function method = (Function) member;
                Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
                return CallableBuilder.javaStaticMethodReference(gen(), expr.getTypeModel(), method, producedReference).build();
            } else if (member instanceof FieldValue) {
                return naming.makeName((TypedDeclaration) member, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED);
            } else if (member instanceof Value) {
                CallBuilder callBuilder = CallBuilder.instance(this);
                JCExpression qualExpr = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) member.getContainer(), DeclNameFlag.QUALIFIED);
                callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
                return callBuilder.build();
            } else if (member instanceof Class) {
                Reference producedReference = expr.getTarget();
                return CallableBuilder.javaStaticMethodReference(gen(), expr.getTypeModel(), (Class) member, producedReference).build();
            }
        }
        if (member instanceof Value) {
            if (expr.getStaticMethodReference() && Decl.isEnumeratedConstructor((Value) member)) {
                CallBuilder callBuilder = CallBuilder.instance(this);
                JCExpression qualExpr;
                Class class1 = (Class) member.getContainer();
                if (class1.isToplevel()) {
                    qualExpr = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) member.getContainer(), DeclNameFlag.QUALIFIED);
                    callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
                } else if (class1.isMember()) {
                    // creates a Callable<Outer.Inner,[Outer]> that returns the enumeratedConstructor given an outer instance
                    if (primary instanceof Tree.QualifiedMemberOrTypeExpression && ((Tree.QualifiedMemberOrTypeExpression) primary).getPrimary() instanceof Tree.BaseTypeExpression)
                        return CallableBuilder.unboundValueMemberReference(gen(), expr, expr.getTypeModel(), ((TypedDeclaration) member)).build();
                    else {
                        qualExpr = primary instanceof Tree.QualifiedMemberOrTypeExpression ? transformExpression(((Tree.QualifiedMemberOrTypeExpression) primary).getPrimary()) : null;
                        callBuilder.invoke(naming.makeQualifiedName(qualExpr, (TypedDeclaration) member, Naming.NA_GETTER | Naming.NA_MEMBER));
                    }
                } else {
                    callBuilder.fieldRead(naming.makeName((TypedDeclaration) member, Naming.NA_IDENT));
                }
                return callBuilder.build();
            } else {
                return CallableBuilder.unboundValueMemberReference(gen(), expr, expr.getTypeModel(), ((TypedDeclaration) member)).build();
            }
        } else if (Decl.isConstructor(member)) {
            Reference producedReference = expr.getTarget();
            return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), Decl.getConstructor(member), producedReference).build();
        } else if (member instanceof Function) {
            Function method = (Function) member;
            if (!method.isParameter()) {
                Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
                return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), method, producedReference).build();
            } else {
                Reference producedReference = method.appliedReference(qualifyingType, typeArguments.getTypeModels());
                return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), method, producedReference).build();
            }
        } else if (member instanceof Class) {
            Reference producedReference = expr.getTarget();
            return CallableBuilder.unboundFunctionalMemberReference(gen(), expr, expr.getTypeModel(), (Class) member, producedReference).build();
        } else {
            return makeErroneous(expr, "compiler bug: member reference of " + expr + " not supported yet");
        }
    } finally {
        withinSyntheticClassBody(prevSyntheticClassBody);
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 47 with Value

use of com.redhat.ceylon.model.typechecker.model.Value in project ceylon-compiler by ceylon.

the class ClassTransformer method makeAttributeForValueParameter.

private void makeAttributeForValueParameter(ClassDefinitionBuilder classBuilder, Tree.Parameter parameterTree, Tree.TypedDeclaration memberTree) {
    Parameter decl = parameterTree.getParameterModel();
    if (!(decl.getModel() instanceof Value)) {
        return;
    }
    final Value value = (Value) decl.getModel();
    if (decl.getDeclaration() instanceof Constructor) {
        classBuilder.field(PUBLIC | FINAL, decl.getName(), makeJavaType(decl.getType()), null, false, expressionGen().transformAnnotations(OutputElement.FIELD, memberTree));
        classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualIdent(naming.makeThis(), decl.getName()), naming.makeName(value, Naming.NA_IDENT))));
    } else if (parameterTree instanceof Tree.ValueParameterDeclaration && (value.isShared() || value.isCaptured())) {
        makeFieldForParameter(classBuilder, decl, memberTree);
        AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, decl.getName(), decl.getModel());
        adb.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
        adb.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, memberTree));
        classBuilder.attribute(adb);
        if (value.isVariable()) {
            AttributeDefinitionBuilder setter = AttributeDefinitionBuilder.setter(this, decl.getName(), decl.getModel());
            setter.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
            //setter.userAnnotations(expressionGen().transform(AnnotationTarget.SETTER, memberTree.getAnnotationList()));
            classBuilder.attribute(setter);
        }
    } else if (decl.isHidden() && // TODO Isn't this always true here? We know this is a parameter to a Class
    (decl.getDeclaration() instanceof TypeDeclaration)) {
        Declaration member = CodegenUtil.findMethodOrValueForParam(decl);
        if (Strategy.createField(decl, (Value) member)) {
            // The field itself is created by when we transform the AttributeDeclaration 
            // but it has to be initialized here so all the fields are initialized in parameter order
            JCExpression parameterExpr = makeUnquotedIdent(Naming.getAliasedParameterName(decl));
            TypedReference typedRef = getTypedReference(value);
            TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
            Type paramType = nonWideningType(typedRef, nonWideningTypedRef);
            if (!paramType.isExactly(decl.getType())) {
                // The parameter type follows normal erasure rules, not affected by inheritance
                // but the attribute respects non-widening rules, so we may need to cast
                // the parameter to the field type (see #1728)
                parameterExpr = make().TypeCast(classGen().transformClassParameterType(decl), parameterExpr);
            }
            classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualifiedName(naming.makeThis(), value, Naming.NA_IDENT), parameterExpr)));
        }
    }
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 48 with Value

use of com.redhat.ceylon.model.typechecker.model.Value in project ceylon-compiler by ceylon.

the class ClassTransformer method refineValue.

private Value refineValue(Value formalAttribute, TypedReference producedValue, Scope container, Unit unit) {
    Value refined = new Value();
    refined.setActual(true);
    refined.setContainer(container);
    refined.setName(formalAttribute.getName());
    refined.setRefinedDeclaration(formalAttribute.getRefinedDeclaration());
    refined.setScope(container);
    refined.setVariable(formalAttribute.isVariable());
    refined.setShared(formalAttribute.isShared());
    refined.setTransient(formalAttribute.isTransient());
    // TODO
    refined.setType(producedValue.getType());
    refined.setTypeErased(formalAttribute.getTypeErased());
    refined.setUnboxed(formalAttribute.getUnboxed());
    refined.setUntrustedType(formalAttribute.getUntrustedType());
    refined.setUnit(unit);
    return refined;
}
Also used : FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value)

Example 49 with Value

use of com.redhat.ceylon.model.typechecker.model.Value in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformAssignment.

private JCExpression transformAssignment(Node op, Tree.Term leftTerm, Tree.Term rightTerm) {
    // Remember and disable inStatement for RHS
    boolean tmpInStatement = inStatement;
    inStatement = false;
    // FIXME: can this be anything else than a Tree.MemberOrTypeExpression or Tree.ParameterizedExpression?
    final JCExpression rhs;
    BoxingStrategy boxing;
    if (leftTerm instanceof Tree.MemberOrTypeExpression) {
        TypedDeclaration decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression) leftTerm).getDeclaration();
        boxing = CodegenUtil.getBoxingStrategy(decl);
        if (decl instanceof Value) {
            Value val = (Value) decl;
            if (val.getSetter() != null && val.getSetter().getUnboxed() != null) {
                boxing = CodegenUtil.getBoxingStrategy(val.getSetter());
            }
        }
        Type targetType = tmpInStatement ? leftTerm.getTypeModel() : rightTerm.getTypeModel();
        // if we're dealing with widening do not trust the type of the declaration and get the real type
        if (CodegenUtil.hasUntrustedType(decl)) {
            TypedReference typedRef = (TypedReference) ((Tree.MemberOrTypeExpression) leftTerm).getTarget();
            TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
            targetType = nonWideningType(typedRef, nonWideningTypedRef);
        }
        rhs = transformExpression(rightTerm, boxing, targetType, decl.hasUncheckedNullType() ? EXPR_TARGET_ACCEPTS_NULL : 0);
    } else {
        // instanceof Tree.ParameterizedExpression
        boxing = CodegenUtil.getBoxingStrategy(leftTerm);
        Tree.ParameterizedExpression paramExpr = (Tree.ParameterizedExpression) leftTerm;
        FunctionOrValue decl = (FunctionOrValue) ((Tree.MemberOrTypeExpression) paramExpr.getPrimary()).getDeclaration();
        CallableBuilder callableBuilder = CallableBuilder.anonymous(gen(), paramExpr, decl, (Tree.Expression) rightTerm, paramExpr.getParameterLists(), paramExpr.getPrimary().getTypeModel(), decl instanceof Function ? !((Function) decl).isDeferred() : false);
        rhs = callableBuilder.build();
    }
    if (tmpInStatement) {
        return transformAssignment(op, leftTerm, rhs);
    } else {
        Type valueType = rightTerm.getTypeModel();
        if (isNull(valueType))
            valueType = leftTerm.getTypeModel();
        return transformAssignAndReturnOperation(op, leftTerm, boxing == BoxingStrategy.BOXED, leftTerm.getTypeModel(), valueType, new AssignAndReturnOperationFactory() {

            @Override
            public JCExpression getNewValue(JCExpression previousValue) {
                return rhs;
            }
        });
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 50 with Value

use of com.redhat.ceylon.model.typechecker.model.Value in project ceylon-compiler by ceylon.

the class ExpressionTransformer method addThisOrObjectQualifierIfRequired.

/**
     * We may need to force a qualified this prefix (direct or outer) in the following cases:
     * 
     * - Required because of mixin inheritance with different type arguments (the same is already
     *   done for qualified references, but not for direct references)
     * - The compiler generates anonymous local classes for things like
     *   Callables and Comprehensions. When referring to a member foo 
     *   within one of those things we need a qualified {@code this}
     *   to ensure we're accessing the outer instances member, not 
     *   a member of the anonymous local class that happens to have the same name.
     */
private JCExpression addThisOrObjectQualifierIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
    if (qualExpr == null && // statics are not members that can be inherited
    !decl.isStaticallyImportable() && !Decl.isConstructor(decl) && decl.isMember() && // and have a name mapping)
    expr.getTarget().getDeclaration() == decl && !Decl.isLocalToInitializer(decl) && !isWithinSuperInvocation()) {
        // First check whether the expression is captured from an enclosing scope
        TypeDeclaration outer = null;
        // get the ClassOrInterface container of the declaration
        Scope stop = Decl.getClassOrInterfaceContainer(decl, false);
        if (stop instanceof TypeDeclaration) {
            // reified scope
            Scope scope = expr.getScope();
            while (!(scope instanceof Package)) {
                if (scope.equals(stop)) {
                    outer = (TypeDeclaration) stop;
                    break;
                }
                scope = scope.getContainer();
            }
        }
        // If not it might be inherited...
        if (outer == null) {
            outer = expr.getScope().getInheritingDeclaration(decl);
        }
        if (outer != null) {
            Type targetType = expr.getTarget().getQualifyingType();
            Type declarationContainerType = ((TypeDeclaration) outer).getType();
            // check if we need a variance cast
            VarianceCastResult varianceCastResult = getVarianceCastResult(targetType, declarationContainerType);
            // if we are within a comprehension body, or if we need a variance cast
            if (isWithinSyntheticClassBody() || varianceCastResult != null) {
                if (decl.isShared() && outer instanceof Interface) {
                    // always prefer qualified
                    qualExpr = makeQualifiedDollarThis(declarationContainerType);
                } else {
                    // Class or companion class,
                    qualExpr = naming.makeQualifiedThis(makeJavaType(((TypeDeclaration) outer).getType(), JT_RAW | (outer instanceof Interface ? JT_COMPANION : 0)));
                }
                // add the variance cast if required
                if (varianceCastResult != null) {
                    qualExpr = applyVarianceCasts(qualExpr, targetType, varianceCastResult, 0);
                }
            }
        } else if (decl.isClassMember() && ((Class) decl.getContainer()).isAnonymous() && ((Class) decl.getContainer()).isToplevel()) {
            Class container = (Class) decl.getContainer();
            Value value = (Value) ((Package) container.getContainer()).getMember(container.getName(), null, false);
            qualExpr = make().Apply(null, naming.makeName(value, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER), List.<JCExpression>nil());
        } else if (decl.isMember() && !expr.getStaticMethodReference()) {
            throw new BugException(expr, decl.getQualifiedNameString() + " was unexpectedly a member");
        }
    }
    return qualExpr;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) Scope(com.redhat.ceylon.model.typechecker.model.Scope) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) Package(com.redhat.ceylon.model.typechecker.model.Package) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Aggregations

Value (com.redhat.ceylon.model.typechecker.model.Value)54 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)39 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)28 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)27 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)27 Function (com.redhat.ceylon.model.typechecker.model.Function)25 Type (com.redhat.ceylon.model.typechecker.model.Type)23 Class (com.redhat.ceylon.model.typechecker.model.Class)19 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)19 JavaBeanValue (com.redhat.ceylon.model.loader.model.JavaBeanValue)16 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)15 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)14 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)14 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)13 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)12 JCTree (com.sun.tools.javac.tree.JCTree)12 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)11 FieldValue (com.redhat.ceylon.model.loader.model.FieldValue)11 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)11 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)11