Search in sources :

Example 36 with Type

use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.

the class CallableBuilder method buildTypeConstructor.

protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
    JCExpression result;
    // Wrap in an anonymous TypeConstructor subcla
    MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
    rawApply.modifiers(Flags.PUBLIC);
    rawApply.isOverride(true);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
        rawApply.parameter(pdb);
    }
    rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
    MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
    typedApply.modifiers(Flags.PRIVATE);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
        typedApply.parameter(pdb);
    }
    ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
    for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
        Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
        typeParameters.add(gen.makeTypeParameter(typeParameter, null));
        typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
    }
    typedApply.body(gen.make().Return(callableInstance));
    // typedApply.body(body.toList());
    MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
    ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
    SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
    JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
    n.asName(), typeParameters.toList(), // extending
    gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
    List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
    result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
    null));
    return result;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Example 37 with Type

use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.

the class CallableBuilder method getParameterTypesFromParameterModels.

private java.util.List<Type> getParameterTypesFromParameterModels() {
    java.util.List<Type> parameterTypes = new ArrayList<Type>(numParams);
    // get them from our declaration
    for (Parameter p : paramLists.getParameters()) {
        Type pt;
        FunctionOrValue pm = p.getModel();
        if (pm instanceof Function && ((Function) pm).isParameter())
            pt = gen.getTypeForFunctionalParameter((Function) pm);
        else
            pt = p.getType();
        parameterTypes.add(pt);
    }
    return parameterTypes;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) ArrayList(java.util.ArrayList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 38 with Type

use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.

the class CallableBuilder method build.

public JCExpression build() {
    // Generate a subclass of Callable
    ListBuffer<JCTree> classBody = new ListBuffer<JCTree>();
    gen.at(node);
    if (parameterDefaultValueMethods != null) {
        for (MethodDefinitionBuilder mdb : parameterDefaultValueMethods) {
            classBody.append(mdb.build());
        }
    }
    transformation.appendMethods(classBody);
    gen.at(node);
    JCClassDecl classDef = gen.make().AnonymousClassDef(gen.make().Modifiers(0, annotations != null ? annotations : List.<JCAnnotation>nil()), classBody.toList());
    int variadicIndex = isVariadic ? numParams - 1 : -1;
    Type callableType;
    if (typeModel.isTypeConstructor()) {
        callableType = typeModel.getDeclaration().getExtendedType();
    } else {
        callableType = typeModel;
    }
    JCNewClass callableInstance;
    if (functionalInterface == null) {
        callableInstance = gen.at(node).NewClass(null, null, gen.makeJavaType(callableType, JT_EXTENDS | JT_CLASS_NEW), List.<JCExpression>of(gen.makeReifiedTypeArgument(callableType.getTypeArgumentList().get(0)), gen.makeReifiedTypeArgument(callableType.getTypeArgumentList().get(1)), gen.make().Literal(callableType.asString(true)), gen.make().TypeCast(gen.syms().shortType, gen.makeInteger(variadicIndex))), classDef);
    } else {
        callableInstance = gen.make().NewClass(null, null, gen.makeJavaType(functionalInterface, JT_EXTENDS | JT_CLASS_NEW), List.<JCExpression>nil(), classDef);
    }
    JCExpression result;
    if (typeModel.isTypeConstructor()) {
        result = buildTypeConstructor(callableType, callableInstance);
    } else {
        result = callableInstance;
    }
    gen.at(null);
    if (instanceSubstitution != null) {
        instanceSubstitution.close();
    }
    return result;
}
Also used : JCClassDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)

Example 39 with Type

use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.

the class CallableBuilder method makeCallMethod.

protected final MethodDefinitionBuilder makeCallMethod(List<JCStatement> body, int arity) {
    MethodDefinitionBuilder callMethod = MethodDefinitionBuilder.callable(gen);
    // we only override it if we're not building a functional interface class
    callMethod.isOverride(functionalInterfaceMethod == null);
    callMethod.modifiers(Flags.PUBLIC);
    Type returnType = gen.getReturnTypeOfCallable(typeModel);
    callMethod.resultType(gen.makeJavaType(returnType, JT_NO_PRIMITIVES), null);
    // Now append formal parameters
    switch(arity) {
        case 3:
            callMethod.parameter(makeCallableCallParam(0, arity - 3));
        // fall through
        case 2:
            callMethod.parameter(makeCallableCallParam(0, arity - 2));
        // fall through
        case 1:
            callMethod.parameter(makeCallableCallParam(0, arity - 1));
            break;
        case 0:
            break;
        default:
            // use varargs
            callMethod.parameter(makeCallableCallParam(Flags.VARARGS, 0));
    }
    // Return the call result, or null if a void method
    callMethod.body(body);
    return callMethod;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type)

Example 40 with Type

use of org.eclipse.ceylon.model.typechecker.model.Type in project ceylon by eclipse.

the class CallableBuilder method methodReference.

