aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/eclipse/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'src/lombok/eclipse/handlers')
-rw-r--r--src/lombok/eclipse/handlers/HandleData.java49
-rw-r--r--src/lombok/eclipse/handlers/HandleGetter.java50
-rw-r--r--src/lombok/eclipse/handlers/HandleSetter.java43
3 files changed, 126 insertions, 16 deletions
diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java
new file mode 100644
index 00000000..64540e95
--- /dev/null
+++ b/src/lombok/eclipse/handlers/HandleData.java
@@ -0,0 +1,49 @@
+package lombok.eclipse.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.mangosdk.spi.ProviderFor;
+
+import lombok.Data;
+import lombok.core.AnnotationValues;
+import lombok.core.AST.Kind;
+import lombok.eclipse.EclipseAnnotationHandler;
+import lombok.eclipse.EclipseAST.Node;
+
+@ProviderFor(EclipseAnnotationHandler.class)
+public class HandleData implements EclipseAnnotationHandler<Data> {
+ @Override public boolean handle(AnnotationValues<Data> annotation, Annotation ast, Node annotationNode) {
+ Node typeNode = annotationNode.up();
+
+ TypeDeclaration typeDecl = null;
+ if ( typeNode.get() instanceof TypeDeclaration ) typeDecl = (TypeDeclaration) typeNode.get();
+ int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
+ boolean notAClass = (modifiers &
+ (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
+
+ if ( typeDecl == null || notAClass ) {
+ annotationNode.addError("@Data is only supported on a class.");
+ return false;
+ }
+
+ List<Node> nodesForEquality = new ArrayList<Node>();
+ for ( Node child : typeNode.down() ) {
+ if ( child.getKind() != Kind.FIELD ) continue;
+ FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
+ //Skip static fields.
+ if ( (fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0 ) continue;
+ if ( (fieldDecl.modifiers & ClassFileConstants.AccTransient) == 0 ) nodesForEquality.add(child);
+ new HandleGetter().generateGetterForField(child, annotationNode.get());
+ if ( (fieldDecl.modifiers & ClassFileConstants.AccFinal) == 0 )
+ new HandleSetter().generateSetterForField(child, annotationNode.get());
+ }
+
+ //TODO generate constructor, hashCode, equals, toString.
+ return true;
+ }
+}
diff --git a/src/lombok/eclipse/handlers/HandleGetter.java b/src/lombok/eclipse/handlers/HandleGetter.java
index ca561a48..798705da 100644
--- a/src/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/lombok/eclipse/handlers/HandleGetter.java
@@ -2,9 +2,12 @@ package lombok.eclipse.handlers;
import static lombok.eclipse.handlers.PKG.*;
+import lombok.AccessLevel;
import lombok.Getter;
import lombok.core.AnnotationValues;
import lombok.core.TransformationsUtil;
+import lombok.core.AST.Kind;
+import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseAST.Node;
@@ -19,30 +22,59 @@ import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
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.MethodScope;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleGetter implements EclipseAnnotationHandler<Getter> {
+ public void generateGetterForField(Node fieldNode, ASTNode pos) {
+ AccessLevel level = Getter.DEFAULT_ACCESS_LEVEL;
+ Node errorNode = fieldNode;
+
+ for ( Node child : fieldNode.down() ) {
+ if ( child.getKind() == Kind.ANNOTATION ) {
+ if ( Eclipse.annotationTypeMatches(Getter.class, child) ) {
+ level = Eclipse.createAnnotation(Getter.class, child).getInstance().value();
+ errorNode = child;
+ pos = child.get();
+ break;
+ }
+ }
+ }
+
+ createGetterForField(level, fieldNode, errorNode, pos);
+ }
+
@Override public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, Node annotationNode) {
- if ( !(annotationNode.up().get() instanceof FieldDeclaration) ) return false;
- FieldDeclaration field = (FieldDeclaration) annotationNode.up().get();
+ Node fieldNode = annotationNode.up();
+ AccessLevel level = annotation.getInstance().value();
+ return createGetterForField(level, fieldNode, annotationNode, annotationNode.get());
+ }
+
+ private boolean createGetterForField(AccessLevel level, Node fieldNode, Node errorNode, ASTNode pos) {
+ if ( fieldNode.getKind() != Kind.FIELD ) {
+ errorNode.addError("@Getter is only supported on a field.");
+ return false;
+ }
+
+ FieldDeclaration field = (FieldDeclaration) fieldNode.get();
TypeReference fieldType = field.type;
String getterName = TransformationsUtil.toGetterName(
new String(field.name), nameEquals(fieldType.getTypeName(), "boolean"));
- TypeDeclaration parent = (TypeDeclaration) annotationNode.up().up().get();
+ TypeDeclaration parent = (TypeDeclaration) fieldNode.up().get();
if ( parent.methods != null ) for ( AbstractMethodDeclaration method : parent.methods ) {
if ( method.selector != null && new String(method.selector).equals(getterName) ) {
- annotationNode.addWarning(String.format(
+ errorNode.addWarning(String.format(
"Not generating %s(): A method with that name already exists", getterName));
return false;
}
}
- int modifier = toModifier(annotation.getInstance().value());
+ int modifier = toModifier(level) | (field.modifiers & ClassFileConstants.AccStatic);
- MethodDeclaration method = generateGetter(parent, field, getterName, modifier, ast);
+ MethodDeclaration method = generateGetter(parent, field, getterName, modifier, pos);
if ( parent.methods == null ) {
parent.methods = new AbstractMethodDeclaration[1];
@@ -58,7 +90,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> {
}
private MethodDeclaration generateGetter(TypeDeclaration parent, FieldDeclaration field, String name,
- int modifier, Annotation ast) {
+ int modifier, ASTNode pos) {
MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
method.modifiers = modifier;
method.returnType = field.type;
@@ -72,8 +104,8 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> {
method.bits |= ASTNode.Bit24;
Expression fieldExpression = new SingleNameReference(field.name, (field.declarationSourceStart << 32) | field.declarationSourceEnd);
Statement returnStatement = new ReturnStatement(fieldExpression, field.sourceStart, field.sourceEnd);
- method.bodyStart = method.declarationSourceStart = method.sourceStart = ast.sourceStart;
- method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = ast.sourceEnd;
+ method.bodyStart = method.declarationSourceStart = method.sourceStart = pos.sourceStart;
+ method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = pos.sourceEnd;
method.statements = new Statement[] { returnStatement };
return method;
}
diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java
index 692061e4..d0d0d902 100644
--- a/src/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/lombok/eclipse/handlers/HandleSetter.java
@@ -15,36 +15,65 @@ import org.eclipse.jdt.internal.compiler.ast.Statement;
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.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.mangosdk.spi.ProviderFor;
+import lombok.AccessLevel;
import lombok.Setter;
import lombok.core.AnnotationValues;
import lombok.core.TransformationsUtil;
+import lombok.core.AST.Kind;
+import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseAST.Node;
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleSetter implements EclipseAnnotationHandler<Setter> {
+ public void generateSetterForField(Node fieldNode, ASTNode pos) {
+ AccessLevel level = Setter.DEFAULT_ACCESS_LEVEL;
+ Node errorNode = fieldNode;
+
+ for ( Node child : fieldNode.down() ) {
+ if ( child.getKind() == Kind.ANNOTATION ) {
+ if ( Eclipse.annotationTypeMatches(Setter.class, child) ) {
+ level = Eclipse.createAnnotation(Setter.class, child).getInstance().value();
+ errorNode = child;
+ pos = child.get();
+ break;
+ }
+ }
+ }
+
+ createSetterForField(level, fieldNode, errorNode, pos);
+ }
+
@Override public boolean handle(AnnotationValues<Setter> annotation, Annotation ast, Node annotationNode) {
- if ( !(annotationNode.up().get() instanceof FieldDeclaration) ) return false;
- FieldDeclaration field = (FieldDeclaration) annotationNode.up().get();
+ Node fieldNode = annotationNode.up();
+ if ( fieldNode.getKind() != Kind.FIELD ) return false;
+ AccessLevel level = annotation.getInstance().value();
+ return createSetterForField(level, fieldNode, annotationNode, annotationNode.get());
+ }
+
+ private boolean createSetterForField(AccessLevel level, Node fieldNode, Node errorNode, ASTNode pos) {
+ if ( fieldNode.getKind() != Kind.FIELD ) return false;
+ FieldDeclaration field = (FieldDeclaration) fieldNode.get();
String setterName = TransformationsUtil.toSetterName(new String(field.name));
- TypeDeclaration parent = (TypeDeclaration) annotationNode.up().up().get();
+ TypeDeclaration parent = (TypeDeclaration) fieldNode.up().get();
if ( parent.methods != null ) for ( AbstractMethodDeclaration method : parent.methods ) {
if ( method.selector != null && new String(method.selector).equals(setterName) ) {
- annotationNode.addWarning(String.format(
+ errorNode.addWarning(String.format(
"Not generating %s(%s %s): A method with that name already exists",
setterName, field.type, new String(field.name)));
return false;
}
}
- int modifier = toModifier(annotation.getInstance().value());
+ int modifier = toModifier(level) | (field.modifiers & ClassFileConstants.AccStatic);
- MethodDeclaration method = generateSetter(parent, field, setterName, modifier, ast);
+ MethodDeclaration method = generateSetter(parent, field, setterName, modifier, pos);
if ( parent.methods == null ) {
parent.methods = new AbstractMethodDeclaration[1];
@@ -60,7 +89,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> {
}
private MethodDeclaration generateSetter(TypeDeclaration parent, FieldDeclaration field, String name,
- int modifier, Annotation ast) {
+ int modifier, ASTNode ast) {
long pos = (((long)ast.sourceStart) << 32) | ast.sourceEnd;
MethodDeclaration method = new MethodDeclaration(parent.compilationResult);
method.modifiers = modifier;