private void createSoftGetter(FieldNode fieldNode, Expression initExpr, ClassNode type) {
final BlockStatement body = new BlockStatement();
final Expression fieldExpr = new VariableExpression(fieldNode);
final Expression resExpr = new VariableExpression("res", type);
final MethodCallExpression callExpression = new MethodCallExpression(fieldExpr, "get", new ArgumentListExpression());
callExpression.setSafe(true);
body.addStatement(declStatement(resExpr, callExpression));
final BlockStatement elseBlock = new BlockStatement();
elseBlock.addStatement(assignStatement(resExpr, initExpr));
elseBlock.addStatement(assignStatement(fieldExpr, new ConstructorCallExpression(SOFT_REF, resExpr)));
elseBlock.addStatement(new ExpressionStatement(resExpr));
final Statement mainIf = new IfStatement(notNullExpr(resExpr), new ExpressionStatement(resExpr), elseBlock);
if (notVolatile(fieldNode)) {
body.addStatement(mainIf);
} else {
body.addStatement(new IfStatement(
notNullExpr(resExpr),
new ExpressionStatement(resExpr),
new SynchronizedStatement(syncTarget(fieldNode), mainIf)
));
}
addMethod(fieldNode, body, type);
}