use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.Parameter param) {
// Transform the expression marking that we're inside a defaulted parameter for $this-handling
// needDollarThis = true;
JCExpression expr;
at(param);
if (Strategy.hasDefaultParameterValueMethod(param.getParameterModel())) {
Tree.SpecifierOrInitializerExpression spec = Decl.getDefaultArgument(param);
Scope container = param.getParameterModel().getModel().getContainer();
boolean classParameter = container instanceof ClassOrInterface;
ClassOrInterface oldWithinDefaultParameterExpression = withinDefaultParameterExpression;
if (classParameter)
withinDefaultParameterExpression((ClassOrInterface) container);
if (param instanceof Tree.FunctionalParameterDeclaration) {
Tree.FunctionalParameterDeclaration fpTree = (Tree.FunctionalParameterDeclaration) param;
Tree.SpecifierExpression lazy = (Tree.SpecifierExpression) spec;
Function fp = (Function) fpTree.getParameterModel().getModel();
expr = CallableBuilder.anonymous(gen(), param, (Function) fpTree.getTypedDeclaration().getDeclarationModel(), lazy.getExpression(), ((Tree.MethodDeclaration) fpTree.getTypedDeclaration()).getParameterLists(), getTypeForFunctionalParameter(fp), true).build();
} else {
expr = transformExpression(spec.getExpression(), CodegenUtil.getBoxingStrategy(param.getParameterModel().getModel()), param.getParameterModel().getModel().getTypedReference().getFullType());
}
if (classParameter)
withinDefaultParameterExpression(oldWithinDefaultParameterExpression);
} else {
expr = makeErroneous(param, "compiler bug: no default parameter value method");
}
// needDollarThis = false;
return expr;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method transformArgument.
private ExpressionAndType transformArgument(SimpleInvocation invocation, int argIndex, BoxingStrategy boxingStrategy) {
ExpressionAndType exprAndType;
JCExpression expr = invocation.getTransformedArgumentExpression(argIndex);
Type paramType = invocation.getParameterType(argIndex);
JCExpression type = makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0);
Class ctedClass = ModelUtil.getConstructedClass(invocation.getPrimaryDeclaration());
if (argIndex == 0 && typeFact().isOptionalType(paramType) && invocation.getArgumentType(argIndex).isSubtypeOf(typeFact().getNullType()) && ctedClass != null && (ctedClass.hasConstructors() || ctedClass.isSerializable())) {
// we've invoking the default constructor, whose first parameter has optional type
// with a null argument: That will be ambiguous wrt any named constructors
// with otherwise identical signitures, so we need a typecast to
// disambiguate
expr = make().TypeCast(makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), expr);
}
exprAndType = new ExpressionAndType(expr, type);
return exprAndType;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method transformConstructorDelegation.
/**
* Transform a delegated constructor call ({@code extends XXX()})
* which may be either a superclass initializer/constructor or a
* same-class constructor.
* @param extendedType
* @param delegation The kind of delegation
* @param invocation
* @param classBuilder
* @return
*/
JCStatement transformConstructorDelegation(Node extendedType, CtorDelegation delegation, Tree.InvocationExpression invocation, ClassDefinitionBuilder classBuilder, boolean forDelegationConstructor) {
if (delegation != null && delegation.isError()) {
return delegation.makeThrow(this);
}
Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
if (paramLists.isEmpty()) {
classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: super class " + primaryDeclaration.getName() + " is missing parameter list")));
return null;
}
SuperInvocation builder = new SuperInvocation(this, classBuilder.getForDefinition(), delegation, invocation, paramLists.get(0), forDelegationConstructor);
CallBuilder callBuilder = CallBuilder.instance(this);
boolean prevFnCall = withinInvocation(true);
try {
if (invocation.getPrimary() instanceof Tree.StaticMemberOrTypeExpression) {
transformTypeArguments(callBuilder, (Tree.StaticMemberOrTypeExpression) invocation.getPrimary());
}
at(builder.getNode());
JCExpression expr = null;
Scope outerDeclaration;
if (Decl.isConstructor(primaryDeclaration)) {
outerDeclaration = builder.getPrimaryDeclaration().getContainer().getContainer();
} else {
outerDeclaration = builder.getPrimaryDeclaration().getContainer();
}
if ((Strategy.generateInstantiator(builder.getPrimaryDeclaration()) || builder.getPrimaryDeclaration() instanceof Class) && outerDeclaration instanceof Interface && !((Interface) outerDeclaration).isJava()) {
// If the subclass is inner to an interface then it will be
// generated inner to the companion and we need to qualify the
// super(), *unless* the subclass is nested within the same
// interface as it's superclass.
Scope outer = builder.getSub().getContainer();
while (!(outer instanceof Package)) {
if (outer == outerDeclaration) {
expr = naming.makeSuper();
break;
}
outer = outer.getContainer();
}
if (expr == null) {
if (delegation.isSelfDelegation()) {
throw new BugException();
}
Interface iface = (Interface) outerDeclaration;
JCExpression superQual;
if (ModelUtil.getClassOrInterfaceContainer(classBuilder.getForDefinition(), false) instanceof Interface) {
superQual = naming.makeCompanionAccessorCall(naming.makeQuotedThis(), iface);
} else {
superQual = naming.makeCompanionFieldName(iface);
}
expr = naming.makeQualifiedSuper(superQual);
}
} else {
expr = delegation.isSelfDelegation() ? naming.makeThis() : naming.makeSuper();
}
final List<JCExpression> superArguments = transformSuperInvocationArguments(classBuilder, builder, callBuilder);
JCExpression superExpr = callBuilder.invoke(expr).arguments(superArguments).build();
return at(extendedType).Exec(superExpr);
// classBuilder.getInitBuilder().superCall(at(extendedType).Exec(superExpr));
} finally {
withinInvocation(prevFnCall);
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method makeTuple.
private JCExpression makeTuple(Type tupleType, java.util.List<Tree.PositionalArgument> expressions) {
if (typeFact().isEmptyType(tupleType)) {
// A tuple terminated by empty
return makeEmpty();
}
JCExpression tail = null;
List<JCExpression> elems = List.<JCExpression>nil();
for (int i = 0; i < expressions.size(); i++) {
Tree.PositionalArgument expr = expressions.get(i);
if (expr instanceof Tree.ListedArgument) {
JCExpression elem = transformExpression(((Tree.ListedArgument) expr).getExpression());
elems = elems.append(elem);
} else if (expr instanceof Tree.SpreadArgument) {
Tree.SpreadArgument spreadExpr = (Tree.SpreadArgument) expr;
// make sure we get a spread part of the right type
Type spreadType = spreadExpr.getExpression().getTypeModel();
Type sequentialSpreadType = null;
// try to get a Sequence
if (typeFact().isNonemptyIterableType(spreadType))
sequentialSpreadType = spreadType.getSupertype(typeFact().getSequenceDeclaration());
// failing that, try Sequential
if (sequentialSpreadType == null)
sequentialSpreadType = spreadType.getSupertype(typeFact().getSequentialDeclaration());
if (sequentialSpreadType != null) {
tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, sequentialSpreadType);
} else {
// must at least be an Iterable, Java Iterable, or Java array then
Type iterableSpreadType;
Type iteratedType;
if (typeFact().isIterableType(spreadType)) {
iterableSpreadType = spreadType.getSupertype(typeFact().getIterableDeclaration());
iteratedType = typeFact().getIteratedType(iterableSpreadType);
tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
tail = utilInvocation().sequentialOf(makeReifiedTypeArgument(iteratedType), tail);
} else if (typeFact().isJavaIterableType(spreadType)) {
iterableSpreadType = spreadType.getSupertype(typeFact().getJavaIterableDeclaration());
iteratedType = typeFact().getJavaIteratedType(iterableSpreadType);
tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
tail = utilInvocation().toIterable(makeJavaType(iteratedType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(iteratedType), tail);
tail = make().Apply(null, makeSelect(tail, "sequence"), List.<JCExpression>nil());
} else if (typeFact().isJavaArrayType(spreadType)) {
if (typeFact().isJavaObjectArrayType(spreadType)) {
iterableSpreadType = spreadType.getSupertype(typeFact().getJavaObjectArrayDeclaration());
} else {
// primitive
iterableSpreadType = spreadType;
}
iteratedType = typeFact().getJavaArrayElementType(iterableSpreadType);
tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
if (typeFact().isJavaObjectArrayType(spreadType)) {
tail = utilInvocation().toIterable(makeJavaType(iteratedType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(iteratedType), tail);
} else {
// primitive
tail = utilInvocation().toIterable(tail);
}
tail = make().Apply(null, makeSelect(tail, "sequence"), List.<JCExpression>nil());
} else {
throw BugException.unhandledTypeCase(spreadType);
}
Type elementType = typeFact().getIteratedType(spreadExpr.getTypeModel());
Type sequentialType = typeFact().getSequentialType(elementType);
Type expectedType = spreadExpr.getTypeModel();
if (typeFact().isNonemptyIterableType(spreadExpr.getTypeModel())) {
expectedType = typeFact().getSequenceType(elementType);
} else if (typeFact().isIterableType(spreadExpr.getTypeModel())) {
expectedType = typeFact().getSequentialType(elementType);
}
tail = sequentialEmptiness(tail, expectedType, sequentialType);
}
} else if (expr instanceof Tree.Comprehension) {
Tree.Comprehension comp = (Tree.Comprehension) expr;
Type elementType = expr.getTypeModel();
Type expectedType = comp.getInitialComprehensionClause().getPossiblyEmpty() ? typeFact().getSequentialType(elementType) : typeFact().getSequenceType(elementType);
tail = comprehensionAsSequential(comp, expectedType);
} else {
return makeErroneous(expr, "compiler bug: " + expr.getNodeType() + " is not a supported tuple argument");
}
}
if (!elems.isEmpty()) {
JCExpression reifiedTypeArg = makeReifiedTypeArgument(tupleType.getTypeArgumentList().get(0));
List<JCExpression> args = List.<JCExpression>of(reifiedTypeArg);
args = args.append(make().NewArray(make().Type(syms().objectType), List.<JCExpression>nil(), elems));
if (tail != null) {
args = args.append(tail);
}
JCExpression typeExpr = makeJavaType(tupleType, JT_TYPE_ARGUMENT);
/* Tuple.instance(reifiedElement, new Object[]{elem, elem, elem}, tail) */
return make().TypeCast(typeExpr, make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(make().QualIdent(syms().ceylonTupleType.tsym), "instance"), args));
} else {
return tail;
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCTree transform(Tree.Exists op) {
// for the purpose of checking if something is null, we need it boxed and optional, otherwise
// for some Java calls if we consider it non-optional we will get an unwanted null check
Type termType = op.getTerm().getTypeModel();
if (!typeFact().isOptionalType(termType)) {
termType = typeFact().getOptionalType(termType);
}
JCExpression expression = transformExpression(op.getTerm(), BoxingStrategy.BOXED, termType);
at(op);
return make().Binary(JCTree.Tag.NE, expression, makeNull());
}
Aggregations