public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode anno = (AnnotationNode) nodes[0]; if (!checkNotInterface(cNode, MY_TYPE_NAME)) return; cNode.addInterface(CLONEABLE_TYPE); boolean includeFields = memberHasValue(anno, "includeFields", true); AutoCloneStyle style = getStyle(anno, "style"); List<String> excludes = getMemberStringList(anno, "excludes"); if (!checkPropertyList(cNode, excludes, "excludes", anno, MY_TYPE_NAME, includeFields)) return; List<FieldNode> list = getInstancePropertyFields(cNode); if (includeFields) { switch (style) { case COPY_CONSTRUCTOR: createCloneCopyConstructor(cNode, list, excludes); break; case SERIALIZATION: createCloneSerialization(cNode); break; case SIMPLE: createSimpleClone(cNode, list, excludes); break; default: createClone(cNode, list, excludes); break;
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode anno = (AnnotationNode) nodes[0]; if (!MY_TYPE.equals(anno.getClassNode())) return; if (parent instanceof ClassNode) { ClassNode cNode = (ClassNode) parent; checkNotInterface(cNode, MY_TYPE_NAME); cNode.addInterface(CLONEABLE_TYPE); boolean includeFields = memberHasValue(anno, "includeFields", true); AutoCloneStyle style = getStyle(anno, "style"); List<String> excludes = tokenize((String) getMemberValue(anno, "excludes")); List<FieldNode> list = getInstancePropertyFields(cNode); if (includeFields) { list.addAll(getInstanceNonPropertyFields(cNode)); } if (style == null) style = AutoCloneStyle.CLONE; switch (style) { case COPY_CONSTRUCTOR: createCloneCopyConstructor(cNode, list, excludes); break; case SERIALIZATION: createCloneSerialization(cNode, list, excludes); break; case CLONE: createClone(cNode, list, excludes); break; } } }
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 createSimpleClone(ClassNode cNode, List<FieldNode> fieldNodes, List<String> excludes) { if (cNode.getDeclaredConstructors().isEmpty()) { // add no-arg constructor addGeneratedConstructor(cNode, ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, block(EmptyStatement.INSTANCE)); } addSimpleCloneHelperMethod(cNode, fieldNodes, excludes); final Expression result = varX("_result", cNode); ClassNode[] exceptions = {make(CloneNotSupportedException.class)}; addGeneratedMethod(cNode, "clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, block( declS(result, ctorX(cNode)), stmt(callThisX("cloneOrCopyMembers", args(result))), returnS(result))); }
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); }
Expression to = propX(varX("this"), 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)) { initBody.addStatement(assignCloned); } else if (!possiblyCloneable(fieldType)) { initBody.addStatement(assignDirect); } else {