use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.
the class ExpressionTransformer method knownNullSafe.
private static boolean knownNullSafe(Tree.Term term) {
if (term instanceof Tree.InvocationExpression) {
Tree.InvocationExpression ie = (Tree.InvocationExpression) term;
Tree.Term p = ie.getPrimary();
if (p instanceof Tree.StaticMemberOrTypeExpression) {
Tree.StaticMemberOrTypeExpression bme = (Tree.StaticMemberOrTypeExpression) p;
Declaration dec = bme.getDeclaration();
if (dec != null) {
String qname = dec.getQualifiedNameString();
return knownNullSafe.contains(qname);
}
}
}
return false;
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.
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);
// getMostPreciseType(term, getTypeArgument(valueType, 0));
final Type returnType = term.getTypeModel();
// we work on boxed types unless we could have optimised
return transformAssignAndReturnOperation(expr, term, !canOptimise, term.getTypeModel(), 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.Tag.PLUS : JCTree.Tag.MINUS, previousValue, makeInteger(1));
ret = unAutoPromote(ret, returnType, expr.getSmall());
return ret;
}
// make this call: previousValue.getSuccessor() or previousValue.getPredecessor()
return make().Apply(null, makeSelect(previousValue, operator.getCeylonMethodName()), List.<JCExpression>nil());
}
});
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.DefaultOp op) {
Term elseTerm = unwrapExpressionUntilTerm(op.getRightTerm());
Type typeModel = typeFact().denotableType(op.getTypeModel());
// make sure we do not insert null checks if we're going to allow testing for null
Type rightExpectedType = getOptionalTypeForInteropIfAllowed(expectedType, typeModel, elseTerm);
if (unwrapExpressionUntilTerm(op.getLeftTerm()) instanceof Tree.ThenOp) {
// Optimize cond then foo else bar (avoids unnecessary boxing in particular)
Tree.ThenOp then = (Tree.ThenOp) unwrapExpressionUntilTerm(op.getLeftTerm());
Term condTerm = then.getLeftTerm();
Term thenTerm = then.getRightTerm();
JCExpression cond = transformExpression(condTerm, BoxingStrategy.UNBOXED, condTerm.getTypeModel());
JCExpression thenpart = transformExpression(thenTerm, CodegenUtil.getBoxingStrategy(op), rightExpectedType);
JCExpression elsepart = transformExpression(elseTerm, CodegenUtil.getBoxingStrategy(op), rightExpectedType);
return make().Conditional(cond, thenpart, elsepart);
}
JCExpression left = transformExpression(op.getLeftTerm(), BoxingStrategy.BOXED, typeFact().getOptionalType(typeModel));
JCExpression right = transformExpression(elseTerm, BoxingStrategy.BOXED, rightExpectedType);
Naming.SyntheticName varName = naming.temp();
JCExpression varIdent = varName.makeIdent();
JCExpression test = at(op).Binary(JCTree.Tag.NE, varIdent, makeNull());
JCExpression cond = make().Conditional(test, varIdent, right);
JCExpression typeExpr = makeJavaType(typeModel, JT_NO_PRIMITIVES);
return makeLetExpr(varName, null, typeExpr, left, cond);
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.
the class ExpressionTransformer method transformArg.
protected final JCExpression transformArg(SimpleInvocation invocation, int argIndex) {
final Tree.Term expr = invocation.getArgumentExpression(argIndex);
if (invocation.hasParameter(argIndex)) {
Type type = invocation.getParameterType(argIndex);
if (invocation.isParameterSequenced(argIndex) && // Java methods need their underlying type preserved
!invocation.isJavaVariadicMethod()) {
if (!invocation.isArgumentSpread(argIndex)) {
// If the parameter is sequenced and the argument is not ...
// then the expected type of the *argument* is the type arg to Iterator
type = typeFact().getIteratedType(type);
} else if (invocation.getArgumentType(argIndex).getSupertype(typeFact().getSequentialDeclaration()) == null) {
// On the other hand, if the parameter is sequenced and the argument is spread,
// but not sequential, then transformArguments() will use getSequence(),
// so we only need to expect an Iterable type
type = org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType(typeFact().getIterableDeclaration(), typeFact().getIteratedType(type), typeFact().getIteratedAbsentType(type));
}
}
BoxingStrategy boxingStrategy = invocation.getParameterBoxingStrategy(argIndex);
int flags = 0;
if (!invocation.isParameterRaw(argIndex))
flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_NOT_RAW;
if (invocation.isParameterWithConstrainedTypeParameters(argIndex))
flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
if (invocation.isParameterWithDependentCovariantTypeParameters(argIndex))
flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_DEPENDENT_COVARIANT_TYPE_PARAMETERS;
if (invocation.erasedArgument(unwrapExpressionUntilTerm(expr))) {
flags |= EXPR_DOWN_CAST;
}
if (!expr.getSmall() && invocation.getParameterSmall(argIndex)) {
flags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
}
boolean coerced = invocation.isParameterCoerced(argIndex);
if (coerced) {
flags |= ExpressionTransformer.EXPR_IS_COERCED;
if (invocation.isParameterJavaVariadic(argIndex) && type.isSequential()) {
type = typeFact().getSequentialElementType(type);
}
}
JCExpression ret = transformExpression(expr, boxingStrategy, type, flags);
// We can coerce most SAMs in transformExpression, EXCEPT invocation
// calls which we do here.
Term term = Decl.unwrapExpressionsUntilTerm(expr);
if (coerced && term instanceof Tree.InvocationExpression && isFunctionalResult(term.getTypeModel()) && checkForFunctionalInterface(type) != null) {
return transformFunctionalInterfaceBridge((Tree.InvocationExpression) term, ret, type);
}
return ret;
} else {
// Overloaded methods don't have a reference to a parameter
// so we have to treat them differently. Also knowing it's
// overloaded we know we're dealing with Java code so we unbox
Type type = expr.getTypeModel();
return expressionGen().transformExpression(expr, BoxingStrategy.UNBOXED, type);
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.
the class ExpressionTransformer method checkForByteLiterals.
private JCExpression checkForByteLiterals(Tree.InvocationExpression ce) {
// same test as in BoxingVisitor.isByteLiteral()
if (ce.getPrimary() instanceof Tree.BaseTypeExpression && ce.getPositionalArgumentList() != null) {
java.util.List<Tree.PositionalArgument> positionalArguments = ce.getPositionalArgumentList().getPositionalArguments();
if (positionalArguments.size() == 1) {
PositionalArgument argument = positionalArguments.get(0);
if (argument instanceof Tree.ListedArgument && ((Tree.ListedArgument) argument).getExpression() != null) {
Term term = ((Tree.ListedArgument) argument).getExpression().getTerm();
boolean negative = false;
if (term instanceof Tree.NegativeOp) {
negative = true;
term = ((Tree.NegativeOp) term).getTerm();
}
if (term instanceof Tree.NaturalLiteral) {
Declaration decl = ((Tree.BaseTypeExpression) ce.getPrimary()).getDeclaration();
if (decl instanceof Class) {
if (((Class) decl).isByte()) {
at(ce);
try {
long value = literalValue((Tree.NaturalLiteral) term).longValue();
if (negative)
value = -value;
// assignment, not for method calls, so it's simpler to always cast
return make().TypeCast(syms().byteType, make().Literal(value));
} catch (ErroneousException e) {
// replaced with a throw.
return e.makeErroneous(this);
}
}
}
}
}
}
}
return null;
}
Aggregations