Search in sources :

Example 16 with ParameterList

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

the class ClassTransformer method transformRefinementSpecifierStatement.

public List<JCStatement> transformRefinementSpecifierStatement(SpecifierStatement op, ClassDefinitionBuilder classBuilder) {
    List<JCStatement> result = List.<JCStatement>nil();
    // Check if this is a shortcut form of formal attribute refinement
    if (op.getRefinement()) {
        Tree.Term baseMemberTerm = op.getBaseMemberExpression();
        if (baseMemberTerm instanceof Tree.ParameterizedExpression)
            baseMemberTerm = ((Tree.ParameterizedExpression) baseMemberTerm).getPrimary();
        Tree.BaseMemberExpression expr = (BaseMemberExpression) baseMemberTerm;
        Declaration decl = expr.getDeclaration();
        if (Decl.isValue(decl) || Decl.isGetter(decl)) {
            // Now build a "fake" declaration for the attribute
            Tree.AttributeDeclaration attrDecl = new Tree.AttributeDeclaration(null);
            attrDecl.setDeclarationModel((Value) decl);
            attrDecl.setIdentifier(expr.getIdentifier());
            attrDecl.setScope(op.getScope());
            attrDecl.setSpecifierOrInitializerExpression(op.getSpecifierExpression());
            attrDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(attrDecl);
            // Generate the attribute
            transform(attrDecl, classBuilder);
        } else if (decl instanceof Function) {
            // Now build a "fake" declaration for the method
            Tree.MethodDeclaration methDecl = new Tree.MethodDeclaration(null);
            Function m = (Function) decl;
            methDecl.setDeclarationModel(m);
            methDecl.setIdentifier(expr.getIdentifier());
            methDecl.setScope(op.getScope());
            methDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            Tree.SpecifierExpression specifierExpression = op.getSpecifierExpression();
            methDecl.setSpecifierExpression(specifierExpression);
            if (specifierExpression instanceof Tree.LazySpecifierExpression == false) {
                Tree.Expression expression = specifierExpression.getExpression();
                Tree.Term expressionTerm = Decl.unwrapExpressionsUntilTerm(expression);
                // we can optimise lambdas and static method calls
                if (!CodegenUtil.canOptimiseMethodSpecifier(expressionTerm, m)) {
                    // we need a field to save the callable value
                    String name = naming.getMethodSpecifierAttributeName(m);
                    JCExpression specifierType = makeJavaType(expression.getTypeModel());
                    JCExpression specifier = expressionGen().transformExpression(expression);
                    classBuilder.field(PRIVATE | FINAL, name, specifierType, specifier, false);
                }
            }
            java.util.List<Tree.ParameterList> parameterListTrees = null;
            if (op.getBaseMemberExpression() instanceof Tree.ParameterizedExpression) {
                parameterListTrees = new ArrayList<>(m.getParameterLists().size());
                parameterListTrees.addAll(((Tree.ParameterizedExpression) op.getBaseMemberExpression()).getParameterLists());
                Tree.Term term = specifierExpression.getExpression().getTerm();
                // and give it the given block of expr as it's specifier
                while (term instanceof Tree.FunctionArgument && m.getParameterLists().size() > 1) {
                    FunctionArgument functionArgument = (Tree.FunctionArgument) term;
                    specifierExpression.setExpression(functionArgument.getExpression());
                    parameterListTrees.addAll(functionArgument.getParameterLists());
                    term = functionArgument.getExpression().getTerm();
                }
            }
            int plIndex = 0;
            // copy from formal declaration
            for (ParameterList pl : m.getParameterLists()) {
                Tree.ParameterList parameterListTree = null;
                if (parameterListTrees != null)
                    parameterListTree = parameterListTrees.get(plIndex++);
                Tree.ParameterList tpl = new Tree.ParameterList(null);
                tpl.setModel(pl);
                int pIndex = 0;
                for (Parameter p : pl.getParameters()) {
                    Tree.Parameter parameterTree = null;
                    if (parameterListTree != null)
                        parameterTree = parameterListTree.getParameters().get(pIndex++);
                    Tree.Parameter tp = null;
                    if (p.getModel() instanceof Value) {
                        Tree.ValueParameterDeclaration tvpd = new Tree.ValueParameterDeclaration(null);
                        if (parameterTree != null)
                            tvpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tvpd.setParameterModel(p);
                        tp = tvpd;
                    } else if (p.getModel() instanceof Function) {
                        Tree.FunctionalParameterDeclaration tfpd = new Tree.FunctionalParameterDeclaration(null);
                        if (parameterTree != null)
                            tfpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tfpd.setParameterModel(p);
                        tp = tfpd;
                    } else {
                        throw BugException.unhandledDeclarationCase(p.getModel());
                    }
                    tp.setScope(p.getDeclaration().getContainer());
                    // tp.setIdentifier(makeIdentifier(p.getName()));
                    tpl.addParameter(tp);
                }
                methDecl.addParameterList(tpl);
            }
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(methDecl);
            // Generate the method
            classBuilder.method(methDecl, Errors.GENERATE);
        }
    } else {
        // Normal case, just generate the specifier statement
        result = result.append(expressionGen().transform(op));
    }
    Tree.Term term = op.getBaseMemberExpression();
    if (term instanceof Tree.BaseMemberExpression) {
        Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
        DeferredSpecification ds = statementGen().getDeferredSpecification(bme.getDeclaration());
        if (ds != null && needsInnerSubstitution(term.getScope(), bme.getDeclaration())) {
            result = result.append(ds.openInnerSubstitution());
        }
    }
    return result;
}
Also used : AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) DeferredSpecification(com.redhat.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification) ArrayList(java.util.ArrayList) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.util.List) 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) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)

