.comment("boolean wasNull = false;")
.putVariable("wasNull", false)
.getVariable("output")
.append(body);
Type projectionType = expressionTypes.get(projection);
Block notNullBlock = new Block(context);
if (projectionType.getJavaType() == boolean.class) {
notNullBlock
.comment("output.append(<booleanStackValue>);")
.invokeInterface(BlockBuilder.class, "appendBoolean", BlockBuilder.class, boolean.class)
.pop();
}
else if (projectionType.getJavaType() == long.class) {
notNullBlock
.comment("output.append(<longStackValue>);")
.invokeInterface(BlockBuilder.class, "appendLong", BlockBuilder.class, long.class)
.pop();
}
else if (projectionType.getJavaType() == double.class) {
notNullBlock
.comment("output.append(<doubleStackValue>);")
.invokeInterface(BlockBuilder.class, "appendDouble", BlockBuilder.class, double.class)
.pop();
}
else if (projectionType.getJavaType() == Slice.class) {
notNullBlock
.comment("output.append(<sliceStackValue>);")
.invokeInterface(BlockBuilder.class, "appendSlice", BlockBuilder.class, Slice.class)
.pop();
}
else {
throw new UnsupportedOperationException("Type " + projectionType + " can not be output yet");
}
Block nullBlock = new Block(context)
.comment("output.appendNull();")
.pop(projectionType.getJavaType())
.invokeInterface(BlockBuilder.class, "appendNull", BlockBuilder.class)
.pop();
projectionMethod.getBody()
.comment("if the result was null, appendNull; otherwise append the value")
.append(new IfStatement(context, new Block(context).getVariable("wasNull"), nullBlock, notNullBlock))
.ret();
return projectionType.getJavaType();
}