aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.xml2
-rw-r--r--doc/changelog.markdown11
-rw-r--r--src/lombok/core/Version.java2
-rw-r--r--src/lombok/eclipse/handlers/HandleData.java4
-rw-r--r--src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java15
-rw-r--r--src/lombok/eclipse/handlers/HandleSetter.java5
-rw-r--r--src/lombok/installer/Installer.java2
-rw-r--r--src/lombok/javac/HandlerLibrary.java5
-rw-r--r--src/lombok/javac/Javac.java15
-rw-r--r--src/lombok/javac/apt/Processor.java18
-rw-r--r--src/lombok/javac/handlers/HandleData.java7
-rw-r--r--src/lombok/javac/handlers/HandleEqualsAndHashCode.java13
-rw-r--r--src/lombok/javac/handlers/HandleSetter.java3
-rw-r--r--website/features/SneakyThrows.html2
-rw-r--r--website/features/ToString.html2
15 files changed, 71 insertions, 35 deletions
diff --git a/build.xml b/build.xml
index 39bf3dcb..2c3bebb0 100644
--- a/build.xml
+++ b/build.xml
@@ -355,7 +355,7 @@ public class CompileChangelog {
</java>
</target>
- <target name="maven" depends="version, dist">
+ <target name="maven" depends="version, dist" description="Build a maven repository.">
<loadresource property="mvn.oldversions">
<url url="http://projectlombok.org/mavenrepo/org/projectlombok/lombok/maven-metadata.xml" />
<filterchain>
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index a7232fae..a74990e4 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,6 +1,17 @@
Lombok Changelog
----------------
+### v0.8.4
+
+* All generated methods now make their parameters (if they have any) final. This should help avoid problems with the 'make all parameters final' save action in eclipse. [Issue #40](http://code.google.com/p/projectlombok/issues/detail?id=40)
+
+### v0.8.3
+
+* @EqualsAndHashCode (and, indirectly, @Data) generate a warning when overriding a class other than java.lang.Object but not setting EqualsAndHashCode's callSuper to true. There are, however, legitimate reasons to do this, so this warning is now no longer generated if you explicitly set callSuper to false. The warning text now also refers to this action if not calling super is intentional.
+* If your fields have @NonNull or @NotNull annotations, then generated setters are generated with a null check, and the
+annotation is copied to the setter's parameter, and the getter's method.
+* An annoying bug that usually showed up if you had package-info.java files has been fixed. It would cause a `NullPointerException` at lombok.javac.apt.Processor.toUnit(Processor.java:143)
+
### v0.8.2
* @EqualsAndHashCode and @ToString created; these are subsets of what @Data does (namely: generate toString(), and generate equals() and hashCode() implementations). @Data will still generate these methods, but you can now generate them separately if you wish. As part of this split off, you can now specify for toString generation to include the field names in the produced toString method, and for all 3 methods: You can choose to involve the implementation of the superclass, and you can choose to exclude certain fields. [Issue #8](http://code.google.com/p/projectlombok/issues/detail?id=8)
diff --git a/src/lombok/core/Version.java b/src/lombok/core/Version.java
index fa7fe159..41e6adee 100644
--- a/src/lombok/core/Version.java
+++ b/src/lombok/core/Version.java
@@ -26,7 +26,7 @@ package lombok.core;
*/
public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
- private static final String VERSION = "0.8.3-HEAD";
+ private static final String VERSION = "0.8.3";
private Version() {
//Prevent instantiation
diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java
index 38e3135d..f072ea64 100644
--- a/src/lombok/eclipse/handlers/HandleData.java
+++ b/src/lombok/eclipse/handlers/HandleData.java
@@ -150,7 +150,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
assigns.add(new Assignment(thisX, new SingleNameReference(field.name, p), (int)p));
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
- Argument argument = new Argument(field.name, fieldPos, copyType(field.type), 0);
+ Argument argument = new Argument(field.name, fieldPos, copyType(field.type), Modifier.FINAL);
Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN);
Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN);
if (nonNulls.length != 0) nullChecks.add(generateNullCheck(field));
@@ -203,7 +203,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
Annotation[] copiedAnnotations = copyAnnotations(
findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN));
if (copiedAnnotations.length != 0) argument.annotations = copiedAnnotations;
- args.add(new Argument(field.name, fieldPos, copyType(field.type), 0));
+ args.add(new Argument(field.name, fieldPos, copyType(field.type), Modifier.FINAL));
}
statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]);
diff --git a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index f837d4a6..1adbe781 100644
--- a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -126,7 +126,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
try {
callSuper = ((Boolean)EqualsAndHashCode.class.getMethod("callSuper").getDefaultValue()).booleanValue();
} catch ( Exception ignore ) {}
- generateMethods(typeNode, errorNode, Collections.<String>emptyList(), callSuper, false);
+ generateMethods(typeNode, errorNode, Collections.<String>emptyList(), callSuper, true, false);
}
@Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation, Annotation ast, Node annotationNode) {
@@ -136,11 +136,12 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
checkForBogusExcludes(typeNode, annotation);
- return generateMethods(typeNode, annotationNode, excludes, ann.callSuper(), true);
+ return generateMethods(typeNode, annotationNode, excludes,
+ ann.callSuper(), annotation.getRawExpression("callSuper") == null, true);
}
public boolean generateMethods(Node typeNode, Node errorNode, List<String> excludes,
- boolean callSuper, boolean whineIfExists) {
+ boolean callSuper, boolean implicit, boolean whineIfExists) {
TypeDeclaration typeDecl = null;
if ( typeNode.get() instanceof TypeDeclaration ) typeDecl = (TypeDeclaration) typeNode.get();
@@ -165,8 +166,8 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return true;
}
- if ( !isDirectDescendantOfObject && !callSuper ) {
- errorNode.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object.");
+ if ( !isDirectDescendantOfObject && !callSuper && implicit ) {
+ errorNode.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.");
}
List<Node> nodesForEquality = new ArrayList<Node>();
@@ -243,7 +244,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
/* Without fields, PRIME isn't used, and that would trigger a 'local variable not used' warning. */
if ( !isEmpty || callSuper ) {
LocalDeclaration primeDecl = new LocalDeclaration(PRIME, 0 ,0);
- primeDecl.modifiers = Modifier.FINAL;
+ primeDecl.modifiers |= Modifier.FINAL;
primeDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
primeDecl.initialization = new IntLiteral("31".toCharArray(), 0, 0);
statements.add(primeDecl);
@@ -363,7 +364,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
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)
+ new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] { 0, 0, 0 }), Modifier.FINAL)
};
List<Statement> statements = new ArrayList<Statement>();
diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java
index 6214c86d..5ad9b193 100644
--- a/src/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/lombok/eclipse/handlers/HandleSetter.java
@@ -23,6 +23,9 @@ package lombok.eclipse.handlers;
import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.handlers.PKG.*;
+
+import java.lang.reflect.Modifier;
+
import lombok.AccessLevel;
import lombok.Setter;
import lombok.core.AnnotationValues;
@@ -125,7 +128,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> {
method.modifiers = modifier;
method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
method.annotations = null;
- Argument param = new Argument(field.name, pos, copyType(field.type), 0);
+ Argument param = new Argument(field.name, pos, copyType(field.type), Modifier.FINAL);
method.arguments = new Argument[] { param };
method.selector = name.toCharArray();
method.binding = null;
diff --git a/src/lombok/installer/Installer.java b/src/lombok/installer/Installer.java
index 6cf51355..89ebfc37 100644
--- a/src/lombok/installer/Installer.java
+++ b/src/lombok/installer/Installer.java
@@ -524,7 +524,7 @@ public class Installer {
if ( success.get() ) SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
- JOptionPane.showMessageDialog(appWindow, "<html>Lombok has been installed on the selected Eclipse installations.<br>Don't forget to add <code>lombok.jar</code> to your projects!</html>", "Install successful", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog(appWindow, "<html>Lombok has been installed on the selected Eclipse installations.<br>Don't forget to add <code>lombok.jar</code> to your projects, and restart your eclipse!</html>", "Install successful", JOptionPane.INFORMATION_MESSAGE);
appWindow.setVisible(false);
System.exit(0);
}
diff --git a/src/lombok/javac/HandlerLibrary.java b/src/lombok/javac/HandlerLibrary.java
index 7253cbaa..ff21bd3f 100644
--- a/src/lombok/javac/HandlerLibrary.java
+++ b/src/lombok/javac/HandlerLibrary.java
@@ -146,6 +146,7 @@ public class HandlerLibrary {
/** Generates an error in the Messager that was used to initialize this HandlerLibrary. */
public void javacError(String message, Throwable t) {
messager.printMessage(Diagnostic.Kind.ERROR, message + (t == null ? "" : (": " + t)));
+ if ( t != null ) t.printStackTrace();
}
/**
@@ -180,7 +181,9 @@ public class HandlerLibrary {
} catch ( AnnotationValueDecodeFail fail ) {
fail.owner.setError(fail.getMessage(), fail.idx);
} catch ( Throwable t ) {
- javacError(String.format("Lombok annotation handler %s failed", container.handler.getClass()), t);
+ String sourceName = "(unknown).java";
+ if ( unit != null && unit.sourcefile != null ) sourceName = unit.sourcefile.getName();
+ javacError(String.format("Lombok annotation handler %s failed on " + sourceName, container.handler.getClass()), t);
}
}
diff --git a/src/lombok/javac/Javac.java b/src/lombok/javac/Javac.java
index 2a3727b6..0987d31a 100644
--- a/src/lombok/javac/Javac.java
+++ b/src/lombok/javac/Javac.java
@@ -94,10 +94,19 @@ public class Javac {
final List<DiagnosticPosition> positions = new ArrayList<DiagnosticPosition>();
for ( JCExpression arg : arguments ) {
- JCAssign assign = (JCAssign) arg;
- String mName = assign.lhs.toString();
+ String mName;
+ JCExpression rhs;
+
+ if ( arg instanceof JCAssign ) {
+ JCAssign assign = (JCAssign) arg;
+ mName = assign.lhs.toString();
+ rhs = assign.rhs;
+ } else {
+ rhs = arg;
+ mName = "value";
+ }
+
if ( !mName.equals(name) ) continue;
- JCExpression rhs = assign.rhs;
if ( rhs instanceof JCNewArray ) {
List<JCExpression> elems = ((JCNewArray)rhs).elems;
for ( JCExpression inner : elems ) {
diff --git a/src/lombok/javac/apt/Processor.java b/src/lombok/javac/apt/Processor.java
index 22daeab1..44edd917 100644
--- a/src/lombok/javac/apt/Processor.java
+++ b/src/lombok/javac/apt/Processor.java
@@ -34,12 +34,14 @@ import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
import lombok.javac.HandlerLibrary;
import lombok.javac.JavacAST;
import lombok.javac.JavacASTAdapter;
import lombok.javac.JavacAST.Node;
+import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
@@ -69,8 +71,10 @@ public class Processor extends AbstractProcessor {
/** {@inheritDoc} */
@Override public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
- if ( !(processingEnv instanceof JavacProcessingEnvironment) ) this.processingEnv = null;
- else {
+ if ( !(processingEnv instanceof JavacProcessingEnvironment) ) {
+ processingEnv.getMessager().printMessage(Kind.WARNING, "You aren't using a compiler based around javac v1.6, so lombok will not work properly.");
+ this.processingEnv = null;
+ } else {
this.processingEnv = (JavacProcessingEnvironment) processingEnv;
handlers = HandlerLibrary.load(processingEnv.getMessager());
trees = Trees.instance(processingEnv);
@@ -83,7 +87,10 @@ public class Processor extends AbstractProcessor {
IdentityHashMap<JCCompilationUnit, Void> units = new IdentityHashMap<JCCompilationUnit, Void>();
- for ( Element element : roundEnv.getRootElements() ) units.put(toUnit(element), null);
+ for ( Element element : roundEnv.getRootElements() ) {
+ JCCompilationUnit unit = toUnit(element);
+ if ( unit != null ) units.put(unit, null);
+ }
List<JavacAST> asts = new ArrayList<JavacAST>();
@@ -140,6 +147,9 @@ public class Processor extends AbstractProcessor {
}
private JCCompilationUnit toUnit(Element element) {
- return (JCCompilationUnit) trees.getPath(element).getCompilationUnit();
+ TreePath path = trees == null ? null : trees.getPath(element);
+ if ( path == null ) return null;
+
+ return (JCCompilationUnit) path.getCompilationUnit();
}
}
diff --git a/src/lombok/javac/handlers/HandleData.java b/src/lombok/javac/handlers/HandleData.java
index 648ff91e..3b4f8951 100644
--- a/src/lombok/javac/handlers/HandleData.java
+++ b/src/lombok/javac/handlers/HandleData.java
@@ -113,11 +113,9 @@ public class HandleData implements JavacAnnotationHandler<Data> {
for ( Node fieldNode : fields ) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
-
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(fieldNode, NULLABLE_PATTERN);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls.appendList(nullables)), field.name, field.vartype, null);
-
+ JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), field.name, field.vartype, null);
params = params.append(param);
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name);
JCAssign assign = maker.Assign(thisX, maker.Ident(field.name));
@@ -170,10 +168,9 @@ public class HandleData implements JavacAnnotationHandler<Data> {
for ( JCExpression arg : typeApply.arguments ) tArgs = tArgs.append(arg);
pType = maker.TypeApply(typeApply.clazz, tArgs);
} else pType = field.vartype;
-
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(fieldNode, NULLABLE_PATTERN);
- JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls.appendList(nullables)), field.name, pType, null);
+ JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), field.name, pType, null);
params = params.append(param);
args = args.append(maker.Ident(field.name));
}
diff --git a/src/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/lombok/javac/handlers/HandleEqualsAndHashCode.java
index e3e7c1ac..8c3124c9 100644
--- a/src/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -86,7 +86,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
checkForBogusExcludes(typeNode, annotation);
- return generateMethods(typeNode, annotationNode, excludes, ann.callSuper(), true);
+ return generateMethods(typeNode, annotationNode, excludes,
+ ann.callSuper(), annotation.getRawExpression("callSuper") == null, true);
}
public void generateEqualsAndHashCodeForType(Node typeNode, Node errorNode) {
@@ -103,11 +104,11 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
try {
callSuper = ((Boolean)EqualsAndHashCode.class.getMethod("callSuper").getDefaultValue()).booleanValue();
} catch ( Exception ignore ) {}
- generateMethods(typeNode, errorNode, List.<String>nil(), callSuper, false);
+ generateMethods(typeNode, errorNode, List.<String>nil(), callSuper, true, false);
}
private boolean generateMethods(Node typeNode, Node errorNode, List<String> excludes,
- boolean callSuper, boolean whineIfExists) {
+ boolean callSuper, boolean implicit, boolean whineIfExists) {
boolean notAClass = true;
if ( typeNode.get() instanceof JCClassDecl ) {
long flags = ((JCClassDecl)typeNode.get()).mods.flags;
@@ -132,8 +133,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
return true;
}
- if ( !isDirectDescendantOfObject && !callSuper ) {
- errorNode.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object.");
+ if ( !isDirectDescendantOfObject && !callSuper && implicit ) {
+ errorNode.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.");
}
List<Node> nodesForEquality = List.nil();
@@ -312,7 +313,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
JCExpression returnType = maker.TypeIdent(TypeTags.BOOLEAN);
List<JCStatement> statements = List.nil();
- List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(0), oName, objectType, null));
+ List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null));
/* if ( o == this ) return true; */ {
statements = statements.append(
diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java
index c10e731c..412b1c43 100644
--- a/src/lombok/javac/handlers/HandleSetter.java
+++ b/src/lombok/javac/handlers/HandleSetter.java
@@ -131,8 +131,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
JCBlock methodBody = treeMaker.Block(0, statements);
Name methodName = field.toName(toSetterName(fieldDecl));
-
- JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, nonNulls.appendList(nullables)), fieldDecl.name, fieldDecl.vartype, null);
+ JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, nonNulls.appendList(nullables)), fieldDecl.name, fieldDecl.vartype, null);
JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType);
List<JCTypeParameter> methodGenericParams = List.nil();
diff --git a/website/features/SneakyThrows.html b/website/features/SneakyThrows.html
index 3f414bab..ec7d09c5 100644
--- a/website/features/SneakyThrows.html
+++ b/website/features/SneakyThrows.html
@@ -54,6 +54,8 @@
<div class="overview">
<h3>Small print</h3><div class="smallprint">
<p>
+ <code>@SneakyThrows</code> is an implementation of this feature request: <a href="http://bugs.sun.com/view_bug.do?bug_id=6534270">http://bugs.sun.com/view_bug.do?bug_id=6534270</a>.
+ </p><p>
Because <code>@SneakyThrows</code> is an implementation detail and not part of your method signature, it is an error if you try to
declare a checked exception as sneakily thrown when you don't call any methods that throw this exception. (Doing so is perfectly legal
for <code>throws</code> statements to accomodate subclasses). Similarly, <code>@SneakyThrows</code> does not inherit.
diff --git a/website/features/ToString.html b/website/features/ToString.html
index 96d69932..0ed142a1 100644
--- a/website/features/ToString.html
+++ b/website/features/ToString.html
@@ -5,7 +5,7 @@
<link rel="stylesheet" type="text/css" href="features.css" />
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
<meta name="description" content="Spice up your java" />
- <title>@Data</title>
+ <title>@ToString</title>
</head><body><div id="pepper">
<div class="minimumHeight"></div>
<div class="meat">