Search in sources :

Example 66 with Function

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

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

the class ExpressionTransformer method transform.

JCExpression transform(Tree.FunctionArgument functionArg, Type expectedType) {
    Function model = functionArg.getDeclarationModel();
    List<JCStatement> body;
    boolean prevNoExpressionlessReturn = statementGen().noExpressionlessReturn;
    boolean prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
    try {
        statementGen().noExpressionlessReturn = isAnything(model.getType());
        if (functionArg.getBlock() != null) {
            body = statementGen().transformBlock(functionArg.getBlock());
            if (!functionArg.getBlock().getDefinitelyReturns()) {
                if (isAnything(model.getType())) {
                    body = body.append(make().Return(makeNull()));
                } else {
                    body = body.append(make().Return(makeErroneous(functionArg.getBlock(), "compiler bug: non-void method does not definitely return")));
                }
            }
        } else {
            Tree.Expression expr = functionArg.getExpression();
            JCExpression transExpr = expressionGen().transformExpression(expr);
            JCReturn returnStat = make().Return(transExpr);
            body = List.<JCStatement>of(returnStat);
        }
    } finally {
        expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
        statementGen().noExpressionlessReturn = prevNoExpressionlessReturn;
    }
    //functionArg.getTypeModel();
    Type callableType = model.getTypedReference().getFullType();
    CallableBuilder callableBuilder = CallableBuilder.methodArgument(gen(), functionArg, model, callableType, Collections.singletonList(functionArg.getParameterLists().get(0)), classGen().transformMplBody(functionArg.getParameterLists(), model, body));
    JCExpression result = callableBuilder.build();
    result = applyErasureAndBoxing(result, callableType, true, BoxingStrategy.BOXED, expectedType);
    return result;
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 68 with Function

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

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

the class ExpressionTransformer method transformAssignment.

private JCExpression transformAssignment(Node op, Tree.Term leftTerm, JCExpression lhs, JCExpression rhs) {
    JCExpression result = null;
    // FIXME: can this be anything else than a Tree.StaticMemberOrTypeExpression or Tree.ParameterizedExpression?
    TypedDeclaration decl;
    if (leftTerm instanceof Tree.StaticMemberOrTypeExpression) {
        decl = (TypedDeclaration) ((Tree.StaticMemberOrTypeExpression) leftTerm).getDeclaration();
        lhs = addInterfaceImplAccessorIfRequired(lhs, (Tree.StaticMemberOrTypeExpression) leftTerm, decl);
        lhs = addThisOrObjectQualifierIfRequired(lhs, (Tree.StaticMemberOrTypeExpression) leftTerm, decl);
    } else {
        // instanceof Tree.ParameterizedExpression
        decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression) ((Tree.ParameterizedExpression) leftTerm).getPrimary()).getDeclaration();
    }
    boolean variable = decl.isVariable();
    at(op);
    String selector = naming.selector(decl, Naming.NA_SETTER);
    if (decl.isToplevel()) {
        // must use top level setter
        lhs = naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER);
    } else if (Decl.isGetter(decl)) {
        if (Decl.isTransient(decl) && !decl.isVariable()) {
            JCExpression attr = gen().transformAttributeGetter(decl, rhs);
            result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER), attr);
        } else {
            // must use the setter
            if (Decl.isLocal(decl)) {
                lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER | Naming.NA_SETTER);
            } else if (decl.isStaticallyImportable()) {
                lhs = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) decl.getContainer(), DeclNameFlag.QUALIFIED);
            }
        }
    } else if (decl instanceof Function && Decl.isDeferred(decl)) {
        if (Decl.isLocal(decl)) {
            // Deferred method initialization of a local function
            // The Callable field has the same name as the method, so use NA_MEMBER
            result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER_UNQUOTED | Naming.NA_MEMBER), rhs);
        } else {
            // Deferred method initialization of a class function
            result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_MEMBER), rhs);
        }
    } else if ((variable || decl.isLate()) && (Decl.isClassAttribute(decl))) {
        // must use the setter, nothing to do, unless it's a java field
        if (Decl.isJavaField(decl)) {
            if (decl.isStaticallyImportable()) {
                // static field
                result = at(op).Assign(naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED), rhs);
            } else {
                // normal field
                result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
            }
        }
    } else if (variable && (decl.isCaptured() || decl.isShared())) {
        // must use the qualified setter
        if (Decl.isBoxedVariable(decl)) {
            result = at(op).Assign(naming.makeName(decl, Naming.NA_Q_LOCAL_INSTANCE | Naming.NA_MEMBER | Naming.NA_SETTER), rhs);
        } else if (Decl.isLocalNotInitializer(decl)) {
            lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER);
        } else if (isWithinSuperInvocation() && decl.isCaptured() && decl.isVariable()) {
            lhs = naming.makeUnquotedIdent(Naming.getAliasedParameterName(((Value) decl).getInitializerParameter()));
            result = at(op).Assign(lhs, rhs);
        }
    } else {
        result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
    }
    if (result == null) {
        result = make().Apply(List.<JCTree.JCExpression>nil(), makeQualIdent(lhs, selector), List.<JCTree.JCExpression>of(rhs));
    }
    return result;
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 70 with Function

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

