From 25e33d02e3b91b04947257ffa3c6233f1c81d3ce Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 1 Sep 2009 19:05:21 +0200 Subject: Added position information _everywhere_ in EqualsAndHashCode and ToString generating. This really does seem to fix the David Lynch bug (#41). --- .../eclipse/handlers/HandleEqualsAndHashCode.java | 183 +++++++++++---------- src/lombok/eclipse/handlers/HandleToString.java | 8 +- src/lombok/eclipse/handlers/PKG.java | 8 + 3 files changed, 103 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index d4435fce..5896dc2d 100644 --- a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -50,7 +50,6 @@ import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.IntLiteral; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; @@ -217,14 +216,15 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler fields, boolean callSuper, ASTNode pos) { + int pS = pos.sourceStart, pE = pos.sourceEnd; + long p = (long)pS << 32 | pE; + MethodDeclaration method = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); method.modifiers = PKG.toModifier(AccessLevel.PUBLIC); method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0); - method.annotations = new Annotation[] { - new MarkerAnnotation(new QualifiedTypeReference(TypeConstants.JAVA_LANG_OVERRIDE, new long[] {0, 0, 0}), 0) - }; + method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, p)}; method.selector = "hashCode".toCharArray(); method.thrownExceptions = null; method.typeParameters = null; @@ -243,24 +243,24 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler 0 && token != null ) { /* Arrays.deepHashCode(array) //just hashCode for simple arrays */ MessageSend arraysHashCodeCall = new MessageSend(); - arraysHashCodeCall.receiver = generateQualifiedNameRef(TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); + arraysHashCodeCall.receiver = generateQualifiedNameRef(p, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); if ( f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token)) ) { arraysHashCodeCall.selector = "deepHashCode".toCharArray(); } else { arraysHashCodeCall.selector = "hashCode".toCharArray(); } - arraysHashCodeCall.arguments = new Expression[] { generateFieldReference(f.name) }; + arraysHashCodeCall.arguments = new Expression[] { generateFieldReference(f.name, p) }; intoResult.add(arraysHashCodeCall); } } @@ -333,29 +333,30 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler fields, boolean callSuper, ASTNode pos) { + int pS = pos.sourceStart; int pE = pos.sourceEnd; + long p = (long)pS << 32 | pE; + MethodDeclaration method = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); method.modifiers = PKG.toModifier(AccessLevel.PUBLIC); method.returnType = TypeReference.baseTypeReference(TypeIds.T_boolean, 0); - method.annotations = new Annotation[] { - new MarkerAnnotation(new QualifiedTypeReference(TypeConstants.JAVA_LANG_OVERRIDE, new long[] { 0, 0, 0}), 0) - }; + method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, p)}; method.selector = "equals".toCharArray(); method.thrownExceptions = null; method.typeParameters = null; @@ -364,41 +365,41 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler statements = new ArrayList(); /* if ( o == this ) return true; */ { EqualExpression otherEqualsThis = new EqualExpression( - new SingleNameReference(new char[] { 'o' }, 0), - new ThisReference(0, 0), OperatorIds.EQUAL_EQUAL); + new SingleNameReference(new char[] { 'o' }, p), + new ThisReference(pS, pE), OperatorIds.EQUAL_EQUAL); - ReturnStatement returnTrue = new ReturnStatement(new TrueLiteral(0, 0), 0, 0); - IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, 0, 0); + ReturnStatement returnTrue = new ReturnStatement(new TrueLiteral(pS, pE), pS, pE); + IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, pS, pE); statements.add(ifOtherEqualsThis); } /* if ( o == null ) return false; */ { EqualExpression otherEqualsNull = new EqualExpression( - new SingleNameReference(new char[] { 'o' }, 0), - new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL); + new SingleNameReference(new char[] { 'o' }, p), + new NullLiteral(pS, pE), OperatorIds.EQUAL_EQUAL); - ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(0, 0), 0, 0); - IfStatement ifOtherEqualsNull = new IfStatement(otherEqualsNull, returnFalse, 0, 0); + ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(pS, pE), pS, pE); + IfStatement ifOtherEqualsNull = new IfStatement(otherEqualsNull, returnFalse, pS, pE); statements.add(ifOtherEqualsNull); } /* if ( o.getClass() != getClass() ) return false; */ { MessageSend otherGetClass = new MessageSend(); - otherGetClass.receiver = new SingleNameReference(new char[] { 'o' }, 0); + otherGetClass.receiver = new SingleNameReference(new char[] { 'o' }, p); otherGetClass.selector = "getClass".toCharArray(); MessageSend thisGetClass = new MessageSend(); - thisGetClass.receiver = new ThisReference(0, 0); + thisGetClass.receiver = new ThisReference(pS, pE); thisGetClass.selector = "getClass".toCharArray(); EqualExpression classesNotEqual = new EqualExpression(otherGetClass, thisGetClass, OperatorIds.NOT_EQUAL); - ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(0, 0), 0, 0); - IfStatement ifClassesNotEqual = new IfStatement(classesNotEqual, returnFalse, 0, 0); + ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(pS, pE), pS, pE); + IfStatement ifClassesNotEqual = new IfStatement(classesNotEqual, returnFalse, pS, pE); statements.add(ifClassesNotEqual); } @@ -407,32 +408,32 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler other = (MyType) o; */ { if ( !fields.isEmpty() ) { - LocalDeclaration other = new LocalDeclaration(otherN, 0, 0); + LocalDeclaration other = new LocalDeclaration(otherN, pS, pE); char[] typeName = typeDecl.name; Expression targetType; if ( typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0 ) { - targetType = new SingleNameReference(((TypeDeclaration)type.get()).name, 0); - other.type = new SingleTypeReference(typeName, 0); + targetType = new SingleNameReference(((TypeDeclaration)type.get()).name, p); + other.type = new SingleTypeReference(typeName, p); } else { TypeReference[] typeArgs = new TypeReference[typeDecl.typeParameters.length]; for ( int i = 0 ; i < typeArgs.length ; i++ ) typeArgs[i] = new Wildcard(Wildcard.UNBOUND); - targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, 0); - other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs), 0, 0); + targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, p); + other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs), 0, p); } other.initialization = new CastExpression( - new SingleNameReference(new char[] { 'o' }, 0), + new SingleNameReference(new char[] { 'o' }, p), targetType); statements.add(other); } @@ -443,90 +444,92 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler 0 && token != null ) { MessageSend arraysEqualCall = new MessageSend(); - arraysEqualCall.receiver = generateQualifiedNameRef(TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); + arraysEqualCall.receiver = generateQualifiedNameRef(p, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray()); if ( f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token)) ) { arraysEqualCall.selector = "deepEquals".toCharArray(); } else { arraysEqualCall.selector = "equals".toCharArray(); } arraysEqualCall.arguments = new Expression[] { - new SingleNameReference(f.name, 0), - generateQualifiedNameRef(otherN, f.name) }; + new SingleNameReference(f.name, p), + generateQualifiedNameRef(p, otherN, f.name) }; UnaryExpression arraysNotEqual = new UnaryExpression(arraysEqualCall, OperatorIds.NOT); - ReturnStatement returnStatement = new ReturnStatement(new FalseLiteral(0, 0), 0, 0); - statements.add(new IfStatement(arraysNotEqual, returnStatement, 0, 0)); + ReturnStatement returnStatement = new ReturnStatement(new FalseLiteral(pS, pE), pS, pE); + statements.add(new IfStatement(arraysNotEqual, returnStatement, pS, pE)); } } /* return true; */ { - statements.add(new ReturnStatement(new TrueLiteral(0, 0), 0, 0)); + statements.add(new ReturnStatement(new TrueLiteral(pS, pE), pS, pE)); } method.statements = statements.toArray(new Statement[statements.size()]); return method; } - private IfStatement generateCompareFloatOrDouble(char[] otherN, char[] floatOrDouble, char[] fieldName) { + private IfStatement generateCompareFloatOrDouble(char[] otherN, char[] floatOrDouble, char[] fieldName, long p) { + int pS = (int)(p >> 32), pE = (int)p; /* if ( Float.compare(fieldName, other.fieldName) != 0 ) return false */ MessageSend floatCompare = new MessageSend(); - floatCompare.receiver = generateQualifiedNameRef(TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); + floatCompare.receiver = generateQualifiedNameRef(p, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble); floatCompare.selector = "compare".toCharArray(); floatCompare.arguments = new Expression[] { - new SingleNameReference(fieldName, 0), - generateQualifiedNameRef(otherN, fieldName) + new SingleNameReference(fieldName, p), + generateQualifiedNameRef(p, otherN, fieldName) }; - EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, new IntLiteral(new char[] {'0'}, 0, 0), OperatorIds.NOT_EQUAL); - ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(0, 0), 0, 0); - return new IfStatement(ifFloatCompareIsNot0, returnFalse, 0, 0); + EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, new IntLiteral(new char[] {'0'}, pS, pE), OperatorIds.NOT_EQUAL); + ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(pS, pE), pS, pE); + return new IfStatement(ifFloatCompareIsNot0, returnFalse, pS, pE); } /** Give 2 clones! */ - private Expression longToIntForHashCode(Reference ref1, Reference ref2) { + private Expression longToIntForHashCode(Reference ref1, Reference ref2, long p) { + int pS = (int)(p >> 32), pE = (int)p; /* (int)(ref >>> 32 ^ ref) */ BinaryExpression higherBits = new BinaryExpression( - ref1, new IntLiteral("32".toCharArray(), 0, 0), + ref1, new IntLiteral("32".toCharArray(), pS, pE), OperatorIds.UNSIGNED_RIGHT_SHIFT); BinaryExpression xorParts = new BinaryExpression(ref2, higherBits, OperatorIds.XOR); return new CastExpression(xorParts, TypeReference.baseTypeReference(TypeIds.T_int, 0)); } - private Reference generateFieldReference(char[] fieldName) { - FieldReference thisX = new FieldReference(("this." + new String(fieldName)).toCharArray(), 0); - thisX.receiver = new ThisReference(0, 0); + private Reference generateFieldReference(char[] fieldName, long p) { + FieldReference thisX = new FieldReference(("this." + new String(fieldName)).toCharArray(), p); + thisX.receiver = new ThisReference((int)(p >> 32), (int)p); thisX.token = fieldName; return thisX; } - private NameReference generateQualifiedNameRef(char[]... varNames) { + private NameReference generateQualifiedNameRef(long p, char[]... varNames) { if ( varNames.length > 1 ) - return new QualifiedNameReference(varNames, new long[varNames.length], 0, 0); - else return new SingleNameReference(varNames[0], 0); + return new QualifiedNameReference(varNames, new long[varNames.length], (int)(p >> 32), (int)p); + else return new SingleNameReference(varNames[0], p); } } diff --git a/src/lombok/eclipse/handlers/HandleToString.java b/src/lombok/eclipse/handlers/HandleToString.java index 86f4496d..f2c4e9cf 100644 --- a/src/lombok/eclipse/handlers/HandleToString.java +++ b/src/lombok/eclipse/handlers/HandleToString.java @@ -45,7 +45,6 @@ import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; @@ -226,12 +225,9 @@ public class HandleToString implements EclipseAnnotationHandler { ReturnStatement returnStatement = new ReturnStatement(current, (int)(p >> 32), (int)p); MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult); - method.modifiers = PKG.toModifier(AccessLevel.PUBLIC); + method.modifiers = toModifier(AccessLevel.PUBLIC); method.returnType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {0, 0, 0}); - MarkerAnnotation overrideAnnotation = new MarkerAnnotation(new QualifiedTypeReference(TypeConstants.JAVA_LANG_OVERRIDE, new long[] {p, p, p}), (int)(p >> 32)); - overrideAnnotation.declarationSourceEnd = overrideAnnotation.sourceEnd = overrideAnnotation.statementEnd = (int)p; - overrideAnnotation.bits |= ASTNode.HasBeenGenerated; - method.annotations = new Annotation[] {overrideAnnotation}; + method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, p)}; method.arguments = null; method.selector = "toString".toCharArray(); method.thrownExceptions = null; diff --git a/src/lombok/eclipse/handlers/PKG.java b/src/lombok/eclipse/handlers/PKG.java index 8e58c83f..98c60524 100644 --- a/src/lombok/eclipse/handlers/PKG.java +++ b/src/lombok/eclipse/handlers/PKG.java @@ -44,6 +44,7 @@ import org.eclipse.jdt.internal.compiler.ast.EqualExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.IfStatement; +import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; @@ -265,4 +266,11 @@ class PKG { return new IfStatement(new EqualExpression(new SingleNameReference(variable.name, 0), new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL), throwStatement, 0, 0); } + + static MarkerAnnotation makeMarkerAnnotation(char[][] name, long pos) { + MarkerAnnotation ann = new MarkerAnnotation(new QualifiedTypeReference(name, new long[] {pos, pos, pos}), (int)(pos >> 32)); + ann.declarationSourceEnd = ann.sourceEnd = ann.statementEnd = (int)pos; + ann.bits |= ASTNode.HasBeenGenerated; + return ann; + } } -- cgit