use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class AutoCloneASTTransformation method createCloneCopyConstructor.
private void createCloneCopyConstructor(ClassNode cNode, List<FieldNode> list, List<String> excludes) {
if (cNode.getDeclaredConstructors().size() == 0) {
// add no-arg constructor
BlockStatement noArgBody = new BlockStatement();
noArgBody.addStatement(EmptyStatement.INSTANCE);
cNode.addConstructor(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, noArgBody);
}
boolean hasThisCons = false;
for (ConstructorNode consNode : cNode.getDeclaredConstructors()) {
Parameter[] parameters = consNode.getParameters();
if (parameters.length == 1 && parameters[0].getType().equals(cNode)) {
hasThisCons = true;
}
}
if (!hasThisCons) {
BlockStatement initBody = new BlockStatement();
Parameter initParam = param(GenericsUtils.nonGeneric(cNode), "other");
final Expression other = varX(initParam);
boolean hasParent = cNode.getSuperClass() != ClassHelper.OBJECT_TYPE;
if (hasParent) {
initBody.addStatement(stmt(ctorX(ClassNode.SUPER, other)));
}
for (FieldNode fieldNode : list) {
String name = fieldNode.getName();
if (excludes.contains(name))
continue;
ClassNode fieldType = fieldNode.getType();
Expression direct = propX(other, name);
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 {
initBody.addStatement(ifElseS(isInstanceOfX(direct, CLONEABLE_TYPE), assignClonedDynamic, assignDirect));
}
}
cNode.addConstructor(ACC_PROTECTED, params(initParam), ClassNode.EMPTY_ARRAY, initBody);
}
ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, block(stmt(ctorX(cNode, args(varX("this"))))));
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class AutoCloneASTTransformation method createClone.
private 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.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) };
cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, body);
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class EqualsAndHashCodeASTTransformation method createHashCode.
public static void createHashCode(ClassNode cNode, boolean cacheResult, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes) {
// make a public method if none exists otherwise try a private method with leading underscore
boolean hasExistingHashCode = hasDeclaredMethod(cNode, "hashCode", 0);
if (hasExistingHashCode && hasDeclaredMethod(cNode, "_hashCode", 0))
return;
final BlockStatement body = new BlockStatement();
// TODO use pList and fList
if (cacheResult) {
final FieldNode hashField = cNode.addField("$hash$code", ACC_PRIVATE | ACC_SYNTHETIC, ClassHelper.int_TYPE, null);
final Expression hash = varX(hashField);
body.addStatement(ifS(isZeroX(hash), calculateHashStatements(cNode, hash, includeFields, callSuper, excludes, includes)));
body.addStatement(returnS(hash));
} else {
body.addStatement(calculateHashStatements(cNode, null, includeFields, callSuper, excludes, includes));
}
cNode.addMethod(new MethodNode(hasExistingHashCode ? "_hashCode" : "hashCode", hasExistingHashCode ? ACC_PRIVATE : ACC_PUBLIC, ClassHelper.int_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body));
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class EqualsAndHashCodeASTTransformation method calculateHashStatements.
private static Statement calculateHashStatements(ClassNode cNode, Expression hash, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes) {
final List<PropertyNode> pList = getInstanceProperties(cNode);
final List<FieldNode> fList = new ArrayList<FieldNode>();
if (includeFields) {
fList.addAll(getInstanceNonPropertyFields(cNode));
}
final BlockStatement body = new BlockStatement();
// def _result = HashCodeHelper.initHash()
final Expression result = varX("_result");
body.addStatement(declS(result, callX(HASHUTIL_TYPE, "initHash")));
for (PropertyNode pNode : pList) {
if (shouldSkip(pNode.getName(), excludes, includes))
continue;
// _result = HashCodeHelper.updateHash(_result, getProperty()) // plus self-reference checking
Expression getter = getterX(cNode, pNode);
final Expression current = callX(HASHUTIL_TYPE, "updateHash", args(result, getter));
body.addStatement(ifS(notX(sameX(getter, varX("this"))), assignS(result, current)));
}
for (FieldNode fNode : fList) {
if (shouldSkip(fNode.getName(), excludes, includes))
continue;
// _result = HashCodeHelper.updateHash(_result, field) // plus self-reference checking
final Expression fieldExpr = varX(fNode);
final Expression current = callX(HASHUTIL_TYPE, "updateHash", args(result, fieldExpr));
body.addStatement(ifS(notX(sameX(fieldExpr, varX("this"))), assignS(result, current)));
}
if (callSuper) {
// _result = HashCodeHelper.updateHash(_result, super.hashCode())
final Expression current = callX(HASHUTIL_TYPE, "updateHash", args(result, callSuperX("hashCode")));
body.addStatement(assignS(result, current));
}
// $hash$code = _result
if (hash != null) {
body.addStatement(assignS(hash, result));
} else {
body.addStatement(returnS(result));
}
return body;
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class ExternalizeMethodsASTTransformation method visit.
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;
if (!checkNotInterface(cNode, MY_TYPE_NAME))
return;
cNode.addInterface(EXTERNALIZABLE_TYPE);
boolean includeFields = memberHasValue(anno, "includeFields", true);
List<String> excludes = getMemberList(anno, "excludes");
List<FieldNode> list = getInstancePropertyFields(cNode);
if (includeFields) {
list.addAll(getInstanceNonPropertyFields(cNode));
}
createWriteExternal(cNode, excludes, list);
createReadExternal(cNode, excludes, list);
}
}
Aggregations