From c06660bd186c7ae8215a822c4eceab097407eeda Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 21 Jul 2010 10:19:13 +0200 Subject: Refactor: for using this.getX() instead of this.x in generated toString(), equals(), and hashCode() methods. Field accessors are now always generated by a utility method. The one thing that remains is adding a getter searcher to this utility method. --- .../javac/handlers/HandleEqualsAndHashCode.java | 62 +++++++++++----------- src/core/lombok/javac/handlers/HandleToString.java | 22 ++++---- .../lombok/javac/handlers/JavacHandlerUtil.java | 22 +++++++- 3 files changed, 61 insertions(+), 45 deletions(-) (limited to 'src/core/lombok/javac/handlers') diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 4ee24391..66d2308a 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -1,5 +1,5 @@ /* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -90,7 +90,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler excludes, List includes, - Boolean callSuper, boolean whineIfExists) { + Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { long flags = ((JCClassDecl)typeNode.get()).mods.flags; @@ -169,7 +169,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler fields, boolean callSuper) { + private JCMethodDecl createHashCode(JavacNode typeNode, List fields, boolean callSuper, boolean useFieldsDirectly) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.nil()); @@ -232,25 +232,23 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandlernil(), chainDots(maker, typeNode, "java", "lang", "Float", "floatToIntBits"), - List.of(thisDotField))); + List.of(fieldAccessor))); break; case DOUBLE: /* longToIntForHashCode(Double.doubleToLongBits(this.fieldName)) */ @@ -258,7 +256,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandlernil(), chainDots(maker, typeNode, "java", "lang", "Double", "doubleToLongBits"), - List.of(thisDotField)); + List.of(fieldAccessor)); statements = statements.append( maker.VarDef(maker.Modifiers(Flags.FINAL), tempVar, maker.TypeIdent(TypeTags.LONG), init)); intoResult = intoResult.append(longToIntForHashCode(maker, maker.Ident(tempVar), maker.Ident(tempVar))); @@ -269,7 +267,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandlernil(), hcMethod, List.of(thisDotField))); + maker.Apply(List.nil(), hcMethod, List.of(fieldAccessor))); } else /* objects */ { /* this.fieldName == null ? 0 : this.fieldName.hashCode() */ - JCExpression hcCall = maker.Apply(List.nil(), maker.Select(thisDotField, typeNode.toName("hashCode")), + JCExpression hcCall = maker.Apply(List.nil(), maker.Select(fieldAccessor, typeNode.toName("hashCode")), List.nil()); - JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisDotField, maker.Literal(TypeTags.BOT, null)); + JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, fieldAccessor, maker.Literal(TypeTags.BOT, null)); intoResult = intoResult.append( maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall)); } @@ -316,7 +314,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler fields, boolean callSuper) { + private JCMethodDecl createEquals(JavacNode typeNode, List fields, boolean callSuper, boolean useFieldsDirectly) { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); @@ -382,24 +380,23 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler args = List.of(thisDotField, otherDotField); + List args = List.of(thisFieldAccessor, otherFieldAccessor); statements = statements.append(maker.If(maker.Unary(JCTree.NOT, maker.Apply(List.nil(), eqMethod, args)), returnBool(maker, false), null)); } else /* objects */ { /* if (this.fieldName == null ? other.fieldName != null : !this.fieldName.equals(other.fieldName)) return false; */ - JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisDotField, maker.Literal(TypeTags.BOT, null)); - JCExpression otherNotEqualsNull = maker.Binary(JCTree.NE, otherDotField, maker.Literal(TypeTags.BOT, null)); - JCExpression thisEqualsThat = maker.Apply( - List.nil(), maker.Select(thisDotField, typeNode.toName("equals")), List.of(otherDotField)); + JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisFieldAccessor, maker.Literal(TypeTags.BOT, null)); + JCExpression otherNotEqualsNull = maker.Binary(JCTree.NE, thisFieldAccessor, maker.Literal(TypeTags.BOT, null)); + JCExpression thisEqualsThat = maker.Apply(List.nil(), + maker.Select(createFieldAccessor(maker, fieldNode, useFieldsDirectly), typeNode.toName("equals")), + List.of(createFieldAccessor(maker, fieldNode, useFieldsDirectly, maker.Ident(otherName)))); JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(JCTree.NOT, thisEqualsThat)); statements = statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null)); } diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index cdba7558..7b1b3b81 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -1,5 +1,5 @@ /* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,6 @@ import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; -import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCModifiers; @@ -89,7 +88,7 @@ public class HandleToString implements JavacAnnotationHandler { annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored."); } - return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true); + return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, ann.doNotUseGetters()); } public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { @@ -106,11 +105,11 @@ public class HandleToString implements JavacAnnotationHandler { try { includeFieldNames = ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue(); } catch (Exception ignore) {} - generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false); + generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, false); } private boolean generateToString(JavacNode typeNode, JavacNode errorNode, List excludes, List includes, - boolean includeFieldNames, Boolean callSuper, boolean whineIfExists) { + boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { long flags = ((JCClassDecl)typeNode.get()).mods.flags; @@ -151,7 +150,7 @@ public class HandleToString implements JavacAnnotationHandler { switch (methodExists("toString", typeNode)) { case NOT_EXISTS: - JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper); + JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, useFieldsDirectly); injectMethod(typeNode, method); return true; case EXISTS_BY_LOMBOK: @@ -166,7 +165,7 @@ public class HandleToString implements JavacAnnotationHandler { } - private JCMethodDecl createToString(JavacNode typeNode, List fields, boolean includeFieldNames, boolean callSuper) { + private JCMethodDecl createToString(JavacNode typeNode, List fields, boolean includeFieldNames, boolean callSuper, boolean useFieldsDirectly) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.nil()); @@ -203,16 +202,16 @@ public class HandleToString implements JavacAnnotationHandler { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); JCExpression expr; - JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name); + JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly); - if (field.vartype instanceof JCArrayTypeTree) { + if (getFieldType(fieldNode, useFieldsDirectly) instanceof JCArrayTypeTree) { boolean multiDim = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCArrayTypeTree; boolean primitiveArray = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCPrimitiveTypeTree; boolean useDeepTS = multiDim || !primitiveArray; JCExpression hcMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepTS ? "deepToString" : "toString"); - expr = maker.Apply(List.nil(), hcMethod, List.of(thisX)); - } else expr = thisX; + expr = maker.Apply(List.nil(), hcMethod, List.of(fieldAccessor)); + } else expr = fieldAccessor; if (first) { current = maker.Binary(JCTree.PLUS, current, expr); @@ -238,5 +237,4 @@ public class HandleToString implements JavacAnnotationHandler { return maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.nil(), List.nil(), List.nil(), body, null); } - } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 9ac84bd1..84388c30 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1,5 +1,5 @@ /* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -269,6 +269,26 @@ public class JavacHandlerUtil { } } + /** + * Creates an expression that reads the field. Will either be {@code this.field} or {@code this.getField()} depending on whether or not there's a getter. + */ + static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly) { + return createFieldAccessor(maker, field, useFieldsDirectly, maker.Ident(field.toName("this"))); + } + + static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly, JCExpression receiver) { + return maker.Select(receiver, ((JCVariableDecl)field.get()).name); + } + + /** + * Returns the type of the field, unless a getter exists for this field, in which case the return type of the getter is returned. + * + * @see #createFieldAccessor(TreeMaker, JavacNode) + */ + static JCExpression getFieldType(JavacNode field, boolean useFieldsDirectly) { + return ((JCVariableDecl)field.get()).vartype; + } + /** * Adds the given new field declaration to the provided type AST Node. * -- cgit