the class ExpressionTransformer method transform.

private List<JCAnnotation> transform(Object useSite, OutputElement target, Tree.AnnotationList annotationList, EnumSet<OutputElement> outputs) {
    if (annotationList == null) {
        return List.nil();
    }
    if ((gen().disableAnnotations & CeylonTransformer.DISABLE_USER_ANNOS) != 0) {
        return List.nil();
    }
    LinkedHashMap<Class, ListBuffer<JCAnnotation>> annotationSet = new LinkedHashMap<>();
    if (annotationList != null) {
        if (annotationList.getAnonymousAnnotation() != null && isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("doc"), useSite, target)) {
            transformAnonymousAnnotation(annotationList.getAnonymousAnnotation(), annotationSet);
        }
        if (annotationList.getAnnotations() != null) {
            for (Tree.Annotation annotation : annotationList.getAnnotations()) {
                Function annoCtorDecl = ((Function) ((Tree.BaseMemberExpression) annotation.getPrimary()).getDeclaration());
                EnumSet<OutputElement> possibleTargets = AnnotationUtil.interopAnnotationTargeting(outputs, annotation, false);
                if ((isNaturalTarget(annoCtorDecl, useSite, target) && possibleTargets == null) || (possibleTargets != null && possibleTargets.equals(EnumSet.of(target)))) {
                    transformAnnotation(annotation, annotationSet);
                }
            }
        }
    }
    ListBuffer<JCAnnotation> result = ListBuffer.lb();
    for (Class annotationClass : annotationSet.keySet()) {
        ListBuffer<JCAnnotation> annotations = annotationSet.get(annotationClass);
        if (isSequencedAnnotation(annotationClass)) {
            JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(annotationClass.getType(), JT_ANNOTATIONS), List.<JCExpression>of(make().NewArray(null, null, (List) annotations.toList())));
            result.append(wrapperAnnotation);
        } else {
            if (annotations.size() > 1) {
                makeErroneous(annotationList, "compiler bug: multiple occurances of non-sequenced annotation class " + annotationClass.getQualifiedNameString());
            }
            result.appendList(annotations);
        }
    }
    // Special case: Generate a @java.lang.Deprecated() if Ceylon deprecated
    if (annotationList != null) {
        for (Tree.Annotation annotation : annotationList.getAnnotations()) {
            if (isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("deprecated"), useSite, target) && isDeprecatedAnnotation(annotation.getPrimary())) {
                result.append(make().Annotation(make().Type(syms().deprecatedType), List.<JCExpression>nil()));
            }
        }
    }
    return result.toList();
}
Also used : ListBuffer(com.sun.tools.javac.util.ListBuffer) LinkedHashMap(java.util.LinkedHashMap) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) OutputElement(com.redhat.ceylon.model.loader.model.OutputElement) 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) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

Function (com.redhat.ceylon.model.typechecker.model.Function)74 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)35 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)35 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)33 Type (com.redhat.ceylon.model.typechecker.model.Type)33 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)26 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)26 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)25 Value (com.redhat.ceylon.model.typechecker.model.Value)25 Class (com.redhat.ceylon.model.typechecker.model.Class)23 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)22 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)20 JCTree (com.sun.tools.javac.tree.JCTree)18 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)17 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)17 ArrayList (java.util.ArrayList)14 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)13 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)12 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)11 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)11