use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method makeMemberValueOrFunctionDeclarationLiteral.
JCExpression makeMemberValueOrFunctionDeclarationLiteral(Node node, Declaration declaration, boolean f) {
// it's a member we get from its container declaration
if (declaration.getContainer() instanceof ClassOrInterface == false)
return makeErroneous(node, "compiler bug: " + declaration.getContainer() + " is not a supported type parameter container");
ClassOrInterface container = (ClassOrInterface) declaration.getContainer();
// use the generated class to get to the declaration literal
JCExpression metamodelCall = makeTypeDeclarationLiteral(container);
JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration(Decl.isConstructor(declaration) ? "ClassDeclaration" : "ClassOrInterfaceDeclaration").getType(), JT_NO_PRIMITIVES);
metamodelCall = make().TypeCast(metamodelCast, metamodelCall);
String memberClassName;
String memberAccessor;
if (declaration instanceof Class)
memberClassName = "ClassDeclaration";
else if (Decl.isConstructor(declaration))
memberClassName = "ConstructorDeclaration";
else if (declaration instanceof Interface)
memberClassName = "InterfaceDeclaration";
else if (declaration instanceof Function)
memberClassName = "FunctionDeclaration";
else if (declaration instanceof Value) {
memberClassName = "ValueDeclaration";
} else {
return makeErroneous(node, "compiler bug: " + declaration + " is not a supported declaration literal");
}
if (Decl.isConstructor(declaration))
memberAccessor = "getConstructorDeclaration";
else
memberAccessor = f ? "getMemberDeclaration" : "getDeclaredMemberDeclaration";
TypeDeclaration metamodelDecl = (TypeDeclaration) typeFact().getLanguageModuleDeclarationDeclaration(memberClassName);
JCExpression memberType = makeJavaType(metamodelDecl.getType());
JCExpression reifiedMemberType = makeReifiedTypeArgument(metamodelDecl.getType());
JCExpression memberCall = make().Apply(List.of(memberType), makeSelect(metamodelCall, memberAccessor), List.of(reifiedMemberType, ceylonLiteral(declaration.getName())));
return memberCall;
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformOverridableBinaryOperator.
private JCExpression transformOverridableBinaryOperator(OperatorTranslation originalOperator, OptimisationStrategy optimisationStrategy, JCExpression left, JCExpression right, Tree.Term leftTerm, Type leftType, Tree.Term rightTerm, Type expectedType) {
JCExpression result = null;
// optimise if we can
if (optimisationStrategy.useJavaOperator()) {
result = make().Binary(originalOperator.javacOperator, left, right);
if (rightTerm != null) {
result = unAutoPromote(result, expectedType);
}
return result;
}
boolean loseComparison = originalOperator == OperatorTranslation.BINARY_SMALLER || originalOperator == OperatorTranslation.BINARY_SMALL_AS || originalOperator == OperatorTranslation.BINARY_LARGER || originalOperator == OperatorTranslation.BINARY_LARGE_AS;
// for comparisons we need to invoke compare()
OperatorTranslation actualOperator = originalOperator;
if (loseComparison) {
actualOperator = Operators.OperatorTranslation.BINARY_COMPARE;
}
List<JCExpression> args = List.of(right);
List<JCExpression> typeArgs = null;
// Set operators need reified generics
if (originalOperator == OperatorTranslation.BINARY_UNION || originalOperator == OperatorTranslation.BINARY_INTERSECTION || originalOperator == OperatorTranslation.BINARY_COMPLEMENT) {
Type otherSetElementType = typeFact().getIteratedType(rightTerm.getTypeModel());
args = args.prepend(makeReifiedTypeArgument(otherSetElementType));
typeArgs = List.<JCExpression>of(makeJavaType(otherSetElementType, JT_TYPE_ARGUMENT));
}
if (optimisationStrategy.useValueTypeMethod()) {
int flags = JT_NO_PRIMITIVES;
if (optimisationStrategy == OptimisationStrategy.OPTIMISE_VALUE_TYPE && leftType.getDeclaration().getSelfType() != null) {
leftType = leftType.getTypeArguments().get(leftType.getDeclaration().getSelfType().getDeclaration());
}
result = make().Apply(typeArgs, naming.makeQualIdent(makeJavaType(leftType, flags), actualOperator.ceylonMethod), args.prepend(left));
} else {
if ((originalOperator == OperatorTranslation.BINARY_LARGE_AS || originalOperator == OperatorTranslation.BINARY_LARGER || originalOperator == OperatorTranslation.BINARY_SMALL_AS || originalOperator == OperatorTranslation.BINARY_SMALLER || originalOperator == OperatorTranslation.BINARY_COMPARE) && willEraseToObject(leftType)) {
left = make().TypeCast(makeJavaType(typeFact().getComparableDeclaration().getType(), JT_RAW), left);
args = List.<JCExpression>of(make().TypeCast(makeJavaType(typeFact().getComparableDeclaration().getType(), JT_RAW), right));
}
result = make().Apply(typeArgs, makeSelect(left, actualOperator.ceylonMethod), args);
}
if (loseComparison) {
// We cheat slightly bu using == instead of equals, but since those values
// don't override equals the effect is the same
result = make().Binary(originalOperator.javacValueOperator, result, makeLanguageValue(originalOperator.ceylonValue));
}
return result;
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformBaseInstantiation.
private JCExpression transformBaseInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
JCExpression resultExpr;
Tree.BaseTypeExpression type = (Tree.BaseTypeExpression) invocation.getPrimary();
Declaration declaration = type.getDeclaration();
invocation.location(callBuilder);
if (Strategy.generateInstantiator(declaration)) {
resultExpr = callBuilder.typeArguments(List.<JCExpression>nil()).invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, (Class) declaration)).build();
if (Strategy.isInstantiatorUntyped(declaration)) {
// $new method declared to return Object, so needs typecast
resultExpr = make().TypeCast(makeJavaType(((TypeDeclaration) declaration).getType()), resultExpr);
}
} else {
Type classType = (Type) type.getTarget();
if (isJavaArray(classType)) {
JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_RAW);
callBuilder.javaArrayInstance(typeExpr);
if (isJavaObjectArray(classType)) {
Type elementType = classType.getTypeArgumentList().get(0);
MultidimensionalArray multiArray = getMultiDimensionalArrayInfo(elementType);
if (multiArray != null)
elementType = multiArray.type;
// array of Foo is fine, array of Nothing too
if (elementType.getDeclaration() instanceof ClassOrInterface || elementType.isNothing()) {
if (!elementType.getTypeArgumentList().isEmpty())
callBuilder.javaArrayInstanceNeedsCast(makeJavaType(classType, AbstractTransformer.JT_NO_PRIMITIVES));
} else {
// if it's an array of union, intersection or type param we need a runtime allocation
callBuilder.javaArrayInstanceIsGeneric(makeReifiedTypeArgument(elementType), multiArray != null ? multiArray.dimension + 1 : 1);
}
}
} else {
if (Decl.isConstructor(classType.getDeclaration())) {
classType = classType.getExtendedType();
}
JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
callBuilder.instantiate(typeExpr);
}
resultExpr = callBuilder.build();
}
return resultExpr;
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
public JCTree transform(Tree.ObjectExpression expr) {
at(expr);
List<JCTree> klass = classGen().transformObjectExpression(expr);
at(expr);
JCExpression newCall = make().NewClass(null, null, makeUnquotedIdent(naming.escapeClassName(expr.getAnonymousClass().getName()) + "_"), List.<JCTree.JCExpression>nil(), null);
return make().LetExpr((List) klass, newCall);
}
use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transform.
// Prefix operator
public JCExpression transform(final Tree.PrefixOperatorExpression expr) {
final OperatorTranslation operator = Operators.getOperator(expr.getClass());
if (operator == null) {
return makeErroneous(expr, "compiler bug: " + expr.getNodeType() + " is not supported yet");
}
OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
final boolean canOptimise = optimisationStrategy.useJavaOperator();
Tree.Term term = expr.getTerm();
// only fully optimise if we don't have to access the getter/setter
if (canOptimise && CodegenUtil.isDirectAccessVariable(term)) {
JCExpression jcTerm = transformExpression(term, BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
return at(expr).Unary(operator.javacOperator, jcTerm);
}
Interface compoundType = expr.getUnit().getOrdinalDeclaration();
Type valueType = getSupertype(term, compoundType);
final Type returnType = getMostPreciseType(term, getTypeArgument(valueType, 0));
// we work on boxed types unless we could have optimised
return transformAssignAndReturnOperation(expr, term, !canOptimise, valueType, returnType, new AssignAndReturnOperationFactory() {
@Override
public JCExpression getNewValue(JCExpression previousValue) {
// use +1/-1 if we can optimise a bit
if (canOptimise) {
JCExpression ret = make().Binary(operator == OperatorTranslation.UNARY_PREFIX_INCREMENT ? JCTree.PLUS : JCTree.MINUS, previousValue, makeInteger(1));
ret = unAutoPromote(ret, returnType);
return ret;
}
// make this call: previousValue.getSuccessor() or previousValue.getPredecessor()
return make().Apply(null, makeSelect(previousValue, operator.ceylonMethod), List.<JCExpression>nil());
}
});
}
Aggregations