use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression 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);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ClassTransformer method substituteSequentialForJavaVariadic.
private JCStatement substituteSequentialForJavaVariadic(SyntheticName alias, Parameter lastParameter) {
JCExpression seqType = makeJavaType(lastParameter.getType());
Type seqElemType = typeFact().getIteratedType(lastParameter.getType());
JCExpression init = javaVariadicToSequential(seqElemType, lastParameter);
return make().VarDef(make().Modifiers(FINAL), alias.asName(), seqType, init);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ClassTransformer method makeReadResolve.
private void makeReadResolve(Node def, ClassDefinitionBuilder objectClassBuilder, Class cls, Value model) {
if (Strategy.addReadResolve(cls)) {
at(def);
MethodDefinitionBuilder readResolve = MethodDefinitionBuilder.systemMethod(this, "readResolve");
readResolve.modifiers(PRIVATE);
readResolve.resultType(new TransformedType(make().Type(syms().objectType)));
JCExpression apply;
if (cls.isToplevel()) {
apply = make().Apply(null, naming.makeQualifiedName(naming.makeTypeDeclarationExpression(null, cls, DeclNameFlag.QUALIFIED), model, Naming.NA_MEMBER | Naming.NA_GETTER), List.<JCExpression>nil());
} else {
apply = makeNull();
}
readResolve.body(make().Return(apply));
objectClassBuilder.method(readResolve);
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ClassTransformer method makeMainForClass.
/**
* Makes a {@code main()} method which calls the given top-level method
* @param def
*/
private MethodDefinitionBuilder makeMainForClass(ClassOrInterface model) {
at(null);
List<JCExpression> arguments = List.nil();
if (model.isAlias()) {
TypeDeclaration constr = ((ClassAlias) model).getConstructor();
if (constr instanceof Constructor) {
// must pass the constructor name arg
arguments = List.of(naming.makeNamedConstructorName((Constructor) constr, false));
}
model = (ClassOrInterface) model.getExtendedType().getDeclaration();
}
JCExpression nameId = makeJavaType(model.getType(), JT_RAW);
arguments = makeBottomReifiedTypeParameters(model.getTypeParameters(), arguments);
JCNewClass expr = make().NewClass(null, null, nameId, arguments, null);
return makeMainMethod(model, expr);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method transformSwitch.
// this one trusts the expected type
private JCExpression transformSwitch(Tree.SwitchExpression op, Type expectedType) {
String tmpVar = naming.newTemp("ifResult");
JCStatement switchExpr = statementGen().transform(op, op.getSwitchClause(), op.getSwitchCaseList(), tmpVar, op, expectedType);
at(op);
// use the op model for the variable, not expected type, because expected type may be optional, where op
// says not optional (even in case of java interop which may return null), so we allow null values in j.l.String (unboxed)
// because the caller will insert the null check if the expected type is optional
JCExpression vartype = makeJavaType(op.getTypeModel(), CodegenUtil.getBoxingStrategy(op) == BoxingStrategy.UNBOXED ? 0 : JT_NO_PRIMITIVES);
return make().LetExpr(make().VarDef(make().Modifiers(0), names().fromString(tmpVar), vartype, null), List.<JCStatement>of(switchExpr), makeUnquotedIdent(tmpVar));
}
Aggregations