Search in sources :

Example 21 with ListBuffer

use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.

the class ClassTransformer method addWriteReplace.

/**
 * Adds a write replace method which replaces value constructor instances
 * with a SerializationProxy
 * @param model
 * @param classBuilder
 */
protected void addWriteReplace(final Class model, ClassDefinitionBuilder classBuilder) {
    MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, "writeReplace");
    mdb.resultType(new TransformedType(make().Type(syms().objectType), null, makeAtNonNull()));
    mdb.modifiers(PRIVATE | FINAL);
    ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
    SyntheticName name = naming.synthetic(Unfix.$name$);
    stmts.add(makeVar(FINAL, name, make().Type(syms().stringType), null));
    if (model.hasEnumerated()) {
        JCStatement tail;
        if (Decl.hasOnlyValueConstructors(model)) {
            tail = make().Throw(statementGen().makeNewEnumeratedTypeError("Instance not of any constructor"));
        } else {
            tail = make().Return(naming.makeThis());
        }
        for (Declaration member : model.getMembers()) {
            if (Decl.isValueConstructor(member)) {
                Value val = (Value) member;
                tail = make().If(make().Binary(JCTree.Tag.EQ, naming.makeThis(), naming.getValueConstructorFieldName(val).makeIdent()), make().Block(0, List.<JCStatement>of(make().Exec(make().Assign(name.makeIdent(), make().Literal(Naming.getGetterName(member)))))), tail);
            }
        }
        stmts.add(tail);
    } else if (model.isAnonymous()) {
        stmts.add(make().Exec(make().Assign(name.makeIdent(), make().Literal(Naming.getGetterName((Value) model.getContainer().getDirectMember(model.getName(), null, false))))));
    } else {
        throw new BugException("Unsupported need for writeReplace()");
    }
    // final String name;
    // if(this == instA) {
    // name = "getInstA";
    // } // ... else { throw new
    // return new SerializationProxy(outer, Foo.clazz, name);
    List<JCExpression> args = List.<JCExpression>of(name.makeIdent());
    if (model.isMember() && !model.isStatic()) {
        ClassOrInterface outer = (ClassOrInterface) model.getContainer();
        args = args.prepend(makeClassLiteral(outer.getType()));
        args = args.prepend(naming.makeQualifiedThis(naming.makeTypeDeclarationExpression(null, outer, DeclNameFlag.QUALIFIED)));
    } else {
        args = args.prepend(makeClassLiteral(model.getType()));
    }
    stmts.add(make().Return(make().NewClass(null, null, make().QualIdent(syms().ceylonSerializationProxyType.tsym), args, null)));
    mdb.body(stmts.toList());
    classBuilder.method(mdb);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)

Example 22 with ListBuffer

use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.

the class ClassTransformer method makeNamedConstructor.

/**
 * Makes a named constructor
 * @param that
 * @param classBuilder
 * @param mods
 * @param ctorName
 * @param ctorBody
 * @param declFlags
 * @return
 */
public List<JCTree> makeNamedConstructor(Tree.Declaration that, Tree.ParameterList parameterList, Constructor ctor, ClassDefinitionBuilder classBuilder, boolean generateInstantiator, int mods, boolean atIgnoreCtor, String ctorName, List<JCStatement> ctorBody, DeclNameFlag... declFlags) {
    ListBuffer<JCTree> result = new ListBuffer<JCTree>();
    Class clz = (Class) ctor.getContainer();
    at(that);
    MethodDefinitionBuilder ctorDb = MethodDefinitionBuilder.constructor(this, ctor.isDeprecated());
    ClassDefinitionBuilder decl = null;
    ClassDefinitionBuilder impl = null;
    if (generateInstantiator) {
        if (clz.getContainer() instanceof Interface) {
            decl = classBuilder.getContainingClassBuilder();
            impl = classBuilder.getContainingClassBuilder().getCompanionBuilder((Interface) clz.getContainer());
        } else {
            decl = classBuilder.getContainingClassBuilder();
            impl = classBuilder.getContainingClassBuilder();
        }
        generateInstantiators(classBuilder, clz, ctor, decl, impl, that, parameterList);
    }
    ctorDb.userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, that));
    if (atIgnoreCtor) {
        ctorDb.modelAnnotations(makeAtIgnore());
    } else if (!Decl.isDefaultConstructor(ctor)) {
        ctorDb.modelAnnotations(makeAtName(ctor.getName()));
    }
    if (ModelUtil.isEnumeratedConstructor(ctor)) {
        ctorDb.modelAnnotations(makeAtEnumerated());
    }
    ctorDb.modifiers(mods);
    for (TypeParameter tp : Strategy.getEffectiveTypeParameters(clz)) {
        ctorDb.reifiedTypeParameter(tp);
    }
    if (ctorName != null) {
        // generate a constructor name class (and constant)
        transformConstructorName(classBuilder, result, ctor, clz, mods, ctorName, declFlags);
        // Add the name paramter
        ctorDb.parameter(makeConstructorNameParameter(ctor, declFlags));
    }
    // Add the rest of the parameters (this worries about aliasing)
    if (parameterList != null) {
        transformClassOrCtorParameters(null, (Class) ctor.getContainer(), ctor, that, parameterList, contains(declFlags, DeclNameFlag.DELEGATION), classBuilder, ctorDb, generateInstantiator, decl, impl);
    }
    // Transformation of body has to happen after transformation of parameter so we know about parameter aliasing.
    at(that);
    ctorDb.block(make().Block(0, ctorBody));
    result.add(ctorDb.build());
    return result.toList();
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 23 with ListBuffer

