diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-06-23 06:01:13 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-06-23 06:01:13 +0200 |
commit | 6c82a3c780539825157f721fcfe1a8894e73b161 (patch) | |
tree | f98ea3a9f826d40f0351f3752b1d96596d0fd10d /src/lombok/eclipse/handlers | |
parent | 4ee8e7a3d2513420e0f7affcca61d916c2a7374b (diff) | |
download | lombok-6c82a3c780539825157f721fcfe1a8894e73b161.tar.gz lombok-6c82a3c780539825157f721fcfe1a8894e73b161.tar.bz2 lombok-6c82a3c780539825157f721fcfe1a8894e73b161.zip |
This is a 3-day bughunt that ended up being something extremely simple:
** DO NOT REUSE TYPEREFERENCE OBJECTS **
because that makes the binding process go pearshaped - after hte first run, that TypeReference object's binding parameter is set, and as its set, the resolver won't bother re-resolving it.
However, each parse run starts with new scope objects, and any 2 bindings created by different scopes aren't equal to each other. urrrrrrgh!
Fortunately, a lot of code that 'fixed' methods by adding bindings and scope have all been removed, as the parser patch point is well before these bindings are created. Thus:
** NEVER CREATE YOUR OWN BINDINGS AND SCOPE OBJECTS **
because if it comes down to that, you're doing it entirely wrong. That's eclipse's job. We're patching where we are so you don't have to do this.
Diffstat (limited to 'src/lombok/eclipse/handlers')
-rw-r--r-- | src/lombok/eclipse/handlers/HandleData.java | 62 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleGetter.java | 21 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleSetter.java | 22 |
3 files changed, 30 insertions, 75 deletions
diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java index b4bba7d7..dd398d74 100644 --- a/src/lombok/eclipse/handlers/HandleData.java +++ b/src/lombok/eclipse/handlers/HandleData.java @@ -2,8 +2,10 @@ package lombok.eclipse.handlers; import static lombok.eclipse.handlers.PKG.*; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import lombok.AccessLevel; @@ -15,6 +17,8 @@ import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseAST.Node; import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; @@ -28,6 +32,7 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; @@ -35,10 +40,14 @@ import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.ast.TypeParameter; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; +import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; import org.mangosdk.spi.ProviderFor; @ProviderFor(EclipseAnnotationHandler.class) @@ -76,9 +85,11 @@ public class HandleData implements EclipseAnnotationHandler<Data> { case NOT_EXISTS: MethodDeclaration toString = createToString(typeNode, nodesForConstructorAndToString, ast); injectMethod(typeNode, toString); - break; + //fallthrough case EXISTS_BY_LOMBOK: - injectScopeIntoToString((MethodDeclaration) getExistingLombokMethod("toString", typeNode).get(), typeDecl); +// TypeBinding javaLangString = null; +// if ( typeDecl.scope != null ) javaLangString = typeDecl.scope.getJavaLangString(); +// fixMethodBinding(getExistingLombokMethod("toString", typeNode), javaLangString, Collections.<Node>emptyList()); } switch ( constructorExists(typeNode) ) { @@ -86,7 +97,12 @@ public class HandleData implements EclipseAnnotationHandler<Data> { ConstructorDeclaration constructor = createConstructor( ann.staticConstructor().isEmpty(), typeNode, nodesForConstructorAndToString, ast); injectMethod(typeNode, constructor); - break; + //fallthrough + case EXISTS_BY_LOMBOK: +// constructor = createConstructor( +// ann.staticConstructor().isEmpty(), typeNode, nodesForConstructorAndToString, ast); +// injectScopeIntoConstructor(constructor, nodesForConstructorAndToString, typeDecl); +// fixMethodBinding(getExistingLombokConstructor(typeNode), typeDecl.binding, nodesForConstructorAndToString); } if ( !ann.staticConstructor().isEmpty() ) { @@ -95,11 +111,12 @@ public class HandleData implements EclipseAnnotationHandler<Data> { MethodDeclaration staticConstructor = createStaticConstructor( ann.staticConstructor(), typeNode, nodesForConstructorAndToString, ast); injectMethod(typeNode, staticConstructor); - break; + //fallthrough case EXISTS_BY_LOMBOK: - injectScopeIntoStaticConstructor((MethodDeclaration) getExistingLombokMethod( - ann.staticConstructor(), typeNode).get(), - nodesForConstructorAndToString, typeDecl); +// fixMethodBinding(getExistingLombokMethod(ann.staticConstructor(), typeNode), typeDecl.binding, nodesForConstructorAndToString); +// injectScopeIntoStaticConstructor((MethodDeclaration) getExistingLombokMethod( +// ann.staticConstructor(), typeNode).get(), +// nodesForConstructorAndToString, typeDecl); } } @@ -107,15 +124,6 @@ public class HandleData implements EclipseAnnotationHandler<Data> { return false; } - private void injectScopeIntoToString(MethodDeclaration method, TypeDeclaration typeDecl) { - if ( typeDecl.scope != null ) { - method.scope = new MethodScope(typeDecl.scope, method, false); - method.returnType.resolvedType = typeDecl.scope.getJavaLangString(); - method.binding = new MethodBinding(method.modifiers, - method.selector, typeDecl.scope.getJavaLangString(), null, null, typeDecl.binding); - } - } - private MethodDeclaration createToString(Node type, Collection<Node> fields, ASTNode pos) { char[] rawTypeName = ((TypeDeclaration)type.get()).name; String typeName = rawTypeName == null ? "" : new String(rawTypeName); @@ -142,14 +150,12 @@ public class HandleData implements EclipseAnnotationHandler<Data> { MethodDeclaration method = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult); method.modifiers = PKG.toModifier(AccessLevel.PUBLIC); - method.returnType = Eclipse.TYPEREF_JAVA_LANG_STRING; + method.returnType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {0, 0, 0}); method.annotations = null; method.arguments = null; method.selector = "toString".toCharArray(); - method.binding = null; method.thrownExceptions = null; method.typeParameters = null; - injectScopeIntoToString(method, (TypeDeclaration) type.get()); method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; method.bodyStart = method.declarationSourceStart = method.sourceStart = pos.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = pos.sourceEnd; @@ -192,32 +198,18 @@ public class HandleData implements EclipseAnnotationHandler<Data> { return constructor; } - private void injectScopeIntoStaticConstructor(MethodDeclaration constructor, Collection<Node> fields, TypeDeclaration typeDecl) { - if ( typeDecl.scope != null ) { - constructor.scope = new MethodScope(typeDecl.scope, constructor, false); -// constructor.binding = new MethodBinding(constructor.modifiers, -// constructor.selector, null, null, null, typeDecl.binding); - constructor.returnType.resolvedType = typeDecl.binding; -// TypeBinding[] bindings = new TypeBinding[fields.size()]; -// int idx = 0; -// for ( Node field : fields ) bindings[idx++] = ((FieldDeclaration)field.get()).type.resolvedType; -// constructor.binding.parameters = bindings; - } - } - private MethodDeclaration createStaticConstructor(String name, Node type, Collection<Node> fields, ASTNode pos) { long p = (long)pos.sourceStart << 32 | pos.sourceEnd; MethodDeclaration constructor = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); - constructor.modifiers = PKG.toModifier(AccessLevel.PUBLIC); + constructor.modifiers = PKG.toModifier(AccessLevel.PUBLIC) | Modifier.STATIC; constructor.returnType = new SingleTypeReference(((TypeDeclaration)type.get()).name, p); constructor.annotations = null; constructor.selector = name.toCharArray(); constructor.thrownExceptions = null; constructor.typeParameters = null; - injectScopeIntoStaticConstructor(constructor, fields, (TypeDeclaration) type.get()); constructor.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = pos.sourceStart; constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = pos.sourceEnd; @@ -236,7 +228,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> { statement.arguments = assigns.toArray(new Expression[assigns.size()]); constructor.arguments = args.toArray(new Argument[args.size()]); - constructor.statements = new Statement[] { statement }; + constructor.statements = new Statement[] { new ReturnStatement(statement, (int)(p >> 32), (int)p) }; return constructor; } diff --git a/src/lombok/eclipse/handlers/HandleGetter.java b/src/lombok/eclipse/handlers/HandleGetter.java index 5b3fbf90..d0ec673d 100644 --- a/src/lombok/eclipse/handlers/HandleGetter.java +++ b/src/lombok/eclipse/handlers/HandleGetter.java @@ -22,8 +22,6 @@ import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; -import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.mangosdk.spi.ProviderFor; @ProviderFor(EclipseAnnotationHandler.class) @@ -69,9 +67,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { switch ( methodExists(getterName, fieldNode) ) { case EXISTS_BY_LOMBOK: - Node methodNode = getExistingLombokMethod(getterName, fieldNode); - injectScopeIntoGetter(modifier, field, (MethodDeclaration)methodNode.get(), (TypeDeclaration) methodNode.up().get()); - return false; + return true; case EXISTS_BY_USER: if ( whineIfExists ) errorNode.addWarning( String.format("Not generating %s(): A method with that name already exists", getterName)); @@ -86,19 +82,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { injectMethod(fieldNode.up(), method); - return false; - } - - private void injectScopeIntoGetter(int modifier, FieldDeclaration field, MethodDeclaration method, TypeDeclaration parent) { - if ( parent.scope != null ) { - if ( method.binding != null ) { - method.binding.returnType = field.type.resolvedType; - } else { - method.scope = new MethodScope(parent.scope, method, false); - method.returnType.resolvedType = field.type.resolvedType; - method.binding = new MethodBinding(modifier, method.selector, method.returnType.resolvedType, null, null, parent.binding); - } - } + return true; } private MethodDeclaration generateGetter(TypeDeclaration parent, FieldDeclaration field, String name, @@ -112,7 +96,6 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { method.binding = null; method.thrownExceptions = null; method.typeParameters = null; - injectScopeIntoGetter(modifier, field, method, parent); method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; Expression fieldExpression = new SingleNameReference(field.name, (field.declarationSourceStart << 32) | field.declarationSourceEnd); Statement returnStatement = new ReturnStatement(fieldExpression, field.sourceStart, field.sourceEnd); diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java index c5f87a93..d33594b1 100644 --- a/src/lombok/eclipse/handlers/HandleSetter.java +++ b/src/lombok/eclipse/handlers/HandleSetter.java @@ -23,10 +23,7 @@ import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; -import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; -import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.mangosdk.spi.ProviderFor; @@ -72,9 +69,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { switch ( methodExists(setterName, fieldNode) ) { case EXISTS_BY_LOMBOK: - Node methodNode = getExistingLombokMethod(setterName, fieldNode); - injectScopeIntoSetter(modifier, field, (MethodDeclaration)methodNode.get(), (TypeDeclaration) methodNode.up().get()); - return false; + return true; case EXISTS_BY_USER: if ( whineIfExists ) errorNode.addWarning( String.format("Not generating %s(%s %s): A method with that name already exists", @@ -93,20 +88,6 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { return false; } - private void injectScopeIntoSetter(int modifier, FieldDeclaration field, MethodDeclaration method, TypeDeclaration parent) { - if ( parent.scope != null ) { - TypeBinding[] params = new TypeBinding[] { field.type.resolvedType }; - - if ( method.binding == null ) { - method.scope = new MethodScope(parent.scope, method, false); - method.binding = new MethodBinding(modifier, method.selector, BaseTypeBinding.VOID, params, null, parent.binding); - } - method.binding.parameters = params; - method.binding.returnType = BaseTypeBinding.VOID; - method.returnType.resolvedType = BaseTypeBinding.VOID; - } - } - private MethodDeclaration generateSetter(TypeDeclaration parent, FieldDeclaration field, String name, int modifier, ASTNode ast) { long pos = (((long)ast.sourceStart) << 32) | ast.sourceEnd; @@ -122,7 +103,6 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { method.typeParameters = null; method.scope = parent.scope == null ? null : new MethodScope(parent.scope, method, false); method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; - injectScopeIntoSetter(modifier, field, method, parent); FieldReference thisX = new FieldReference(("this." + new String(field.name)).toCharArray(), pos); thisX.receiver = new ThisReference(ast.sourceStart, ast.sourceEnd); thisX.token = field.name; |