diff options
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. |