use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.

the class ExpressionTransformer method makeJavaStaticInvocation.

JCExpression makeJavaStaticInvocation(CeylonTransformer gen, final Functional methodOrClass, Reference producedReference, final ParameterList parameterList) {
    CallBuilder callBuilder = CallBuilder.instance(gen);
    if (methodOrClass instanceof Function) {
        JCExpression fn;
        if (Decl.isJavaArrayFrom((Declaration) methodOrClass)) {
            fn = gen.makeUnwrapArray((Declaration) methodOrClass);
        } else {
            fn = naming.makeName((Function) methodOrClass, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED);
        }
        callBuilder.invoke(fn);
    } else if (methodOrClass instanceof Class) {
        callBuilder.instantiate(gen.makeJavaType(((Class) methodOrClass).getType(), JT_RAW | JT_NO_PRIMITIVES));
    }
    ListBuffer<ExpressionAndType> reified = new ListBuffer<ExpressionAndType>();
    DirectInvocation.addReifiedArguments(gen, producedReference, reified);
    for (ExpressionAndType reifiedArgument : reified) {
        callBuilder.argument(reifiedArgument.expression);
    }
    for (Parameter parameter : parameterList.getParameters()) {
        callBuilder.argument(gen.naming.makeQuotedIdent(parameter.getName()));
    }
    JCExpression innerInvocation = callBuilder.build();
    return innerInvocation;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 24 with ListBuffer

use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.

the class ExpressionTransformer method transformUnknownArguments.

private ExpressionAndType transformUnknownArguments(SimpleInvocation invocation, CallBuilder callBuilder) {
    // doesn't really matter, assume Object, it's not used
    Type iteratedType = typeFact().getObjectType();
    // the single spread argument which is allowed
    JCExpression rest = null;
    ListBuffer<JCExpression> initial = new ListBuffer<JCExpression>();
    for (int ii = 0; ii < invocation.getNumArguments(); ii++) {
        if (invocation.isArgumentSpread(ii)) {
            rest = invocation.getTransformedArgumentExpression(ii);
        } else {
            initial.add(invocation.getTransformedArgumentExpression(ii));
        }
    }
    JCExpression expr;
    if (initial.isEmpty()) {
        expr = make().TypeCast(makeJavaType(typeFact().getSequentialDeclaration().getType(), JT_RAW), rest);
    } else {
        expr = utilInvocation().sequentialInstance(null, makeReifiedTypeArgument(iteratedType), rest != null ? rest : makeEmptyAsSequential(true), initial.toList());
    }
    JCExpression type = makeJavaType(typeFact().getSequenceType(iteratedType).getType());
    return new ExpressionAndType(expr, type);
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) 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)

Example 25 with ListBuffer

use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.

the class ExpressionTransformer method makeTopLevelValueOrFunctionLiteral.

private JCTree makeTopLevelValueOrFunctionLiteral(Tree.MemberLiteral expr) {
    Declaration declaration = expr.getDeclaration();
    JCExpression toplevelCall = makeTopLevelValueOrFunctionDeclarationLiteral(declaration);
    if (!expr.getWantsDeclaration()) {
        ListBuffer<JCExpression> closedTypeArgs = new ListBuffer<JCExpression>();
        // expr is of type Function<Type,Arguments> or Value<Get,Set> so we can get its type like that
        JCExpression reifiedType = makeReifiedTypeArgument(expr.getTypeModel().getTypeArgumentList().get(0));
        closedTypeArgs.append(reifiedType);
        if (Decl.isMethod(declaration)) {
            // expr is of type Function<Type,Arguments> so we can get its arguments type like that
            Type argumentsType = typeFact().getCallableTuple(expr.getTypeModel());
            JCExpression reifiedArguments = makeReifiedTypeArgument(argumentsType);
            closedTypeArgs.append(reifiedArguments);
            if (expr.getTypeArgumentList() != null) {
                java.util.List<Type> typeModels = expr.getTypeArgumentList().getTypeModels();
                if (typeModels != null) {
                    JCExpression closedTypesExpr = getClosedTypesSequential(typeModels);
                    // must apply it
                    closedTypeArgs.append(closedTypesExpr);
                }
            }
        } else {
            JCExpression reifiedSet;
            Type ptype;
            if (!((Value) declaration).isVariable())
                ptype = typeFact().getNothingType();
            else
                ptype = expr.getTypeModel().getTypeArgumentList().get(0);
            reifiedSet = makeReifiedTypeArgument(ptype);
            closedTypeArgs.append(reifiedSet);
        }
        toplevelCall = make().Apply(null, makeSelect(toplevelCall, "apply"), closedTypeArgs.toList());
        // add cast
        Type exprType = expr.getTypeModel().resolveAliases();
        JCExpression typeClass = makeJavaType(exprType, JT_NO_PRIMITIVES);
        JCExpression rawTypeClass = makeJavaType(exprType, JT_NO_PRIMITIVES | JT_RAW);
        return make().TypeCast(typeClass, make().TypeCast(rawTypeClass, toplevelCall));
    }
    return toplevelCall;
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) 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) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)67 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)53 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)30 Type (org.eclipse.ceylon.model.typechecker.model.Type)23 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)22 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)20 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)16 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)16 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)15 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)14 JCAnnotation (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)13 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)12 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)12 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)11 Function (org.eclipse.ceylon.model.typechecker.model.Function)10 Class (org.eclipse.ceylon.model.typechecker.model.Class)9 JCTypeParameter (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter)8 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)8 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)8 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)7