/**
 * Constructs an {@code AbstractCallable} suitable for wrapping a
 * method reference. For example:
 * <pre>
 *   void someMethod() { ... }
 *   Anything() ref = someMethod;
 * </pre>
 */
public static JCExpression methodReference(CeylonTransformer gen, final Tree.StaticMemberOrTypeExpression forwardCallTo, ParameterList parameterList, Type expectedType, Type callableType, boolean useParameterTypesFromCallableModel) {
    ListBuffer<JCStatement> letStmts = new ListBuffer<JCStatement>();
    CallableBuilder cb = new CallableBuilder(gen, forwardCallTo, callableType, parameterList);
    cb.parameterTypes = useParameterTypesFromCallableModel ? cb.getParameterTypesFromCallableModel() : cb.getParameterTypesFromParameterModels();
    Naming.SyntheticName instanceFieldName;
    boolean instanceFieldIsBoxed = false;
    if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression && !ExpressionTransformer.isSuperOrSuperOf(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary()) && !ExpressionTransformer.isPackageQualified((Tree.QualifiedMemberOrTypeExpression) forwardCallTo)) {
        if ((((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SpreadOp)) {
            instanceFieldIsBoxed = true;
            instanceFieldName = null;
        } else {
            Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) forwardCallTo;
            boolean prevCallableInv = gen.expressionGen().withinSyntheticClassBody(true);
            try {
                instanceFieldName = gen.naming.synthetic(Unfix.$instance$);
                int varTypeFlags = Decl.isPrivateAccessRequiringCompanion(qmte) ? JT_COMPANION : 0;
                Type primaryType;
                if (Decl.isValueTypeDecl(qmte.getPrimary().getTypeModel())) {
                    primaryType = qmte.getPrimary().getTypeModel();
                } else {
                    primaryType = qmte.getTarget().getQualifyingType();
                }
                if (((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SafeMemberOp) {
                    primaryType = gen.typeFact().getOptionalType(primaryType);
                }
                JCExpression primaryExpr = gen.expressionGen().transformQualifiedMemberPrimary(qmte);
                Declaration dec = qmte.getDeclaration();
                if (Decl.isPrivateAccessRequiringCompanion(qmte)) {
                    primaryExpr = gen.naming.makeCompanionAccessorCall(primaryExpr, (Interface) dec.getContainer());
                }
                Type varType = dec.isShared() ? primaryType : Decl.getPrivateAccessType(qmte);
                if (qmte.getPrimary().getUnboxed() == false) {
                    varTypeFlags |= JT_NO_PRIMITIVES;
                    instanceFieldIsBoxed = true;
                }
                letStmts.add(gen.makeVar(Flags.FINAL, instanceFieldName, gen.makeJavaType(varType, varTypeFlags), primaryExpr));
                if (qmte.getPrimary() instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration() instanceof TypedDeclaration) {
                    cb.instanceSubstitution = gen.naming.addVariableSubst((TypedDeclaration) ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration(), instanceFieldName.getName());
                }
            } finally {
                gen.expressionGen().withinSyntheticClassBody(prevCallableInv);
            }
        }
    } else {
        instanceFieldName = null;
    }
    CallableTransformation tx;
    cb.defaultValueCall = new DefaultValueMethodTransformation() {

        @Override
        public JCExpression makeDefaultValueMethod(AbstractTransformer gen, Parameter defaultedParam, List<JCExpression> defaultMethodArgs) {
            JCExpression fn = null;
            if (forwardCallTo instanceof Tree.BaseMemberOrTypeExpression) {
                fn = gen.naming.makeDefaultedParamMethod(null, defaultedParam);
            } else if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression) {
                JCExpression qualifier = gen.expressionGen().transformTermForInvocation(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary(), null);
                fn = gen.naming.makeDefaultedParamMethod(qualifier, defaultedParam);
            }
            return gen.make().Apply(null, fn, defaultMethodArgs);
        }
    };
    if (cb.isVariadic) {
        tx = cb.new VariadicCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, false, callableType));
    } else {
        tx = cb.new FixedArityCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, true, callableType), null);
    }
    cb.useTransformation(tx);
    cb.checkForFunctionalInterface(expectedType);
    return letStmts.isEmpty() ? cb.build() : gen.make().LetExpr(letStmts.toList(), cb.build());
}
Also used : ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) QualifiedMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.QualifiedMemberOrTypeExpression) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) QualifiedMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.QualifiedMemberOrTypeExpression) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) QualifiedMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.QualifiedMemberOrTypeExpression) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) Interface(org.eclipse.ceylon.model.typechecker.model.Interface)

Aggregations

Type (org.eclipse.ceylon.model.typechecker.model.Type)692 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)270 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)263 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)244 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)225 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)207 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)182 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)176 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)176 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)169 ModelUtil.genericFunctionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType)153 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)130 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)125 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)114 ArrayList (java.util.ArrayList)106 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)100 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)96 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)95 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)94 Class (org.eclipse.ceylon.model.typechecker.model.Class)87