Search in sources :

Example 16 with Functional

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

the class AnnotationInvocationVisitor method transformConstructorArgument.

public static JCExpression transformConstructorArgument(ExpressionTransformer exprGen, Tree.InvocationExpression invocation, Parameter classParameter, AnnotationArgument argument, com.sun.tools.javac.util.List<AnnotationFieldName> fieldPath) {
    AnnotationInvocation anno = annoCtorModel(invocation);
    AnnotationInvocationVisitor visitor = new AnnotationInvocationVisitor(exprGen, invocation, anno);
    visitor.parameter = classParameter;
    AnnotationTerm term = argument.getTerm();
    if (term instanceof ParameterAnnotationTerm) {
        ParameterAnnotationTerm parameterArgument = (ParameterAnnotationTerm) term;
        Parameter sp = parameterArgument.getSourceParameter();
        int argumentIndex = ((Functional) sp.getDeclaration()).getFirstParameterList().getParameters().indexOf(sp);
        if (invocation.getPositionalArgumentList() != null) {
            java.util.List<Tree.PositionalArgument> positionalArguments = invocation.getPositionalArgumentList().getPositionalArguments();
            if (parameterArgument.isSpread()) {
                visitor.transformSpreadArgument(positionalArguments.subList(argumentIndex, positionalArguments.size()), classParameter);
            } else {
                if (0 <= argumentIndex && argumentIndex < positionalArguments.size()) {
                    Tree.PositionalArgument pargument = positionalArguments.get(argumentIndex);
                    if (pargument.getParameter().isSequenced()) {
                        visitor.transformVarargs(argumentIndex, positionalArguments);
                    } else {
                        visitor.transformArgument(pargument);
                    }
                } else if (sp.isDefaulted()) {
                    visitor.makeDefaultExpr(invocation, parameterArgument, sp);
                } else if (sp.isSequenced()) {
                    visitor.appendBuiltArray(visitor.startArray());
                }
            }
        } else if (invocation.getNamedArgumentList() != null) {
            boolean found = false;
            for (Tree.NamedArgument na : invocation.getNamedArgumentList().getNamedArguments()) {
                Parameter parameter = na.getParameter();
                int parameterIndex = anno.indexOfConstructorParameter(parameter);
                if (parameterIndex == argumentIndex) {
                    visitor.transformArgument(na);
                    found = true;
                    break;
                }
            }
            if (!found) {
                if (sp.isDefaulted()) {
                    visitor.makeDefaultExpr(invocation, parameterArgument, sp);
                } else if (sp.isSequenced()) {
                    visitor.appendBuiltArray(visitor.startArray());
                } else {
                    visitor.append(exprGen.makeErroneous(invocation, "Unable to find argument"));
                }
            }
        }
    } else if (term instanceof LiteralAnnotationTerm) {
        visitor.append(term.makeAnnotationArgumentValue(visitor.exprGen, visitor.anno, fieldPath.append(argument)));
    } else if (term instanceof InvocationAnnotationTerm) {
        AnnotationInvocation instantiation = ((InvocationAnnotationTerm) term).getInstantiation();
        visitor.append(transformConstructor(visitor.exprGen, invocation, instantiation, fieldPath.append(argument)));
    } else {
        visitor.append(visitor.exprGen.makeErroneous(invocation, "Unable to find argument"));
    }
    return visitor.getExpression();
}
Also used : PositionalArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) Functional(com.redhat.ceylon.model.typechecker.model.Functional) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.PositionalArgument)

Example 17 with Functional

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

the class BoxingDeclarationVisitor method setBoxingState.

