diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-10-25 19:39:08 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-10-25 19:39:08 +0200 |
commit | 16661be2d99359c94569620e1daf2362d5356341 (patch) | |
tree | cca9a8062623818a3a995a7c86f228e023448f02 | |
parent | 7f7d1eed36f605cc7ca0e7af81ea9caf895e7b73 (diff) | |
download | lombok-16661be2d99359c94569620e1daf2362d5356341.tar.gz lombok-16661be2d99359c94569620e1daf2362d5356341.tar.bz2 lombok-16661be2d99359c94569620e1daf2362d5356341.zip |
Fixed issue 289: non-static inner classes whose outer class has generics can't be @EqualsAndHashCode marked.
4 files changed, 55 insertions, 10 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown index e48f5a06..111d00e9 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -3,6 +3,7 @@ Lombok Changelog ### v0.10.2 (edge) * BUGFIX: Turns out treating `@NotNull` as an annotation that indicates lombok should generate nullcheck guards causes all sorts of problems. This has been removed again, and documentation has been updated to reflect this. [Issue #287](http://code.google.com/p/projectlombok/issues/detail?id=287) +* BUGFIX: `@EqualsAndHashCode` or `@Data` did not work on non-static inner classes whose outer class has a type variable. It does now. [Issue #289](http://code.google.com/p/projectlombok/issues/detail?id=289) ### v0.10.1 (October 3rd, 2011) * BUGFIX: `@Delegate` in eclipse could cause memory leaks in 0.10.0. [Issue #264](http://code.google.com/p/projectlombok/issues/detail?id=264) diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index fef55904..328a8e6d 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1211,6 +1211,9 @@ public class EclipseHandlerUtil { throw Lombok.sneakyThrow(e); } + result.sourceStart = source.sourceStart; + result.sourceEnd = source.sourceEnd; + setGeneratedBy(result, source); return result; } diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index a4989b4c..d51aab4c 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -408,6 +408,27 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH return method; } + private TypeReference createTypeReference(EclipseNode type, long p) { + List<String> list = new ArrayList<String>(); + list.add(type.getName()); + EclipseNode tNode = type.up(); + while (tNode != null && tNode.getKind() == Kind.TYPE) { + list.add(tNode.getName()); + tNode = tNode.up(); + } + Collections.reverse(list); + + if (list.size() == 1) return new SingleTypeReference(list.get(0).toCharArray(), p); + long[] ps = new long[list.size()]; + char[][] tokens = new char[list.size()][]; + for (int i = 0; i < list.size(); i++) { + ps[i] = p; + tokens[i] = list.get(i).toCharArray(); + } + + return new QualifiedTypeReference(tokens, ps); + } + private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess, boolean needsCanEqual) { int pS = source.sourceStart; int pE = source.sourceEnd; long p = (long)pS << 32 | pE; @@ -452,12 +473,11 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH statements.add(ifOtherEqualsThis); } - /* if (!(o instanceof MyType) return false; */ { + /* if (!(o instanceof Outer.Inner.MyType) return false; */ { SingleNameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); - SingleTypeReference typeReference = new SingleTypeReference(typeDecl.name, p); - setGeneratedBy(typeReference, source); + TypeReference typeReference = createTypeReference(type, p); InstanceOfExpression instanceOf = new InstanceOfExpression(oRef, typeReference); instanceOf.sourceStart = pS; instanceOf.sourceEnd = pE; @@ -505,6 +525,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH } NameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); + other.annotations = createSuppressWarningsAll(source, null); other.initialization = makeCastExpression(oRef, targetType, source); statements.add(other); } @@ -653,7 +674,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH private MethodDeclaration createCanEqual(EclipseNode type, ASTNode source) { /* public boolean canEqual(final java.lang.Object other) { - * return other instanceof MyType; + * return other instanceof Outer.Inner.MyType; * } */ int pS = source.sourceStart; int pE = source.sourceEnd; @@ -683,7 +704,8 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH SingleNameReference otherRef = new SingleNameReference(otherName, p); setGeneratedBy(otherRef, source); - SingleTypeReference typeReference = new SingleTypeReference(((TypeDeclaration)type.get()).name, p); + TypeReference typeReference = createTypeReference(type, p); + setGeneratedBy(typeReference, source); InstanceOfExpression instanceOf = new InstanceOfExpression(otherRef, typeReference); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 50bcdd3e..2d4adbdb 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -320,6 +320,26 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas return maker.TypeCast(maker.TypeIdent(getCtcInt(TypeTags.class, "INT")), xorBits); } + private JCExpression createTypeReference(JavacNode type) { + java.util.List<String> list = new ArrayList<String>(); + list.add(type.getName()); + JavacNode tNode = type.up(); + while (tNode != null && tNode.getKind() == Kind.TYPE) { + list.add(tNode.getName()); + tNode = tNode.up(); + } + Collections.reverse(list); + + TreeMaker maker = type.getTreeMaker(); + JCExpression chain = maker.Ident(type.toName(list.get(0))); + + for (int i = 1; i < list.size(); i++) { + chain = maker.Select(chain, type.toName(list.get(i))); + } + + return chain; + } + private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); @@ -341,8 +361,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas maker.Ident(thisName)), returnBool(maker, true), null)); } - /* if (!(o instanceof MyType) return false; */ { - JCUnary notInstanceOf = maker.Unary(getCtcInt(JCTree.class, "NOT"), maker.TypeTest(maker.Ident(oName), maker.Ident(type.name))); + /* if (!(o instanceof Outer.Inner.MyType) return false; */ { + JCUnary notInstanceOf = maker.Unary(getCtcInt(JCTree.class, "NOT"), maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } @@ -444,11 +464,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas private JCMethodDecl createCanEqual(JavacNode typeNode, JCTree source) { /* public boolean canEqual(final java.lang.Object other) { - * return other instanceof MyType; + * return other instanceof Outer.Inner.MyType; * } */ TreeMaker maker = typeNode.getTreeMaker(); - JCClassDecl type = (JCClassDecl) typeNode.get(); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.<JCAnnotation>nil()); JCExpression returnType = maker.TypeIdent(getCtcInt(TypeTags.class, "BOOLEAN")); @@ -458,7 +477,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), otherName, objectType, null)); JCBlock body = maker.Block(0, List.<JCStatement>of( - maker.Return(maker.TypeTest(maker.Ident(otherName), maker.Ident(type.name))))); + maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode))))); return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); } |