Example 17 with ParameterList

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

the class ClassTransformer method refineClass.

private Class refineClass(Scope container, Reference pr, ClassOrInterface classModel, Class formalClass, Unit unit) {
    Class refined = new Class();
    refined.setActual(true);
    refined.setShared(formalClass.isShared());
    refined.setContainer(container);
    refined.setExtendedType(formalClass.getType());
    refined.setDeprecated(formalClass.isDeprecated());
    refined.setName(formalClass.getName());
    refined.setRefinedDeclaration(formalClass.getRefinedDeclaration());
    refined.setScope(container);
    // refined.setType(pr.getType());
    refined.setUnit(unit);
    for (ParameterList formalPl : formalClass.getParameterLists()) {
        ParameterList refinedPl = new ParameterList();
        for (Parameter formalP : formalPl.getParameters()) {
            Parameter refinedP = new Parameter();
            refinedP.setAtLeastOne(formalP.isAtLeastOne());
            refinedP.setDeclaration(refined);
            refinedP.setDefaulted(formalP.isDefaulted());
            refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
            refinedP.setHidden(formalP.isHidden());
            refinedP.setSequenced(formalP.isSequenced());
            refinedP.setName(formalP.getName());
            final TypedReference typedParameter = pr.getTypedParameter(formalP);
            FunctionOrValue paramModel;
            if (formalP.getModel() instanceof Value) {
                Value paramValueModel = refineValue((Value) formalP.getModel(), typedParameter, refined, classModel.getUnit());
                paramValueModel.setInitializerParameter(refinedP);
                paramModel = paramValueModel;
            } else {
                Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function) formalP.getModel(), unit);
                paramFunctionModel.setInitializerParameter(refinedP);
                paramModel = paramFunctionModel;
            }
            refinedP.setModel(paramModel);
            refinedPl.getParameters().add(refinedP);
        }
        refined.addParameterList(refinedPl);
    }
    return refined;
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 18 with ParameterList

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

the class CallableBuilder method unboundFunctionalMemberReference.

