Search in sources :

Example 96 with Declaration

use of com.redhat.ceylon.model.typechecker.model.Declaration 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 97 with Declaration

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

the class ExpressionTransformer method checkForByteLiterals.

private JCExpression checkForByteLiterals(Tree.InvocationExpression ce) {
    // same test as in BoxingVisitor.isByteLiteral()
    if (ce.getPrimary() instanceof Tree.BaseTypeExpression && ce.getPositionalArgumentList() != null) {
        java.util.List<Tree.PositionalArgument> positionalArguments = ce.getPositionalArgumentList().getPositionalArguments();
        if (positionalArguments.size() == 1) {
            PositionalArgument argument = positionalArguments.get(0);
            if (argument instanceof Tree.ListedArgument && ((Tree.ListedArgument) argument).getExpression() != null) {
                Term term = ((Tree.ListedArgument) argument).getExpression().getTerm();
                boolean negative = false;
                if (term instanceof Tree.NegativeOp) {
                    negative = true;
                    term = ((Tree.NegativeOp) term).getTerm();
                }
                if (term instanceof Tree.NaturalLiteral) {
                    Declaration decl = ((Tree.BaseTypeExpression) ce.getPrimary()).getDeclaration();
                    if (decl instanceof Class) {
                        String name = decl.getQualifiedNameString();
                        if (name.equals("ceylon.language::Byte")) {
                            at(ce);
                            try {
                                long value = literalValue((Tree.NaturalLiteral) term);
                                if (negative)
                                    value = -value;
                                // assignment, not for method calls, so it's simpler to always cast
                                return make().TypeCast(syms().byteType, make().Literal(value));
                            } catch (ErroneousException e) {
                                // replaced with a throw.
                                return e.makeErroneous(this);
                            }
                        }
                    }
                }
            }
        }
    }
    return null;
}
Also used : PositionalArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) TreeUtil.unwrapExpressionUntilTerm(com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) 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)

Example 98 with Declaration

use of com.redhat.ceylon.model.typechecker.model.Declaration 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 99 with Declaration

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

the class CodegenUtil method isContainerFunctionalParameter.

public static boolean isContainerFunctionalParameter(Declaration declaration) {
    Scope containerScope = declaration.getContainer();
    Declaration containerDeclaration;
    if (containerScope instanceof Specification) {
        containerDeclaration = ((Specification) containerScope).getDeclaration();
    } else if (containerScope instanceof Declaration) {
        containerDeclaration = (Declaration) containerScope;
    } else {
        throw BugException.unhandledCase(containerScope);
    }
    return containerDeclaration instanceof Function && ((Function) containerDeclaration).isParameter();
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Specification(com.redhat.ceylon.model.typechecker.model.Specification) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 100 with Declaration

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

the class ExpressionTransformer method transformQualifiedInstantiation.

private JCExpression transformQualifiedInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
    Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) invocation.getPrimary();
    Declaration declaration = qte.getDeclaration();
    invocation.location(callBuilder);
    if (Decl.isJavaStaticOrInterfacePrimary(invocation.getPrimary())) {
        callBuilder.instantiate(transformedPrimary.expr);
    } else if (!Strategy.generateInstantiator(declaration)) {
        if (Decl.isConstructorPrimary(invocation.getPrimary())) {
            if (Decl.getConstructedClass(invocation.getPrimaryDeclaration()).isMember()) /*&& invocation.getPrimary() instanceof Tree.QualifiedTypeExpression
                        && !(((Tree.QualifiedTypeExpression)invocation.getPrimary()).getPrimary() instanceof Tree.BaseTypeExpression)*/
            {
                callBuilder.instantiate(new ExpressionAndType(transformedPrimary.expr, null), makeJavaType(invocation.getReturnType(), JT_CLASS_NEW | (transformedPrimary.expr == null ? 0 : JT_NON_QUALIFIED)));
            } else {
                callBuilder.instantiate(makeJavaType(invocation.getReturnType(), JT_CLASS_NEW));
            }
        } else {
            JCExpression qualifier;
            JCExpression qualifierType;
            if (declaration.getContainer() instanceof Interface) {
                // When doing qualified invocation through an interface we need
                // to get the companion.
                Interface qualifyingInterface = (Interface) declaration.getContainer();
                qualifier = transformedPrimary.expr;
                qualifierType = makeJavaType(qualifyingInterface.getType(), JT_COMPANION);
            } else {
                qualifier = transformedPrimary.expr;
                if (declaration.getContainer() instanceof TypeDeclaration) {
                    qualifierType = makeJavaType(((TypeDeclaration) declaration.getContainer()).getType());
                } else {
                    qualifierType = null;
                }
            }
            Type classType = (Type) qte.getTarget();
            JCExpression type;
            // special case for package-qualified things that are not really qualified
            if (qualifier == null) {
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
            } else {
                // Note: here we're not fully qualifying the class name because the JLS says that if "new" is qualified the class name
                // is qualified relative to it
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED);
            }
            callBuilder.instantiate(new ExpressionAndType(qualifier, qualifierType), type);
        }
    } else {
        // instantiator
        callBuilder.typeArguments(List.<JCExpression>nil());
        java.util.List<Type> typeModels = qte.getTypeArguments().getTypeModels();
        if (typeModels != null) {
            for (Type tm : typeModels) {
                callBuilder.typeArgument(makeJavaType(tm, AbstractTransformer.JT_TYPE_ARGUMENT));
            }
        }
        callBuilder.invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, Decl.getConstructedClass(declaration)));
    }
    JCExpression result = callBuilder.build();
    if (Strategy.isInstantiatorUntyped(declaration)) {
        result = make().TypeCast(makeJavaType(invocation.getReturnType()), result);
    }
    return result;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) List(com.sun.tools.javac.util.List) CondList(com.redhat.ceylon.compiler.java.codegen.StatementTransformer.CondList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) 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

Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)107 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)95 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)80 Type (com.redhat.ceylon.model.typechecker.model.Type)34 Function (com.redhat.ceylon.model.typechecker.model.Function)33 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)30 Class (com.redhat.ceylon.model.typechecker.model.Class)28 Value (com.redhat.ceylon.model.typechecker.model.Value)28 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)27 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)27 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)24 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)22 JCTree (com.sun.tools.javac.tree.JCTree)22 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)21 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)20 Interface (com.redhat.ceylon.model.typechecker.model.Interface)20 Scope (com.redhat.ceylon.model.typechecker.model.Scope)20 Package (com.redhat.ceylon.model.typechecker.model.Package)17 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)17 ArrayList (java.util.ArrayList)16