use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.
the class ExpressionTransformer method makeAssignment.
private JCExpression makeAssignment(Node op, Tree.Term leftTerm, final JCExpression lhs, JCExpression rhs) {
TypedDeclaration decl;
if (leftTerm instanceof Tree.StaticMemberOrTypeExpression) {
decl = (TypedDeclaration) ((Tree.StaticMemberOrTypeExpression) leftTerm).getDeclaration();
} else if (leftTerm instanceof Tree.IndexExpression) {
// in this case lhs is null anyway, so let's discard it
return transformIndexAssignment(op, (Tree.IndexExpression) leftTerm, rhs);
} else if (leftTerm instanceof Tree.ParameterizedExpression) {
// instanceof Tree.ParameterizedExpression
decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression) ((Tree.ParameterizedExpression) leftTerm).getPrimary()).getDeclaration();
} else {
return makeErroneous(op, "Unexpected LHS in assignment: " + leftTerm.getNodeType());
}
rhs = adjustRhs(decl, rhs);
JCExpression varExpr = makeAssignmentVariable(op, lhs, decl);
JCExpression result;
if (varExpr != null) {
result = at(op).Assign(varExpr, rhs);
} else {
ListBuffer<JCExpression> typeArguments = new ListBuffer<JCExpression>();
ListBuffer<JCExpression> reifiedTypeArguments = new ListBuffer<JCExpression>();
if (decl.isStatic() && ModelUtil.isCeylonDeclaration(decl)) {
Type primType = ((Tree.StaticMemberOrTypeExpression) leftTerm).getTarget().getQualifyingType();
if (primType != null) {
for (Type pt : primType.getTypeArgumentList()) {
typeArguments.add(makeJavaType(pt, JT_TYPE_ARGUMENT));
reifiedTypeArguments.add(makeReifiedTypeArgument(pt));
}
}
}
String selector = Naming.selector(decl, Naming.NA_SETTER);
result = make().Apply(typeArguments.toList(), makeQualIdent(lhs, selector), reifiedTypeArguments.toList().append(rhs));
}
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.
the class ExpressionTransformer method transformSpreadOperator.
private JCExpression transformSpreadOperator(final Tree.QualifiedMemberOrTypeExpression expr, TermTransformer transformer) {
at(expr);
boolean spreadMethodReferenceOuter = !expr.equals(spreading) && !isWithinInvocation() && isCeylonCallableSubtype(expr.getTypeModel());
boolean spreadMethodReferenceInner = expr.equals(spreading) && isWithinInvocation();
Tree.QualifiedMemberOrTypeExpression oldSpreading = spreading;
if (spreadMethodReferenceOuter) {
spreading = expr;
}
try {
Naming.SyntheticName varBaseName = naming.alias("spread");
ListBuffer<JCStatement> letStmts = new ListBuffer<JCStatement>();
final Naming.SyntheticName srcIterableName;
if (spreadMethodReferenceInner) {
// use the var we initialized in the outer
srcIterableName = this.memberPrimary;
} else {
srcIterableName = varBaseName.suffixedBy(Suffix.$iterable$);
}
if (spreadMethodReferenceOuter) {
// if we're in the outer, note then name of the var for use in the inner.
this.memberPrimary = srcIterableName;
}
Naming.SyntheticName srcIteratorName = varBaseName.suffixedBy(Suffix.$iterator$);
Type srcElementType = expr.getTarget().getQualifyingType();
JCExpression srcIterableExpr;
boolean isSuperOrSuperOf = false;
Type srcIterableType;
if (typeFact().isIterableType(expr.getPrimary().getTypeModel())) {
srcIterableType = typeFact().getIterableType(srcElementType);
} else if (typeFact().isJavaIterableType(expr.getPrimary().getTypeModel())) {
srcIterableType = typeFact().getJavaIterableDeclaration().appliedType(null, Collections.singletonList(srcElementType));
} else if (typeFact().isJavaArrayType(expr.getPrimary().getTypeModel())) {
srcIterableType = expr.getPrimary().getTypeModel();
srcElementType = typeFact().getJavaArrayElementType(srcIterableType);
} else {
return makeErroneous(expr, "unhandled iterable type");
}
if (spreadMethodReferenceInner) {
srcIterableExpr = srcIterableName.makeIdent();
} else {
boolean isSuper = isSuper(expr.getPrimary());
isSuperOrSuperOf = isSuper || isSuperOf(expr.getPrimary());
if (isSuperOrSuperOf) {
// so we just refer to it later
if (isSuper) {
Declaration member = expr.getPrimary().getTypeModel().getDeclaration().getMember("iterator", null, false);
srcIterableExpr = transformSuper(expr, (TypeDeclaration) member.getContainer());
} else
srcIterableExpr = transformSuperOf(expr, expr.getPrimary(), "iterator");
} else {
srcIterableExpr = transformExpression(expr.getPrimary(), BoxingStrategy.BOXED, srcIterableType);
}
}
// do not capture the iterable for super invocations: see above
if (!spreadMethodReferenceInner && !isSuperOrSuperOf) {
JCVariableDecl srcIterable = null;
JCExpression srcIterableTypeExpr = makeJavaType(srcIterableType, JT_NO_PRIMITIVES);
srcIterable = makeVar(Flags.FINAL, srcIterableName, srcIterableTypeExpr, srcIterableExpr);
letStmts.prepend(srcIterable);
}
/* public Object next() {
* Object result;
* if (!((result = iterator.next()) instanceof Finished)) {
* result = transformedMember(result);
* }
* return result;
*/
/* Any arguments in the member of the spread would get re-evaluated on each iteration
* so we need to shift them to the scope of the Let to ensure they're evaluated once.
*/
boolean aliasArguments = transformer instanceof InvocationTermTransformer && ((InvocationTermTransformer) transformer).invocation.getNode() instanceof Tree.InvocationExpression && ((Tree.InvocationExpression) ((InvocationTermTransformer) transformer).invocation.getNode()).getPositionalArgumentList() != null;
if (aliasArguments) {
((InvocationTermTransformer) transformer).callBuilder.argumentHandling(CallBuilder.CB_ALIAS_ARGS, varBaseName);
}
JCNewClass iterableClass;
boolean prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
try {
Naming.SyntheticName iteratorResultName = varBaseName.suffixedBy(Suffix.$element$);
JCExpression transformedElement = applyErasureAndBoxing(iteratorResultName.makeIdent(), typeFact().getAnythingType(), CodegenUtil.hasTypeErased(expr.getPrimary()), true, BoxingStrategy.BOXED, srcElementType, 0);
transformedElement = transformMemberExpression(expr, transformedElement, transformer);
// be handled by the previous recursion
if (spreadMethodReferenceOuter) {
return make().LetExpr(letStmts.toList(), transformedElement);
}
Type resultElementType = expr.getTarget().getType();
final Type resultAbsentType;
transformedElement = applyErasureAndBoxing(transformedElement, resultElementType, // not necessarily of the applied member
expr.getTarget().getDeclaration() instanceof TypedDeclaration ? CodegenUtil.hasTypeErased((TypedDeclaration) expr.getTarget().getDeclaration()) : false, !CodegenUtil.isUnBoxed(expr), BoxingStrategy.BOXED, resultElementType, 0);
MethodDefinitionBuilder nextMdb = MethodDefinitionBuilder.systemMethod(this, "next");
nextMdb.isOverride(true);
nextMdb.annotationFlags(Annotations.IGNORE);
nextMdb.modifiers(Flags.PUBLIC | Flags.FINAL);
nextMdb.resultType(new TransformedType(make().Type(syms().objectType)));
final List<JCTree> l;
if (typeFact().isIterableType(expr.getPrimary().getTypeModel())) {
// private Iterator<srcElementType> iterator = srcIterableName.iterator();
JCVariableDecl srcIterator = makeVar(Flags.FINAL, srcIteratorName, makeJavaType(typeFact().getIteratorType(srcElementType)), make().Apply(null, // for super we do not capture it because we can't and it's constant anyways
naming.makeQualIdent(isSuperOrSuperOf ? srcIterableExpr : srcIterableName.makeIdent(), "iterator"), List.<JCExpression>nil()));
resultAbsentType = typeFact().getIteratedAbsentType(expr.getPrimary().getTypeModel());
nextMdb.body(List.of(makeVar(iteratorResultName, make().Type(syms().objectType), null), make().If(make().Unary(JCTree.Tag.NOT, make().TypeTest(make().Assign(iteratorResultName.makeIdent(), make().Apply(null, naming.makeQualIdent(srcIteratorName.makeIdent(), "next"), List.<JCExpression>nil())), make().Type(syms().ceylonFinishedType))), make().Block(0, List.<JCStatement>of(make().Exec(make().Assign(iteratorResultName.makeIdent(), transformedElement)))), null), make().Return(iteratorResultName.makeIdent())));
l = List.of(srcIterator, nextMdb.build());
} else if (typeFact().isJavaIterableType(expr.getPrimary().getTypeModel())) {
// private Iterator<srcElementType> iterator = srcIterableName.iterator();
JCVariableDecl srcIterator = makeVar(Flags.PRIVATE | Flags.FINAL, srcIteratorName, makeJavaType(typeFact().getJavaIteratorType(srcElementType)), make().Apply(null, // for super we do not capture it because we can't and it's constant anyways
naming.makeQualIdent(isSuperOrSuperOf ? srcIterableExpr : srcIterableName.makeIdent(), "iterator"), List.<JCExpression>nil()));
resultAbsentType = typeFact().getNullType();
nextMdb.body(List.<JCStatement>of(make().If(make().Apply(null, naming.makeQualIdent(srcIteratorName.makeIdent(), "hasNext"), List.<JCExpression>nil()), make().Block(0, List.<JCStatement>of(makeVar(iteratorResultName, make().Type(syms().objectType), make().Apply(null, naming.makeQualIdent(srcIteratorName.makeIdent(), "next"), List.<JCExpression>nil())), make().Return(transformedElement))), make().Return(makeFinished()))));
l = List.of(srcIterator, nextMdb.build());
} else if (typeFact().isJavaArrayType(expr.getPrimary().getTypeModel())) {
resultAbsentType = typeFact().getNullType();
JCVariableDecl srcIndex = makeVar(Flags.PRIVATE, srcIteratorName, make().Type(syms().intType), make().Literal(0));
JCExpression indexed = make().Indexed(srcIterableName.makeIdent(), make().Unary(Tag.POSTINC, srcIteratorName.makeIdent()));
if (typeFact().isJavaPrimitiveArrayType(expr.getPrimary().getTypeModel())) {
indexed = applyErasureAndBoxing(indexed, srcElementType, false, BoxingStrategy.BOXED, srcElementType);
}
nextMdb.body(List.<JCStatement>of(make().If(make().Binary(Tag.LT, srcIteratorName.makeIdent(), // for super we do not capture it because we can't and it's constant anyways
naming.makeQualIdent(isSuperOrSuperOf ? srcIterableExpr : srcIterableName.makeIdent(), "length")), make().Block(0, List.<JCStatement>of(makeVar(iteratorResultName, make().Type(syms().objectType), indexed), make().Return(transformedElement))), make().Return(makeFinished()))));
l = List.of(srcIndex, nextMdb.build());
} else {
return makeErroneous(expr, "unhandled iterable type");
}
// new AbstractIterator()
JCNewClass iteratorClass = make().NewClass(null, null, make().TypeApply(make().QualIdent(syms().ceylonAbstractIteratorType.tsym), List.of(makeJavaType(resultElementType, JT_TYPE_ARGUMENT))), List.of(makeReifiedTypeArgument(resultElementType)), make().AnonymousClassDef(make().Modifiers(0), l));
MethodDefinitionBuilder iteratorMdb = MethodDefinitionBuilder.systemMethod(this, "iterator");
iteratorMdb.isOverride(true);
iteratorMdb.annotationFlags(Annotations.IGNORE);
iteratorMdb.modifiers(Flags.PUBLIC | Flags.FINAL);
iteratorMdb.resultType(new TransformedType(makeJavaType(typeFact().getIteratorType(resultElementType)), makeAtNonNull()));
iteratorMdb.body(make().Return(iteratorClass));
// new AbstractIterable()
iterableClass = make().NewClass(null, null, make().TypeApply(make().QualIdent(syms().ceylonAbstractIterableType.tsym), List.of(makeJavaType(resultElementType, JT_TYPE_ARGUMENT), makeJavaType(resultAbsentType, JT_TYPE_ARGUMENT))), List.of(makeReifiedTypeArgument(resultElementType), makeReifiedTypeArgument(resultAbsentType)), make().AnonymousClassDef(make().Modifiers(0), List.<JCTree>of(iteratorMdb.build())));
} finally {
expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
}
if (aliasArguments) {
letStmts = letStmts.appendList(((InvocationTermTransformer) transformer).callBuilder.getStatements());
}
JCMethodInvocation result = make().Apply(null, naming.makeQualIdent(iterableClass, "sequence"), List.<JCExpression>nil());
JCExpression spread = letStmts.isEmpty() ? result : make().LetExpr(letStmts.toList(), result);
// Do we *statically* know the result must be a Sequence
final boolean primaryIsSequence = typeFact().isNonemptyIterableType(expr.getPrimary().getTypeModel());
Type returnElementType = expr.getTarget().getType();
if (primaryIsSequence) {
int flags = EXPR_DOWN_CAST;
spread = applyErasureAndBoxing(spread, typeFact().getSequentialType(returnElementType), false, true, BoxingStrategy.BOXED, primaryIsSequence ? typeFact().getSequenceType(returnElementType) : typeFact().getSequentialType(returnElementType), flags);
}
return spread;
} finally {
spreading = oldSpreading;
}
}
use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.
the class InitializerBuilder method build.
/**
* Only called for classes with parameter lists
*/
JCMethodDecl build() {
if (delegateCall != null) /* && !isAlias*/
{
init.add(0, delegateCall);
}
List<JCStatement> body = statementsBetween(null, null);
int index = 0;
for (JCStatement stmt : body) {
if (stmt instanceof JCThrow) {
ListBuffer<JCStatement> filtered = new ListBuffer<JCStatement>();
filtered.addAll(body.subList(0, index + 1));
body = filtered.toList();
break;
}
index++;
}
MethodDefinitionBuilder constructor = MethodDefinitionBuilder.constructor(gen, deprecated);
constructor.modifiers(modifiers).userAnnotations(userAnnos.toList()).parameters(params.toList()).body(body);
return constructor.build();
}
use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.
the class ClassTransformer method serializationConstructor.
/**
* <p>Generates the serialization constructor
* with signature {@code ($Serialization$)} which:</p>
* <ul>
* <li>invokes {@code super()}, if the super class is also
* serializable,</li>
* <li>initializes all companion instance fields to a
* newly instantiated companion instance,</li>
* <li>initializes all reified type argument fields to null,</li>
* <li>initializes all reference attribute fields to null,</li>
* <li>initializesall primitive attribute fields to a default
* value (basically some kind of 0)</li>
* </ul>
*/
private void serializationConstructor(Class model, ClassDefinitionBuilder classBuilder) {
MethodDefinitionBuilder ctor = classBuilder.addConstructor(model.isDeprecated());
ctor.ignoreModelAnnotations();
ctor.modifiers(PUBLIC);
ParameterDefinitionBuilder serializationPdb = ParameterDefinitionBuilder.systemParameter(this, "ignored");
serializationPdb.modifiers(FINAL);
serializationPdb.type(new TransformedType(make().Type(syms().ceylonSerializationType), null));
ctor.parameter(serializationPdb);
for (TypeParameter tp : model.getTypeParameters()) {
ctor.reifiedTypeParameter(tp);
}
final ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
if (extendsSerializable(model)) {
// invoke super
ListBuffer<JCExpression> superArgs = new ListBuffer<JCExpression>();
superArgs.add(naming.makeUnquotedIdent("ignored"));
for (JCExpression ta : makeReifiedTypeArguments(model.getExtendedType())) {
superArgs.add(ta);
}
stmts.add(make().Exec(make().Apply(null, naming.makeSuper(), superArgs.toList())));
}
buildFieldInits(model, classBuilder, stmts);
ctor.body(stmts.toList());
}
use of org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer in project ceylon by eclipse.
the class ClassTransformer method buildJpaConstructor.
protected void buildJpaConstructor(Class model, ClassDefinitionBuilder classBuilder) {
MethodDefinitionBuilder ctor = classBuilder.addConstructor(model.isDeprecated());
ctor.modelAnnotations(makeAtJpa());
ctor.modelAnnotations(makeAtIgnore());
ctor.modifiers(modifierTransformation().jpaConstructor(model));
for (TypeParameter tp : model.getTypeParameters()) {
ctor.reifiedTypeParameter(tp);
}
final ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
// invoke super (or this if
ListBuffer<JCExpression> superArgs = new ListBuffer<JCExpression>();
if (model.isSerializable()) {
superArgs.add(make().TypeCast(make().QualIdent(syms().ceylonSerializationType.tsym), makeNull()));
for (JCExpression ta : makeReifiedTypeArguments(model.getType())) {
superArgs.add(ta);
}
} else {
for (JCExpression ta : makeReifiedTypeArguments(model.getExtendedType())) {
superArgs.add(ta);
}
}
stmts.add(make().Exec(make().Apply(null, model.isSerializable() ? naming.makeThis() : naming.makeSuper(), superArgs.toList())));
if (!model.isSerializable()) {
buildFieldInits(model, classBuilder, stmts);
}
ctor.body(stmts.toList());
}
Aggregations