/**
 * Used for "static" method or class references. For example:
 * <pre>
 *     value x = Integer.plus;
 *     value y = Foo.method;
 *     value z = Outer.Inner;
 * </pre>
 */
public static CallableBuilder unboundFunctionalMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final Functional methodClassOrCtor, Reference producedReference) {
    final ParameterList parameterList = methodClassOrCtor.getFirstParameterList();
    Type type = typeModel;
    JCExpression target;
    boolean hasOuter = !(Decl.isConstructor((Declaration) methodClassOrCtor) && gen.getNumParameterLists(typeModel) == 1);
    if (!hasOuter) {
        type = typeModel;
        target = null;
    } else {
        type = gen.getReturnTypeOfCallable(type);
        Type qualifyingType = qmte.getTarget().getQualifyingType();
        target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
        target = gen.expressionGen().applyErasureAndBoxing(target, producedReference.getQualifyingType(), true, BoxingStrategy.BOXED, qualifyingType);
    }
    CallableBuilder inner = new CallableBuilder(gen, null, type, parameterList);
    // FromParameterModels();
    inner.parameterTypes = inner.getParameterTypesFromCallableModel();
    if (hasOuter) {
        inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodClassOrCtor);
    }
    CallBuilder callBuilder = CallBuilder.instance(gen);
    Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
    if (Decl.isConstructor((Declaration) methodClassOrCtor)) {
        Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
        Class cls = Decl.getConstructedClass(ctor);
        if (Strategy.generateInstantiator(ctor)) {
            callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
        } else {
            callBuilder.instantiate(gen.makeJavaType(gen.getReturnTypeOfCallable(typeModel), JT_CLASS_NEW));
            if (!ctor.isShared()) {
                accessType = Decl.getPrivateAccessType(qmte);
            }
        }
    } else if (methodClassOrCtor instanceof Function && ((Function) methodClassOrCtor).isParameter()) {
        callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
    } else if (methodClassOrCtor instanceof Function) {
        callBuilder.invoke(gen.naming.makeQualifiedName(target, (Function) methodClassOrCtor, Naming.NA_MEMBER));
        if (!((TypedDeclaration) methodClassOrCtor).isShared()) {
            accessType = Decl.getPrivateAccessType(qmte);
        }
    } else if (methodClassOrCtor instanceof Class) {
        Class cls = (Class) methodClassOrCtor;
        if (Strategy.generateInstantiator(cls)) {
            callBuilder.invoke(gen.naming.makeInstantiatorMethodName(target, cls));
        } else {
            callBuilder.instantiate(new ExpressionAndType(target, null), gen.makeJavaType(cls.getType(), JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED));
            if (!cls.isShared()) {
                accessType = Decl.getPrivateAccessType(qmte);
            }
        }
    } else {
        throw BugException.unhandledDeclarationCase((Declaration) methodClassOrCtor, qmte);
    }
    ListBuffer<ExpressionAndType> reified = ListBuffer.lb();
    DirectInvocation.addReifiedArguments(gen, producedReference, reified);
    for (ExpressionAndType reifiedArgument : reified) {
        callBuilder.argument(reifiedArgument.expression);
    }
    if (Decl.isConstructor((Declaration) methodClassOrCtor) && !Decl.isDefaultConstructor(Decl.getConstructor((Declaration) methodClassOrCtor))) {
        // invoke the param class ctor
        Constructor ctor = Decl.getConstructor((Declaration) methodClassOrCtor);
        callBuilder.argument(gen.naming.makeNamedConstructorName(ctor, false));
    }
    for (Parameter parameter : parameterList.getParameters()) {
        callBuilder.argument(gen.naming.makeQuotedIdent(Naming.getAliasedParameterName(parameter)));
    }
    JCExpression innerInvocation = callBuilder.build();
    // Need to worry about boxing for Function and FunctionalParameter
    if (methodClassOrCtor instanceof TypedDeclaration && !Decl.isConstructor((Declaration) methodClassOrCtor)) {
        // use the method return type since the function is actually applied
        Type returnType = gen.getReturnTypeOfCallable(type);
        innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
        CodegenUtil.hasTypeErased((TypedDeclaration) methodClassOrCtor), !CodegenUtil.isUnBoxed((TypedDeclaration) methodClassOrCtor), BoxingStrategy.BOXED, returnType, 0);
    } else if (methodClassOrCtor instanceof Class && Strategy.isInstantiatorUntyped((Class) methodClassOrCtor)) {
        // $new method declared to return Object, so needs typecast
        innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodClassOrCtor).getType()), innerInvocation);
    }
    List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
    inner.useDefaultTransformation(innerBody);
    if (!hasOuter) {
        return inner;
    }
    ParameterList outerPl = new ParameterList();
    Parameter instanceParameter = new Parameter();
    instanceParameter.setName(Naming.name(Unfix.$instance$));
    Value valueModel = new Value();
    instanceParameter.setModel(valueModel);
    valueModel.setName(instanceParameter.getName());
    valueModel.setInitializerParameter(instanceParameter);
    valueModel.setType(accessType);
    valueModel.setUnboxed(false);
    outerPl.getParameters().add(instanceParameter);
    CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
    outer.parameterTypes = outer.getParameterTypesFromParameterModels();
    List<JCStatement> outerBody = List.<JCStatement>of(gen.make().Return(inner.build()));
    outer.useDefaultTransformation(outerBody);
    outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
    return outer;
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) 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) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) Class(com.redhat.ceylon.model.typechecker.model.Class) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration)

