use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class AbstractTransformer method convertToIntForHashAttribute.
/**
* Turn this long value into an int value by applying (int)(e ^ (e >>> 32))
*/
public JCExpression convertToIntForHashAttribute(JCExpression value) {
SyntheticName tempName = naming.temp("hash");
JCExpression type = make().Type(syms().longType);
JCBinary combine = make().Binary(JCTree.Tag.BITXOR, makeUnquotedIdent(tempName.asName()), make().Binary(JCTree.Tag.USR, makeUnquotedIdent(tempName.asName()), makeInteger(32)));
return make().TypeCast(syms().intType, makeLetExpr(tempName, null, type, value, combine));
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class AbstractTransformer method boxJavaType.
JCExpression boxJavaType(JCExpression expr, Type type) {
JCExpression allowNull = make().Literal(!type.isSubtypeOf(typeFact().getObjectType()));
type = simplifyType(type);
if (type.isSubtypeOf(typeFact().getNullType())) {
return expr;
} else if (type.isString()) {
return expr;
} else if (type.getDeclaration().equals(typeFact().getListDeclaration())) {
// Wrappings.toCeylonList().inverse()
Type elementType = type.getTypeArgumentList().get(0);
return make().Apply(null, makeSelect(make().Apply(null, makeSelect(make().Apply(List.<JCExpression>of(isJavaBoxableType(elementType, true) ? javaBoxType(elementType) : makeJavaType(elementType, JT_TYPE_ARGUMENT), makeJavaType(elementType, JT_TYPE_ARGUMENT)), makeQuotedFQIdent("org.eclipse.ceylon.compiler.java.wrapping.Wrappings.toCeylonList"), List.<JCExpression>of(makeReifiedTypeArgument(elementType), allowNull)), "inverted"), List.<JCExpression>nil()), "wrap"), List.<JCExpression>of(expr));
} else if (type.getDeclaration().equals(typeFact().getSetDeclaration())) {
Type elementType = type.getTypeArgumentList().get(0);
return make().Apply(null, makeSelect(make().Apply(null, makeSelect(make().Apply(List.<JCExpression>of(isJavaBoxableType(elementType, true) ? javaBoxType(elementType) : makeJavaType(elementType, JT_TYPE_ARGUMENT), makeJavaType(elementType, JT_TYPE_ARGUMENT)), makeQuotedFQIdent("org.eclipse.ceylon.compiler.java.wrapping.Wrappings.toCeylonSet"), List.<JCExpression>of(makeReifiedTypeArgument(elementType), allowNull)), "inverted"), List.<JCExpression>nil()), "wrap"), List.<JCExpression>of(expr));
} else if (type.getDeclaration().equals(typeFact().getMapDeclaration())) {
Type keyType = type.getTypeArgumentList().get(0);
Type itemType = type.getTypeArgumentList().get(1);
return make().Apply(null, makeSelect(make().Apply(null, makeSelect(make().Apply(List.<JCExpression>of(isJavaBoxableType(keyType, true) ? javaBoxType(keyType) : makeJavaType(keyType, JT_TYPE_ARGUMENT), isJavaBoxableType(itemType, true) ? javaBoxType(itemType) : makeJavaType(itemType, JT_TYPE_ARGUMENT), makeJavaType(keyType, JT_TYPE_ARGUMENT), makeJavaType(itemType, JT_TYPE_ARGUMENT)), makeQuotedFQIdent("org.eclipse.ceylon.compiler.java.wrapping.Wrappings.toCeylonMap"), List.<JCExpression>of(makeReifiedTypeArgument(keyType), makeReifiedTypeArgument(itemType), allowNull)), "inverted"), List.<JCExpression>nil()), "wrap"), List.<JCExpression>of(expr));
} else {
return make().Apply(null, makeSelect(javaBoxType(type), "valueOf"), List.<JCExpression>of(expr));
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class AbstractTransformer method makeAtMember.
JCAnnotation makeAtMember(Type type) {
JCExpression classAttribute = make().Assign(naming.makeUnquotedIdent("klass"), makeClassLiteral(type));
List<JCExpression> attributes = List.of(classAttribute);
return make().Annotation(makeIdent(syms().ceylonAtMemberType), attributes);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class AbstractTransformer method makeTypeArgs.
private ListBuffer<JCExpression> makeTypeArgs(boolean isCeylonCallable, int flags, Map<TypeParameter, Type> tas, java.util.List<TypeParameter> tps, Type simpleType) {
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
for (TypeParameter tp : tps) {
Type ta = tas.get(tp);
// error handling
if (ta == null)
continue;
boolean isDependedOn = hasDependentTypeParameters(tps, tp);
// record whether we were initially working with Anything, because getNonNullType turns it into Object
// and we need to treat "in Anything" specially below
boolean isAnything = isAnything(ta);
// we want, so we make sure it's not Null
if (isOptional(ta) && !isNull(ta)) {
// For an optional type T?:
// - The Ceylon type Foo<T?> results in the Java type Foo<T>.
ta = getNonNullType(ta);
}
// In a type argument Foo<X&Object> or Foo<X?> transform to just Foo<X>
ta = simplifyType(ta);
if (typeFact().isUnion(ta) || typeFact().isIntersection(ta)) {
// conform with where raw types would be used between expressions and constructors
if (((flags & (JT_EXTENDS | JT_SATISFIES)) != 0 && tp.getSelfTypedDeclaration() != null)) {
// A bit ugly, but we need to escape from the loop and create a raw type, no generics
if ((flags & (JT_EXTENDS | JT_SATISFIES)) != 0)
throw new BugException("rawSupertype() should prevent this method going raw when JT_EXTENDS | JT_SATISFIES");
typeArgs = null;
break;
} else if ((flags & (__JT_FULL_TYPE | JT_EXTENDS | JT_SATISFIES)) == 0) {
if ((flags & (JT_EXTENDS | JT_SATISFIES)) != 0)
throw new BugException("rawSupertype() should prevent this method going raw when JT_EXTENDS | JT_SATISFIES");
typeArgs = null;
break;
}
// otherwise just go on
}
if (isCeylonBoolean(ta) && !isTypeParameter(ta)) {
ta = typeFact.getBooleanType();
}
JCExpression jta;
if (!tp.getSatisfiedTypes().isEmpty()) {
boolean needsCastForBounds = false;
for (Type bound : tp.getSatisfiedTypes()) {
bound = bound.substitute(tas, null);
needsCastForBounds |= expressionGen().needsCast(ta, bound, false, false, false);
}
if (needsCastForBounds) {
// replace with the first bound
ta = tp.getSatisfiedTypes().get(0).substitute(tas, null);
if (tp.getSatisfiedTypes().size() > 1 || isBoundsSelfDependant(tp) || isBoundsRecursive(simpleType, tp) || willEraseToObject(ta) || // we should reject it for all non-covariant types, unless we're in satisfies/extends
((flags & (JT_SATISFIES | JT_EXTENDS)) == 0 && !simpleType.isCovariant(tp))) {
if ((flags & (JT_EXTENDS | JT_SATISFIES)) != 0)
throw new BugException("rawSupertype() should prevent this method going raw when JT_EXTENDS | JT_SATISFIES");
// A bit ugly, but we need to escape from the loop and create a raw type, no generics
typeArgs = null;
break;
}
}
}
if (ta.isExactlyNothing() || // use the same erasure rules as bottom: prefer wildcards
((flags & (__JT_FULL_TYPE | JT_EXTENDS | JT_SATISFIES)) != 0 && (typeFact().isUnion(ta) || typeFact().isIntersection(ta)))) {
// For the bottom type Bottom:
if ((flags & (JT_CLASS_NEW)) != 0) {
// A bit ugly, but we need to escape from the loop and create a raw type, no generics
if ((flags & (JT_EXTENDS | JT_SATISFIES)) != 0)
throw new BugException("rawSupertype() should prevent this method going raw when JT_EXTENDS | JT_SATISFIES");
typeArgs = null;
break;
} else {
// Foo<Object> (see https://github.com/ceylon/ceylon-compiler/issues/633 for why)
if ((flags & (JT_SATISFIES | JT_EXTENDS)) != 0) {
if (ta.isExactlyNothing()) {
jta = make().Type(syms().objectType);
} else {
if (!tp.getSatisfiedTypes().isEmpty()) {
// union or intersection: Use the common upper bound of the types
jta = makeJavaType(tp.getSatisfiedTypes().get(0), JT_TYPE_ARGUMENT);
} else {
jta = make().Type(syms().objectType);
}
}
} else if (ta.isExactlyNothing()) {
// see https://github.com/ceylon/ceylon-compiler/issues/1003
if (simpleType.isContravariant(tp)) {
typeArgs = null;
break;
} else if (tp.isCovariant() && !isDependedOn) {
// DO NOT trust use-site covariance for Nothing, because we consider "out Nothing" to be the same
// as "Nothing". Only look at declaration-site covariance
jta = make().Wildcard(make().TypeBoundKind(BoundKind.EXTENDS), make().Type(syms().objectType));
} else {
jta = make().Type(syms().objectType);
}
} else {
// see https://github.com/ceylon/ceylon/issues/6365
if (((flags & JT_CLASS_NEW) == 0) && simpleType.isContravariant(tp)) /* && !isDependedOn*/
{
jta = make().Wildcard(make().TypeBoundKind(BoundKind.SUPER), makeJavaType(ta, JT_TYPE_ARGUMENT));
} else if (((flags & JT_CLASS_NEW) == 0) && simpleType.isCovariant(tp) && !isDependedOn) {
jta = make().Wildcard(make().TypeBoundKind(BoundKind.EXTENDS), makeJavaType(ta, JT_TYPE_ARGUMENT));
} else {
jta = makeJavaType(ta, JT_TYPE_ARGUMENT);
}
}
}
} else {
// For an ordinary class or interface type T:
if ((flags & (JT_SATISFIES | JT_EXTENDS)) != 0) {
// - The Ceylon type Foo<T> appearing in an extends or satisfies clause
// results in the Java type Foo<T>
jta = makeJavaType(ta, JT_TYPE_ARGUMENT);
} else {
// - Foo<? super T> if Foo is contravariant in T
if (((flags & JT_CLASS_NEW) == 0) && simpleType.isContravariant(tp) && (!isAnything || tp.isContravariant())) // FIXME: it may be necessary to uncomment this in the future,
// see https://github.com/ceylon/ceylon/issues/6365
/*&& !isDependedOn*/
{
// DO NOT trust use-site contravariance for Anything, because we consider "in Anything" to be the same
// as "Anything". Only look at declaration-site contravariance
jta = make().Wildcard(make().TypeBoundKind(BoundKind.SUPER), makeJavaType(ta, JT_TYPE_ARGUMENT));
} else if (((flags & JT_CLASS_NEW) == 0) && simpleType.isCovariant(tp) && !isDependedOn) {
jta = make().Wildcard(make().TypeBoundKind(BoundKind.EXTENDS), makeJavaType(ta, JT_TYPE_ARGUMENT));
} else {
jta = makeJavaType(ta, JT_TYPE_ARGUMENT);
}
}
}
typeArgs.add(jta);
if (isCeylonCallable) {
// In the runtime Callable only has a single type param
break;
}
}
return typeArgs;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.
the class AbstractTransformer method makeVariableBoxDecl.
/**
* Makes a final {@code VariableBox<T>} (or {@code VariableBoxBoolean},
* {@code VariableBoxLong}, etc) variable decl, so that a variable can
* be captured.
* @param init The initial value
* @param The (value/parameter) declaration which is being accessed through the box.
*/
JCVariableDecl makeVariableBoxDecl(JCExpression init, TypedDeclaration declarationModel) {
List<JCExpression> args = init != null ? List.<JCExpression>of(init) : List.<JCExpression>nil();
JCExpression newBox = make().NewClass(null, List.<JCExpression>nil(), makeVariableBoxType(declarationModel), args, null);
String varName = naming.getVariableBoxName(declarationModel);
JCTree.JCVariableDecl var = make().VarDef(make().Modifiers(FINAL), names().fromString(varName), makeVariableBoxType(declarationModel), newBox);
return var;
}
Aggregations