diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-02-01 06:52:52 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-02-01 06:53:10 +0100 |
commit | e5860edabe31f3b6ceabd91f9cbcadf3d4d0315a (patch) | |
tree | b1d52306c826f384aed0ff9228029feb3f0ff88d /src | |
parent | a6170f5298daf42931877a2d9c98e6f2ad1985be (diff) | |
download | lombok-e5860edabe31f3b6ceabd91f9cbcadf3d4d0315a.tar.gz lombok-e5860edabe31f3b6ceabd91f9cbcadf3d4d0315a.tar.bz2 lombok-e5860edabe31f3b6ceabd91f9cbcadf3d4d0315a.zip |
Fixed issues with val in inner classes, and re-enabled a test that caught it that we ignored earlier.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/lombok/javac/JavacResolution.java | 55 | ||||
-rw-r--r-- | src/utils/lombok/javac/TreeMirrorMaker.java | 13 |
2 files changed, 60 insertions, 8 deletions
diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 8063d5e3..6231735c 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -24,6 +24,7 @@ package lombok.javac; import static lombok.javac.Javac.*; import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayDeque; @@ -98,7 +99,7 @@ public class JavacResolution { @Override public void visitClassDef(JCClassDecl tree) { if (copyAt != null) return; - env = enter.getClassEnv(tree.sym); + if (tree.sym != null) env = enter.getClassEnv(tree.sym); } @Override public void visitMethodDef(JCMethodDecl tree) { @@ -138,16 +139,64 @@ public class JavacResolution { EnvFinder finder = new EnvFinder(node.getContext()); while (!stack.isEmpty()) stack.pop().accept(finder); - TreeMirrorMaker mirrorMaker = new TreeMirrorMaker(node.getTreeMaker()); + TreeMirrorMaker mirrorMaker = new TreeMirrorMaker(node.getTreeMaker(), node.getContext()); JCTree copy = mirrorMaker.copy(finder.copyAt()); - attrib(copy, finder.get()); + memberEnterAndAttribute(copy, finder.get(), node.getContext()); return mirrorMaker.getOriginalToCopyMap(); } finally { messageSuppressor.enableLoggers(); } } + private static Field memberEnterDotEnv; + + private static Field getMemberEnterDotEnv() { + if (memberEnterDotEnv != null) return memberEnterDotEnv; + try { + Field f = MemberEnter.class.getDeclaredField("env"); + f.setAccessible(true); + memberEnterDotEnv = f; + } catch (NoSuchFieldException e) { + return null; + } + + return memberEnterDotEnv; + } + + @SuppressWarnings("unchecked") + private static Env<AttrContext> getEnvOfMemberEnter(MemberEnter memberEnter) { + Field f = getMemberEnterDotEnv(); + try { + return (Env<AttrContext>) f.get(memberEnter); + } catch (Exception e) { + return null; + } + } + + private static void setEnvOfMemberEnter(MemberEnter memberEnter, Env<AttrContext> env) { + Field f = getMemberEnterDotEnv(); + try { + f.set(memberEnter, env); + } catch (Exception e) { + return; + } + } + + private void memberEnterAndAttribute(JCTree copy, Env<AttrContext> env, Context context) { + MemberEnter memberEnter = MemberEnter.instance(context); + Env<AttrContext> oldEnv = getEnvOfMemberEnter(memberEnter); + setEnvOfMemberEnter(memberEnter, env); + try { + copy.accept(memberEnter); + } catch (Exception ignore) { + // intentionally ignored; usually even if this step fails, val will work (but not for val in method local inner classes and anonymous inner classes). + } finally { + setEnvOfMemberEnter(memberEnter, oldEnv); + } + attrib(copy, env); + } + public void resolveClassMember(JavacNode node) { ArrayDeque<JCTree> stack = new ArrayDeque<JCTree>(); diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java index 621e4e00..093839d7 100644 --- a/src/utils/lombok/javac/TreeMirrorMaker.java +++ b/src/utils/lombok/javac/TreeMirrorMaker.java @@ -38,6 +38,7 @@ import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeCopier; +import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; /** @@ -53,7 +54,7 @@ import com.sun.tools.javac.util.List; public class TreeMirrorMaker extends TreeCopier<Void> { private final IdentityHashMap<JCTree, JCTree> originalToCopy = new IdentityHashMap<JCTree, JCTree>(); - public TreeMirrorMaker(JavacTreeMaker maker) { + public TreeMirrorMaker(JavacTreeMaker maker, Context context) { super(maker.getUnderlyingTreeMaker()); } @@ -93,12 +94,14 @@ public class TreeMirrorMaker extends TreeCopier<Void> { return Collections.unmodifiableMap(originalToCopy); } - // Fix for NPE in HandleVal. See http://code.google.com/p/projectlombok/issues/detail?id=205 - // Maybe this should be done elsewhere... + // Monitor issue 205 and issue 694 when making changes here. @Override public JCTree visitVariable(VariableTree node, Void p) { + JCVariableDecl original = node instanceof JCVariableDecl ? (JCVariableDecl) node : null; JCVariableDecl copy = (JCVariableDecl) super.visitVariable(node, p); - copy.sym = ((JCVariableDecl) node).sym; - if (copy.sym != null) copy.type = ((JCVariableDecl) node).type; + if (original == null) return copy; + + copy.sym = original.sym; + if (copy.sym != null) copy.type = original.type; if (copy.type != null) { boolean wipeSymAndType = copy.type.isErroneous(); if (!wipeSymAndType) { |