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/core | |
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/core')
-rw-r--r-- | src/core/lombok/javac/JavacResolution.java | 55 |
1 files changed, 52 insertions, 3 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>(); |