diff options
author | Roel Spilker <r.spilker@gmail.com> | 2013-11-19 21:02:59 +0100 |
---|---|---|
committer | Roel Spilker <r.spilker@gmail.com> | 2013-11-19 21:02:59 +0100 |
commit | 78b2d6919e35887940f9f11b6ae1731245739b83 (patch) | |
tree | 0dc305883c19a862a38669374c5614e26480d4b8 /src/core/lombok/eclipse | |
parent | 5deb185591904d275cb06eea85c0d739587fc738 (diff) | |
parent | 83b7e77b0cce6cd5993b17f36164271accdd281c (diff) | |
download | lombok-78b2d6919e35887940f9f11b6ae1731245739b83.tar.gz lombok-78b2d6919e35887940f9f11b6ae1731245739b83.tar.bz2 lombok-78b2d6919e35887940f9f11b6ae1731245739b83.zip |
Merge branch 'master' of github.com:rzwitserloot/lombok
Conflicts:
src/delombok/lombok/delombok/DelombokApp.java
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r-- | src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 67 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleBuilder.java | 2 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleConstructor.java | 11 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java | 2 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleNonNull.java (renamed from src/core/lombok/eclipse/handlers/NonNullHandler.java) | 60 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleSneakyThrows.java | 2 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleSynchronized.java | 2 |
7 files changed, 106 insertions, 40 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 9bd634f7..5e322c90 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1125,6 +1125,37 @@ public class EclipseHandlerUtil { return true; } + public static char[] removePrefixFromField(EclipseNode field) { + String[] prefixes = null; + for (EclipseNode node : field.down()) { + if (annotationTypeMatches(Accessors.class, node)) { + prefixes = createAnnotation(Accessors.class, node).getInstance().prefix(); + break; + } + } + + if (prefixes == null) { + EclipseNode current = field.up(); + outer: + while (current != null) { + for (EclipseNode node : current.down()) { + if (annotationTypeMatches(Accessors.class, node)) { + prefixes = createAnnotation(Accessors.class, node).getInstance().prefix(); + break outer; + } + } + current = current.up(); + } + } + + if (prefixes != null && prefixes.length > 0) { + CharSequence newName = TransformationsUtil.removePrefix(field.getName(), prefixes); + if (newName != null) return newName.toString().toCharArray(); + } + + return ((FieldDeclaration) field.get()).name; + } + public static AnnotationValues<Accessors> getAccessorsForField(EclipseNode field) { for (EclipseNode node : field.down()) { if (annotationTypeMatches(Accessors.class, node)) { @@ -1562,9 +1593,9 @@ public class EclipseHandlerUtil { intLiteralFactoryMethod = intLiteralFactoryMethod_; } - private static boolean isAllUnderscores(char[] in) { + private static boolean isAllValidOnXCharacters(char[] in) { if (in == null || in.length == 0) return false; - for (char c : in) if (c != '_') return false; + for (char c : in) if (c != '_' && c != 'X' && c != 'x' && c != '$') return false; return true; } @@ -1597,31 +1628,31 @@ public class EclipseHandlerUtil { if (i > 0) System.arraycopy(pairs, 0, newPairs, 0, i); if (i < pairs.length - 1) System.arraycopy(pairs, i + 1, newPairs, i, pairs.length - i - 1); normalAnnotation.memberValuePairs = newPairs; - // We have now removed the annotation parameter and stored '@_({... annotations ...})', + // We have now removed the annotation parameter and stored '@__({... annotations ...})', // which we must now unbox. if (!(value instanceof Annotation)) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } - Annotation atUnderscore = (Annotation) value; - if (!(atUnderscore.type instanceof SingleTypeReference) || - !isAllUnderscores(((SingleTypeReference) atUnderscore.type).token)) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + Annotation atDummyIdentifier = (Annotation) value; + if (!(atDummyIdentifier.type instanceof SingleTypeReference) || + !isAllValidOnXCharacters(((SingleTypeReference) atDummyIdentifier.type).token)) { + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } - if (atUnderscore instanceof MarkerAnnotation) { - // It's @getter(onMethod=@_). This is weird, but fine. + if (atDummyIdentifier instanceof MarkerAnnotation) { + // It's @Getter(onMethod=@__). This is weird, but fine. return Collections.emptyList(); } Expression content = null; - if (atUnderscore instanceof NormalAnnotation) { - MemberValuePair[] mvps = ((NormalAnnotation) atUnderscore).memberValuePairs; + if (atDummyIdentifier instanceof NormalAnnotation) { + MemberValuePair[] mvps = ((NormalAnnotation) atDummyIdentifier).memberValuePairs; if (mvps == null || mvps.length == 0) { - // It's @getter(onMethod=@_()). This is weird, but fine. + // It's @Getter(onMethod=@__()). This is weird, but fine. return Collections.emptyList(); } if (mvps.length == 1 && Arrays.equals("value".toCharArray(), mvps[0].name)) { @@ -1629,12 +1660,12 @@ public class EclipseHandlerUtil { } } - if (atUnderscore instanceof SingleMemberAnnotation) { - content = ((SingleMemberAnnotation) atUnderscore).memberValue; + if (atDummyIdentifier instanceof SingleMemberAnnotation) { + content = ((SingleMemberAnnotation) atDummyIdentifier).memberValue; } if (content == null) { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } @@ -1646,13 +1677,13 @@ public class EclipseHandlerUtil { if (expressions != null) for (Expression ex : expressions) { if (ex instanceof Annotation) result.add((Annotation) ex); else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } } return result; } else { - errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); return Collections.emptyList(); } } diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 70110a9c..981d77dc 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -113,7 +113,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { // non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves. // Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that. if (fd.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue; - namesOfParameters.add(fd.name); + namesOfParameters.add(removePrefixFromField(fieldNode)); typesOfParameters.add(fd.type); fields.add(fieldNode); } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 1ae680d9..22285b2d 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -230,7 +230,8 @@ public class HandleConstructor { int ctr = 0; for (EclipseNode field : fields) { - fieldNames.expressions[ctr] = new StringLiteral(field.getName().toCharArray(), pS, pE, 0); + char[] fieldName = removePrefixFromField(field); + fieldNames.expressions[ctr] = new StringLiteral(fieldName, pS, pE, 0); setGeneratedBy(fieldNames.expressions[ctr], source); ctr++; } @@ -273,15 +274,17 @@ public class HandleConstructor { for (EclipseNode fieldNode : fields) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - FieldReference thisX = new FieldReference(field.name, p); + char[] rawName = field.name; + char[] fieldName = removePrefixFromField(fieldNode); + FieldReference thisX = new FieldReference(rawName, p); thisX.receiver = new ThisReference((int)(p >> 32), (int)p); - SingleNameReference assignmentNameRef = new SingleNameReference(field.name, p); + SingleNameReference assignmentNameRef = new SingleNameReference(fieldName, p); Assignment assignment = new Assignment(thisX, assignmentNameRef, (int)p); assignment.sourceStart = (int)(p >> 32); assignment.sourceEnd = assignment.statementEnd = (int)(p >> 32); assigns.add(assignment); long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; - Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); + Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL); Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); if (nonNulls.length != 0) { diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 6990e609..3c8a7039 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -221,7 +221,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH // The user code couldn't possibly (barring really weird subclassing shenanigans) be in a shippable state anyway; the implementations of these 3 methods are // all inter-related and should be written by the same entity. String msg = String.format("Not generating %s: One of equals, hashCode, and canEqual exists. " + - "You should either write all of these are none of these (in the latter case, lombok generates them).", + "You should either write all of these or none of these (in the latter case, lombok generates them).", equalsExists == MemberExistsResult.NOT_EXISTS && hashCodeExists == MemberExistsResult.NOT_EXISTS ? "equals and hashCode" : equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode"); errorNode.addWarning(msg); diff --git a/src/core/lombok/eclipse/handlers/NonNullHandler.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index 5c58069c..634cb2d9 100644 --- a/src/core/lombok/eclipse/handlers/NonNullHandler.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -21,8 +21,19 @@ */ package lombok.eclipse.handlers; +import static lombok.eclipse.Eclipse.isPrimitive; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + import java.util.Arrays; +import lombok.NonNull; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; +import lombok.eclipse.DeferUntilPostDiet; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; + import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; @@ -36,22 +47,15 @@ import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; +import org.eclipse.jdt.internal.compiler.ast.TryStatement; import org.mangosdk.spi.ProviderFor; -import lombok.NonNull; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.eclipse.DeferUntilPostDiet; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; - -import static lombok.eclipse.Eclipse.*; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; - @DeferUntilPostDiet @ProviderFor(EclipseAnnotationHandler.class) -public class NonNullHandler extends EclipseAnnotationHandler<NonNull> { +@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. +public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { @Override public void handle(AnnotationValues<NonNull> annotation, Annotation ast, EclipseNode annotationNode) { if (annotationNode.up().getKind() == Kind.FIELD) { // This is meaningless unless the field is used to generate a method (@Setter, @RequiredArgsConstructor, etc), @@ -82,6 +86,11 @@ public class NonNullHandler extends EclipseAnnotationHandler<NonNull> { if (isGenerated(declaration)) return; + if (declaration.isAbstract()) { + annotationNode.addWarning("@NonNull is meaningless on a parameter of an abstract method."); + return; + } + // Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter, // and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and // wrap all references to it in the super/this to a call to this method. @@ -98,16 +107,31 @@ public class NonNullHandler extends EclipseAnnotationHandler<NonNull> { declaration.statements = new Statement[] {nullCheck}; } else { char[] expectedName = arg.name; - for (Statement stat : declaration.statements) { - char[] varNameOfNullCheck = returnVarNameIfNullCheck(stat); - if (varNameOfNullCheck == null) break; - if (Arrays.equals(expectedName, varNameOfNullCheck)) return; + /* Abort if the null check is already there, delving into try and synchronized statements */ { + Statement[] stats = declaration.statements; + int idx = 0; + while (stats != null && stats.length > idx) { + Statement stat = stats[idx++]; + if (stat instanceof TryStatement) { + stats = ((TryStatement) stat).tryBlock.statements; + idx = 0; + continue; + } + if (stat instanceof SynchronizedStatement) { + stats = ((SynchronizedStatement) stat).block.statements; + idx = 0; + continue; + } + char[] varNameOfNullCheck = returnVarNameIfNullCheck(stat); + if (varNameOfNullCheck == null) break; + if (Arrays.equals(varNameOfNullCheck, expectedName)) return; + } } Statement[] newStatements = new Statement[declaration.statements.length + 1]; int skipOver = 0; for (Statement stat : declaration.statements) { - if (isGenerated(stat)) skipOver++; + if (isGenerated(stat) && isNullCheck(stat)) skipOver++; else break; } System.arraycopy(declaration.statements, 0, newStatements, 0, skipOver); @@ -118,6 +142,10 @@ public class NonNullHandler extends EclipseAnnotationHandler<NonNull> { annotationNode.up().up().rebuild(); } + private boolean isNullCheck(Statement stat) { + return returnVarNameIfNullCheck(stat) != null; + } + private char[] returnVarNameIfNullCheck(Statement stat) { if (!(stat instanceof IfStatement)) return null; diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java index aa78ca3b..d3a95db8 100644 --- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java @@ -30,6 +30,7 @@ import java.util.List; import lombok.SneakyThrows; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; @@ -60,6 +61,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) @DeferUntilPostDiet +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSneakyThrows extends EclipseAnnotationHandler<SneakyThrows> { private static class DeclaredException { diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index e4c58eab..f76f06ed 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java @@ -27,6 +27,7 @@ import java.lang.reflect.Modifier; import lombok.Synchronized; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.core.AST.Kind; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; @@ -52,6 +53,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) @DeferUntilPostDiet +@HandlerPriority(value = 1024) // 2^10; @NonNull must have run first, so that we wrap around the statements generated by it. public class HandleSynchronized extends EclipseAnnotationHandler<Synchronized> { private static final char[] INSTANCE_LOCK_NAME = "$lock".toCharArray(); private static final char[] STATIC_LOCK_NAME = "$LOCK".toCharArray(); |