private static boolean possiblyCloneable(ClassNode type) { return !isPrimitiveType(type) && ((isCloneableType(type) || (type.getModifiers() & ACC_FINAL) == 0)); }
private static void createClone(ClassNode cNode, List<FieldNode> fieldNodes, List<String> excludes) { final BlockStatement body = new BlockStatement(); final Expression result = varX("_result", cNode); body.addStatement(declS(result, castX(cNode, callSuperX("clone")))); for (FieldNode fieldNode : fieldNodes) { if (excludes != null && excludes.contains(fieldNode.getName())) continue; ClassNode fieldType = fieldNode.getType(); Expression fieldExpr = varX(fieldNode); Expression to = propX(result, fieldNode.getName()); Statement doClone = assignS(to, castX(fieldType, callCloneDirectX(fieldExpr))); Statement doCloneDynamic = assignS(to, castX(fieldType, callCloneDynamicX(fieldExpr))); if (isCloneableType(fieldType)) { body.addStatement(doClone); } else if (possiblyCloneable(fieldType)) { body.addStatement(ifS(isInstanceOfX(fieldExpr, CLONEABLE_TYPE), doCloneDynamic)); } } body.addStatement(returnS(result)); ClassNode[] exceptions = {make(CloneNotSupportedException.class)}; addGeneratedMethod(cNode, "clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, body); }
private static void addSimpleCloneHelperMethod(ClassNode cNode, List<FieldNode> fieldNodes, List<String> excludes) { Parameter methodParam = new Parameter(GenericsUtils.nonGeneric(cNode), "other"); final Expression other = varX(methodParam); boolean hasParent = cNode.getSuperClass() != ClassHelper.OBJECT_TYPE; BlockStatement methodBody = new BlockStatement(); if (hasParent) { methodBody.addStatement(stmt(callSuperX("cloneOrCopyMembers", args(other)))); } for (FieldNode fieldNode : fieldNodes) { String name = fieldNode.getName(); if (excludes != null && excludes.contains(name)) continue; ClassNode fieldType = fieldNode.getType(); Expression direct = propX(varX("this"), name); Expression to = propX(other, name); Statement assignDirect = assignS(to, direct); Statement assignCloned = assignS(to, castX(fieldType, callCloneDirectX(direct))); Statement assignClonedDynamic = assignS(to, castX(fieldType, callCloneDynamicX(direct))); if (isCloneableType(fieldType)) { methodBody.addStatement(assignCloned); } else if (!possiblyCloneable(fieldType)) { methodBody.addStatement(assignDirect); } else { methodBody.addStatement(ifElseS(isInstanceOfX(direct, CLONEABLE_TYPE), assignClonedDynamic, assignDirect)); } } ClassNode[] exceptions = {make(CloneNotSupportedException.class)}; addGeneratedMethod(cNode, "cloneOrCopyMembers", ACC_PROTECTED, ClassHelper.VOID_TYPE, params(methodParam), exceptions, methodBody); }
Statement assignCloned = assignS(to, castX(fieldType, callCloneDirectX(direct))); Statement assignClonedDynamic = assignS(to, castX(fieldType, callCloneDynamicX(direct))); if (isCloneableType(fieldType)) { initBody.addStatement(assignCloned); } else if (!possiblyCloneable(fieldType)) {