Example 19 with ParameterList

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

the class CallableBuilder method javaStaticMethodReference.

public static CallableBuilder javaStaticMethodReference(CeylonTransformer gen, Type typeModel, final Functional methodOrClass, Reference producedReference) {
    final ParameterList parameterList = methodOrClass.getFirstParameterList();
    CallableBuilder inner = new CallableBuilder(gen, null, typeModel, parameterList);
    ArrayList<Type> pt = new ArrayList<>();
    for (Parameter p : methodOrClass.getFirstParameterList().getParameters()) {
        pt.add(p.getType());
    }
    inner.parameterTypes = pt;
    inner.defaultValueCall = inner.new MemberReferenceDefaultValueCall(methodOrClass);
    JCExpression innerInvocation = gen.expressionGen().makeJavaStaticInvocation(gen, methodOrClass, producedReference, parameterList);
    // Need to worry about boxing for Function and FunctionalParameter
    if (methodOrClass instanceof TypedDeclaration) {
        innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, methodOrClass.getType(), !CodegenUtil.isUnBoxed((TypedDeclaration) methodOrClass), BoxingStrategy.BOXED, methodOrClass.getType());
    } else if (Strategy.isInstantiatorUntyped((Class) methodOrClass)) {
        // $new method declared to return Object, so needs typecast
        innerInvocation = gen.make().TypeCast(gen.makeJavaType(((Class) methodOrClass).getType()), innerInvocation);
    }
    List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
    inner.useDefaultTransformation(innerBody);
    return inner;
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ArrayList(java.util.ArrayList) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) Class(com.redhat.ceylon.model.typechecker.model.Class) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Aggregations

ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)19 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)13 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)11 Function (com.redhat.ceylon.model.typechecker.model.Function)8 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)7 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)7 Value (com.redhat.ceylon.model.typechecker.model.Value)7 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)6 Functional (com.redhat.ceylon.model.typechecker.model.Functional)6 Type (com.redhat.ceylon.model.typechecker.model.Type)6 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)6 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)5 Class (com.redhat.ceylon.model.typechecker.model.Class)5 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)5 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)5 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)5 ArrayList (java.util.ArrayList)5 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)4 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)4 FieldValue (com.redhat.ceylon.model.loader.model.FieldValue)3