aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/eclipse/handlers/HandleData.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@tipit.to>2009-06-23 08:04:44 +0200
committerReinier Zwitserloot <reinier@tipit.to>2009-06-23 08:04:44 +0200
commit8bbdcec6fad6edf8f335f9e0c6899fddc56e07c1 (patch)
tree2f9c6d2c92f0723454eb8486e1a18dd178d0e885 /src/lombok/eclipse/handlers/HandleData.java
parent6c82a3c780539825157f721fcfe1a8894e73b161 (diff)
downloadlombok-8bbdcec6fad6edf8f335f9e0c6899fddc56e07c1.tar.gz
lombok-8bbdcec6fad6edf8f335f9e0c6899fddc56e07c1.tar.bz2
lombok-8bbdcec6fad6edf8f335f9e0c6899fddc56e07c1.zip
Figured out that our previous act of just assigning TypeReference objects directly to other nodes (e.g. from a FieldDeclaration's type to a method argument) is NOT a good idea, as this screws up when
the TypeReference object represents a generic type (like 'T') - each instance of a generic type has a different resolution, but 1 TypeReference object can only hold 1 resolution. Thus, a copyType() method has been written, and the Handle* classes have been updated to use it. Also, generateEquals() is half-finished in HandleData.
Diffstat (limited to 'src/lombok/eclipse/handlers/HandleData.java')
-rw-r--r--src/lombok/eclipse/handlers/HandleData.java139
1 files changed, 97 insertions, 42 deletions
diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java
index dd398d74..27757e7d 100644
--- a/src/lombok/eclipse/handlers/HandleData.java
+++ b/src/lombok/eclipse/handlers/HandleData.java
@@ -1,11 +1,11 @@
package lombok.eclipse.handlers;
+import static lombok.eclipse.Eclipse.*;
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,22 +15,28 @@ import lombok.core.AST.Kind;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseAST.Node;
+import lombok.eclipse.handlers.PKG.MethodExistsResult;
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;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
@@ -39,15 +45,12 @@ import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
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.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+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.TypeConstants;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseAnnotationHandler.class)
@@ -81,42 +84,22 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
new HandleSetter().generateSetterForField(child, annotationNode.get());
}
- switch ( methodExists("toString", typeNode) ) {
- case NOT_EXISTS:
+ if ( methodExists("toString", typeNode) == MethodExistsResult.NOT_EXISTS ) {
MethodDeclaration toString = createToString(typeNode, nodesForConstructorAndToString, ast);
injectMethod(typeNode, toString);
- //fallthrough
- case EXISTS_BY_LOMBOK:
-// TypeBinding javaLangString = null;
-// if ( typeDecl.scope != null ) javaLangString = typeDecl.scope.getJavaLangString();
-// fixMethodBinding(getExistingLombokMethod("toString", typeNode), javaLangString, Collections.<Node>emptyList());
}
- switch ( constructorExists(typeNode) ) {
- case NOT_EXISTS:
+ if ( constructorExists(typeNode) == MethodExistsResult.NOT_EXISTS ) {
ConstructorDeclaration constructor = createConstructor(
ann.staticConstructor().isEmpty(), typeNode, nodesForConstructorAndToString, ast);
injectMethod(typeNode, constructor);
- //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() ) {
- switch ( methodExists("of", typeNode) ) {
- case NOT_EXISTS:
+ if ( methodExists("of", typeNode) == MethodExistsResult.NOT_EXISTS ) {
MethodDeclaration staticConstructor = createStaticConstructor(
ann.staticConstructor(), typeNode, nodesForConstructorAndToString, ast);
injectMethod(typeNode, staticConstructor);
- //fallthrough
- case EXISTS_BY_LOMBOK:
-// fixMethodBinding(getExistingLombokMethod(ann.staticConstructor(), typeNode), typeDecl.binding, nodesForConstructorAndToString);
-// injectScopeIntoStaticConstructor((MethodDeclaration) getExistingLombokMethod(
-// ann.staticConstructor(), typeNode).get(),
-// nodesForConstructorAndToString, typeDecl);
}
}
@@ -190,7 +173,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
thisX.token = field.name;
assigns.add(new Assignment(thisX, new SingleNameReference(field.name, p), (int)p));
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
- args.add(new Argument(field.name, fieldPos, field.type, 0));
+ args.add(new Argument(field.name, fieldPos, copyType(field.type), 0));
}
constructor.statements = assigns.toArray(new Statement[assigns.size()]);
@@ -209,7 +192,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
constructor.annotations = null;
constructor.selector = name.toCharArray();
constructor.thrownExceptions = null;
- constructor.typeParameters = null;
+ constructor.typeParameters = copyTypeParams(((TypeDeclaration)type.get()).typeParameters);
constructor.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = pos.sourceStart;
constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = pos.sourceEnd;
@@ -217,13 +200,13 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
List<Argument> args = new ArrayList<Argument>();
List<Expression> assigns = new ArrayList<Expression>();
AllocationExpression statement = new AllocationExpression();
- statement.type = constructor.returnType;
+ statement.type = copyType(constructor.returnType);
for ( Node fieldNode : fields ) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
assigns.add(new SingleNameReference(field.name, fieldPos));
- args.add(new Argument(field.name, fieldPos, field.type, 0));
+ args.add(new Argument(field.name, fieldPos, copyType(field.type), 0));
}
statement.arguments = assigns.toArray(new Expression[assigns.size()]);
@@ -232,14 +215,86 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
return constructor;
}
- private MethodDeclaration createEquals(Collection<Node> fields) {
- //If using an of() constructor, make private.
- //method params
- //on loop: Assignment(FieldReference(ThisReference, "x"), SingleNameReference("x"))
- return null;
+ private MethodDeclaration createEquals(Node type, Collection<Node> fields, ASTNode pos) {
+ long p = (long)pos.sourceStart << 32 | pos.sourceEnd;
+ 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 = null;
+ method.selector = "equals".toCharArray();
+ method.thrownExceptions = null;
+ method.typeParameters = null;
+ method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
+ method.bodyStart = method.declarationSourceStart = method.sourceStart = pos.sourceStart;
+ method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = pos.sourceEnd;
+ method.arguments = new Argument[] {
+ new Argument(new char[] { 'o' }, 0,
+ new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { 0, 0, 0 }), 0)
+ };
+
+ List<Statement> statements = new ArrayList<Statement>();
+
+ /* if ( o == this ) return true; */ {
+ EqualExpression otherEqualsThis = new EqualExpression(
+ new SingleNameReference(new char[] { 'o' }, 0),
+ new ThisReference(0, 0), OperatorIds.EQUAL_EQUAL);
+
+ ReturnStatement returnTrue = new ReturnStatement(new TrueLiteral(0, 0), 0, 0);
+ IfStatement ifOtherEqualsThis = new IfStatement(otherEqualsThis, returnTrue, 0, 0);
+ 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);
+
+ ReturnStatement returnFalse = new ReturnStatement(new FalseLiteral(0, 0), 0, 0);
+ IfStatement ifOtherEqualsNull = new IfStatement(otherEqualsNull, returnFalse, 0, 0);
+ statements.add(ifOtherEqualsNull);
+ }
+
+ /* if ( o.getClass() != getClass() ) return false; */ {
+ MessageSend otherGetClass = new MessageSend();
+ otherGetClass.receiver = new SingleNameReference(new char[] { 'o' }, 0);
+ otherGetClass.selector = "getClass".toCharArray();
+ MessageSend thisGetClass = new MessageSend();
+ thisGetClass.receiver = new ThisReference(0, 0);
+ 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);
+ statements.add(ifClassesNotEqual);
+ }
+
+ char[] otherN = "other".toCharArray();
+
+ //TODO fix generics raw type warnings by inserting Wildcards.
+ /* MyType other = (MyType) o; */ {
+ if ( !fields.isEmpty() ) {
+ LocalDeclaration other = new LocalDeclaration(otherN, 0, 0);
+ other.initialization = new CastExpression(
+ new SingleNameReference(new char[] { 'o' }, 0),
+ new SingleNameReference(((TypeDeclaration)type.get()).name, 0));
+ }
+ }
+
+ for ( Node field : fields ) {
+ FieldDeclaration f = (FieldDeclaration) field.get();
+ //compare if primitive, write per-primitive special code, otherwise use == null ? other == null ? .equals(other).
+ //TODO I LEFT IT HERE
+ }
+
+ /* return true; */ {
+ statements.add(new ReturnStatement(new TrueLiteral(0, 0), 0, 0));
+ }
+ method.statements = statements.toArray(new Statement[statements.size()]);
+ return method;
}
- private MethodDeclaration createHashCode(Collection<Node> fields) {
+ private MethodDeclaration createHashCode(Node type, Collection<Node> fields, ASTNode pos) {
//booleans: conditionalexpression that bounces between 1231 and 1237.
//longs: (int) (lng ^ (lng >>> 32));
//doubles and floats: Double.doubleToLongBits, then as long.