if (cast) {
newReturnValue = new JavaExpression.CastExpression(resultTypeName, newReturnValue);
}
return new ReturnStatement (newReturnValue);
}
}
JavaExpression dataInstanceValue = handleDataInstance(returnValue);
if (dataInstanceValue != null) {
return new ReturnStatement(dataInstanceValue);
}
// See if we're returning a cached literal value.
//For example, this applies in the case of Prelude.signumInt and signumLong. We want the unboxed versions
//to return the literal constant values instead of evaluating and unboxing the RTValues.
if (returnValue instanceof JavaExpression.JavaField.Static) {
final JavaField.Static field = (JavaField.Static)returnValue;
final String fieldName = field.getFieldName();
if (fieldName.startsWith(SCJavaDefn.LITERAL_PREFIX)) {
for (final KernelLiteral kl : sharedValues.getLiteralValues()) {
//Prelude.Integer (i.e. java.lang.BigInteger) values are not handled here, since they do not
//have a literal unboxed representation in Java.
if (kl.getSymbol().equals(fieldName) && !kl.kernelTypeClass.equals(CAL_Integer.class)) {
return new ReturnStatement(LiteralWrapper.make(kl.getLiteralObject()));
}
}
}
}
// We want to invoke evaluate on the return value and then unbox.
JavaExpression newReturnValue = (JavaExpression)returnValue.accept(this, arg);
if (!(newReturnValue instanceof JavaExpression.MethodInvocation.Instance) ||
!((JavaExpression.MethodInvocation)newReturnValue).getMethodName().equals("evaluate")) {
// If all arguments and locals are not self referential types we can continue.
boolean problematicType = false;
for (int i = 0, n = getArity(); i < n; ++i) {
TypeExpr argType = getArgumentType(i);
if (argType != null) {
if (argType instanceof TypeVar) {
problematicType = true;
break;
} else if (argType instanceof TypeConsApp) {
if (SCJavaDefn.isSelfReferentialDataType(argType)) {
problematicType = true;
break;
}
}
}
}
if (!problematicType) {
// Check local variables.
Set<VarInfo> localVars = returnStatementToLocalVars.get(returnStatement);
if (localVars == null) {
problematicType = true;
} else {
for (final VarInfo vi : localVars) {
TypeExpr argType = vi.getVarType();
if (argType != null) {
if (argType instanceof TypeVar) {
problematicType = true;
break;
} else if (argType instanceof TypeConsApp) {
if (SCJavaDefn.isSelfReferentialDataType(argType)) {
problematicType = true;
break;
}
}
}
}
}
}
if (problematicType) {
throw new UnboxingTransformationError("Unable to transform function body.");
}
newReturnValue = createInvocation(newReturnValue, SCJavaDefn.EVALUATE, SCJavaDefn.EXECUTION_CONTEXT_VAR);
}
newReturnValue = SCJavaDefn.unboxValue(resultTypeName, newReturnValue);
return new ReturnStatement(newReturnValue);
}