diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2016-03-07 15:21:01 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2016-03-07 15:21:01 +0100 |
commit | 3378cbe65553e685afaad816c260426438aa434b (patch) | |
tree | 8ae03f26c05d6a23bde7ef546f8f04bf936c301c | |
parent | 07b8af4cc5c844c9e085e2c4662df1d08221e710 (diff) | |
download | lombok-3378cbe65553e685afaad816c260426438aa434b.tar.gz lombok-3378cbe65553e685afaad816c260426438aa434b.tar.bz2 lombok-3378cbe65553e685afaad816c260426438aa434b.zip |
@Helper is now legal in just about every place method local classes are legal. Also now no longer messes up syntax highlighting in eclipse.
Still need to investigate how to improve autocomplete presence of helper methods.
7 files changed, 94 insertions, 56 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleHelper.java b/src/core/lombok/eclipse/handlers/HandleHelper.java index 4e9a7c68..70cf35f3 100644 --- a/src/core/lombok/eclipse/handlers/HandleHelper.java +++ b/src/core/lombok/eclipse/handlers/HandleHelper.java @@ -33,12 +33,14 @@ import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Block; 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.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -48,7 +50,6 @@ import org.mangosdk.spi.ProviderFor; import lombok.ConfigurationKeys; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; -import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; import lombok.experimental.Helper; @@ -58,19 +59,33 @@ import lombok.experimental.Helper; */ @ProviderFor(EclipseAnnotationHandler.class) public class HandleHelper extends EclipseAnnotationHandler<Helper> { + private Statement[] getStatementsFromAstNode(ASTNode node) { + if (node instanceof Block) return ((Block) node).statements; + if (node instanceof AbstractMethodDeclaration) return ((AbstractMethodDeclaration) node).statements; + if (node instanceof SwitchStatement) return ((SwitchStatement) node).statements; + return null; + } + + private void setStatementsOfAstNode(ASTNode node, Statement[] statements) { + if (node instanceof Block) ((Block) node).statements = statements; + else if (node instanceof AbstractMethodDeclaration) ((AbstractMethodDeclaration) node).statements = statements; + else if (node instanceof SwitchStatement) ((SwitchStatement) node).statements = statements; + else throw new IllegalArgumentException("Can't set statements on node type: " + node.getClass()); + } + @Override public void handle(AnnotationValues<Helper> annotation, Annotation ast, EclipseNode annotationNode) { handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper"); EclipseNode annotatedType = annotationNode.up(); - EclipseNode containingMethod = annotatedType == null ? null : annotatedType.up(); - if (annotatedType == null || containingMethod == null || annotatedType.getKind() != Kind.TYPE || containingMethod.getKind() != Kind.METHOD) { + EclipseNode containingBlock = annotatedType == null ? null : annotatedType.directUp(); + Statement[] origStatements = getStatementsFromAstNode(containingBlock == null ? null : containingBlock.get()); + + if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) { annotationNode.addError("@Helper is legal only on method-local classes."); return; } TypeDeclaration annotatedType_ = (TypeDeclaration) annotatedType.get(); - AbstractMethodDeclaration amd = (AbstractMethodDeclaration) containingMethod.get(); - Statement[] origStatements = amd.statements; int indexOfType = -1; for (int i = 0; i < origStatements.length; i++) { if (origStatements[i] == annotatedType_) { @@ -105,7 +120,7 @@ public class HandleHelper extends EclipseAnnotationHandler<Helper> { if (name == null || name.length == 0 || name[0] == '<') return true; String n = new String(name); if (Arrays.binarySearch(knownMethodNames_, n) < 0) return true; - messageSend.receiver = new SingleNameReference(helperName, Eclipse.pos(messageSend)); + messageSend.receiver = new SingleNameReference(helperName, messageSend.nameSourcePosition); helperUsed[0] = true; return true; } @@ -132,6 +147,6 @@ public class HandleHelper extends EclipseAnnotationHandler<Helper> { SetGeneratedByVisitor sgbvVisitor = new SetGeneratedByVisitor(annotationNode.get()); decl.traverse(sgbvVisitor, null); newStatements[indexOfType + 1] = decl; - amd.statements = newStatements; + setStatementsOfAstNode(containingBlock.get(), newStatements); } } diff --git a/src/core/lombok/javac/handlers/HandleHelper.java b/src/core/lombok/javac/handlers/HandleHelper.java index 99131f70..d422d068 100644 --- a/src/core/lombok/javac/handlers/HandleHelper.java +++ b/src/core/lombok/javac/handlers/HandleHelper.java @@ -35,11 +35,13 @@ import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.TreeVisitor; import com.sun.source.util.TreeScanner; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCCase; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCIdent; -import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -57,21 +59,32 @@ import lombok.javac.JavacTreeMaker; @ProviderFor(JavacAnnotationHandler.class) public class HandleHelper extends JavacAnnotationHandler<Helper> { + private List<JCStatement> getStatementsFromJcNode(JCTree tree) { + if (tree instanceof JCBlock) return ((JCBlock) tree).stats; + if (tree instanceof JCCase) return ((JCCase) tree).stats; + return null; + } + + private void setStatementsOfJcNode(JCTree tree, List<JCStatement> statements) { + if (tree instanceof JCBlock) ((JCBlock) tree).stats = statements; + else if (tree instanceof JCCase) ((JCCase) tree).stats = statements; + else throw new IllegalArgumentException("Can't set statements on node type: " + tree.getClass()); + } + @Override public void handle(AnnotationValues<Helper> annotation, JCAnnotation ast, JavacNode annotationNode) { handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper"); deleteAnnotationIfNeccessary(annotationNode, Helper.class); JavacNode annotatedType = annotationNode.up(); - JavacNode containingMethod = annotatedType == null ? null : annotatedType.up(); + JavacNode containingBlock = annotatedType == null ? null : annotatedType.directUp(); + List<JCStatement> origStatements = getStatementsFromJcNode(containingBlock == null ? null : containingBlock.get()); - if (annotatedType == null || containingMethod == null || annotatedType.getKind() != Kind.TYPE || containingMethod.getKind() != Kind.METHOD) { + if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) { annotationNode.addError("@Helper is legal only on method-local classes."); return; } JCClassDecl annotatedType_ = (JCClassDecl) annotatedType.get(); - JCMethodDecl amd = (JCMethodDecl) containingMethod.get(); - List<JCStatement> origStatements = amd.body.stats; Iterator<JCStatement> it = origStatements.iterator(); while (it.hasNext()) { if (it.next() == annotatedType_) { @@ -133,6 +146,6 @@ public class HandleHelper extends JavacAnnotationHandler<Helper> { JCVariableDecl decl = maker.VarDef(maker.Modifiers(Flags.FINAL), helperName, varType, init); newStatements.append(decl); } - amd.body.stats = newStatements.toList(); + setStatementsOfJcNode(containingBlock.get(), newStatements.toList()); } } diff --git a/test/transform/resource/after-delombok/Helper.java b/test/transform/resource/after-delombok/Helper.java index 52f50dd2..64ecb492 100644 --- a/test/transform/resource/after-delombok/Helper.java +++ b/test/transform/resource/after-delombok/Helper.java @@ -1,15 +1,18 @@ class HelperTest { - void test() { - class H1 { - void foo() { - System.out.println("Hello"); + { + final int z = 5; + if (Boolean.TRUE) { + class H1 { + void foo(int x) { + System.out.println("Hello, " + (x + z)); + } } - } - final H1 $H1 = new H1(); - $H1.foo(); - class H2 { - void bar() { - $H1.foo(); + final H1 $H1 = new H1(); + $H1.foo(10); + class H2 { + void bar() { + $H1.foo(12); + } } } } diff --git a/test/transform/resource/after-ecj/Helper.java b/test/transform/resource/after-ecj/Helper.java index 1b4e8bd2..44c2a171 100644 --- a/test/transform/resource/after-ecj/Helper.java +++ b/test/transform/resource/after-ecj/Helper.java @@ -1,26 +1,30 @@ import lombok.experimental.Helper; class HelperTest { + { + final int z = 5; + if (Boolean.TRUE) + { + @Helper class H1 { + H1() { + super(); + } + void foo(int x) { + System.out.println(("Hello, " + (x + z))); + } + } + final H1 $H1 = new H1(); + $H1.foo(10); + @Helper class H2 { + H2() { + super(); + } + void bar() { + $H1.foo(12); + } + } + } + } HelperTest() { super(); } - void test() { - @Helper class H1 { - H1() { - super(); - } - void foo() { - System.out.println("Hello"); - } - } - final H1 $H1 = new H1(); - $H1.foo(); - @Helper class H2 { - H2() { - super(); - } - void bar() { - $H1.foo(); - } - } - } } diff --git a/test/transform/resource/before/Helper.java b/test/transform/resource/before/Helper.java index 145d740f..cec9c7ce 100644 --- a/test/transform/resource/before/Helper.java +++ b/test/transform/resource/before/Helper.java @@ -1,18 +1,21 @@ import lombok.experimental.Helper; class HelperTest { - void test() { - @Helper class H1 { - void foo() { - System.out.println("Hello"); + { + final int z = 5; + if (Boolean.TRUE) { + @Helper class H1 { + void foo(int x) { + System.out.println("Hello, " + (x + z)); + } } - } - - foo(); - - @Helper class H2 { - void bar() { - foo(); + + foo(10); + + @Helper class H2 { + void bar() { + foo(12); + } } } } diff --git a/test/transform/resource/messages-delombok/Helper.java.messages b/test/transform/resource/messages-delombok/Helper.java.messages index 05260c0b..bf780b03 100644 --- a/test/transform/resource/messages-delombok/Helper.java.messages +++ b/test/transform/resource/messages-delombok/Helper.java.messages @@ -1 +1 @@ -13 No methods of this helper class are ever used.
\ No newline at end of file +15 No methods of this helper class are ever used.
\ No newline at end of file diff --git a/test/transform/resource/messages-ecj/Helper.java.messages b/test/transform/resource/messages-ecj/Helper.java.messages index 7207e136..4193dfe2 100644 --- a/test/transform/resource/messages-ecj/Helper.java.messages +++ b/test/transform/resource/messages-ecj/Helper.java.messages @@ -1 +1 @@ -13 No methods of this helper class are ever used. +15 No methods of this helper class are ever used. |