private void setBoxingState(TypedDeclaration declaration, TypedDeclaration refinedDeclaration, Node that) {
    Type type = declaration.getType();
    if (type == null) {
        // an error must have already been reported
        return;
    }
    // fetch the real refined declaration if required
    if (Decl.equal(declaration, refinedDeclaration) && declaration instanceof FunctionOrValue && ((FunctionOrValue) declaration).isParameter() && declaration.getContainer() instanceof Class) {
        // maybe it is really inherited from a field?
        FunctionOrValue methodOrValueForParam = (FunctionOrValue) declaration;
        if (methodOrValueForParam != null) {
            // make sure we get the refined version of that member
            refinedDeclaration = (TypedDeclaration) methodOrValueForParam.getRefinedDeclaration();
        }
    }
    // inherit underlying type constraints
    if (!Decl.equal(refinedDeclaration, declaration) && type.getUnderlyingType() == null && refinedDeclaration.getType() != null)
        type.setUnderlyingType(refinedDeclaration.getType().getUnderlyingType());
    // abort if our boxing state has already been set
    if (declaration.getUnboxed() != null)
        return;
    // functional parameter return values are always boxed if we're not creating a method for them
    if (declaration instanceof Function && ((Function) declaration).isParameter() && !JvmBackendUtil.createMethod((Function) declaration)) {
        declaration.setUnboxed(false);
        return;
    }
    if (!Decl.equal(refinedDeclaration, declaration)) {
        // make sure refined declarations have already been set
        if (refinedDeclaration.getUnboxed() == null)
            setBoxingState(refinedDeclaration, refinedDeclaration, that);
        // inherit
        declaration.setUnboxed(refinedDeclaration.getUnboxed());
    } else if (declaration instanceof Function && CodegenUtil.isVoid(declaration.getType()) && Strategy.useBoxedVoid((Function) declaration) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        declaration.setUnboxed(false);
    } else if ((isCeylonBasicType(type) || Decl.isUnboxedVoid(declaration)) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && (refinedDeclaration.getContainer() instanceof Declaration == false || !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration)) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        boolean unbox = !forceBoxedLocals || !(declaration instanceof Value) || !Decl.isLocal(declaration) || Decl.isParameter(declaration) || Decl.isTransient(declaration);
        declaration.setUnboxed(unbox);
    } else if (Decl.isValueParameter(declaration) && CodegenUtil.isContainerFunctionalParameter(declaration) && JvmBackendUtil.createMethod((FunctionOrValue) declaration.getContainer())) {
        Function functionalParameter = (Function) declaration.getContainer();
        TypedDeclaration refinedFrom = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(functionalParameter, optimisedMethodSpecifiersToMethods);
        if (Decl.equal(refinedFrom, functionalParameter)) {
            // not a method return type (where void would be considered unboxed).
            if (declaration.getUnit().getAnythingType().isExactly(declaration.getType()) || declaration.getUnit().isOptionalType(declaration.getType())) {
                declaration.setUnboxed(false);
            } else {
                declaration.setUnboxed(true);
            }
        } else {
            // make sure refined declarations have already been set
            if (refinedFrom.getUnboxed() == null)
                setBoxingState(refinedFrom, refinedFrom, that);
            // inherit
            declaration.setUnboxed(refinedFrom.getUnboxed());
        }
    } else {
        declaration.setUnboxed(false);
    }
    // Any "@boxed" or "@unboxed" compiler annotation overrides
    boxFromAnnotation(declaration, that);
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) Function(com.redhat.ceylon.model.typechecker.model.Function) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Type(com.redhat.ceylon.model.typechecker.model.Type) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Class(com.redhat.ceylon.model.typechecker.model.Class) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) FunctionalParameterDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionalParameterDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

Functional (com.redhat.ceylon.model.typechecker.model.Functional)17 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)9 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)9 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)8 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)7 Function (com.redhat.ceylon.model.typechecker.model.Function)7 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)7 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)6 Type (com.redhat.ceylon.model.typechecker.model.Type)6 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)5 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)5 Value (com.redhat.ceylon.model.typechecker.model.Value)5 Class (com.redhat.ceylon.model.typechecker.model.Class)4 JCTree (com.sun.tools.javac.tree.JCTree)4 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)3 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)3 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)3 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)3 HasErrorException (com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException)2 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)2