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);
}
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();
}
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;
}
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);
}
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;
}
Aggregations