mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 16:15:16 +00:00
Fixed issues with val in inner classes, and re-enabled a test that caught it that we ignored earlier.
This commit is contained in:
1 parent
a6170f5298
commit
e5860edabe
8 files changed
+111
-9
No files matched your search
@@ -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>();
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -183,6 +183,8 @@ public class LombokTestSource {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lc.startsWith("issue ")) continue;
|
||||
|
||||
Assert.fail("Directive line \"" + directive + "\" in '" + file.getAbsolutePath() + "' invalid: unrecognized directive.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.util.*;
|
||||
public class ValAnonymousSubclassWithGenerics {
|
||||
Object object = new Object(){
|
||||
void foo() {
|
||||
final int j = 1;
|
||||
}
|
||||
};
|
||||
void bar() {
|
||||
final int k = super.hashCode();
|
||||
int x = k;
|
||||
}
|
||||
java.util.List<String> names = new java.util.ArrayList<String>(){
|
||||
public String get(int i) {
|
||||
final java.lang.String result = super.get(i);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import java.util.*;
|
||||
import lombok.val;
|
||||
public class ValAnonymousSubclassWithGenerics {
|
||||
Object object = new Object() {
|
||||
x() {
|
||||
super();
|
||||
}
|
||||
void foo() {
|
||||
final @val int j = 1;
|
||||
}
|
||||
};
|
||||
java.util.List<String> names = new java.util.ArrayList<String>() {
|
||||
x() {
|
||||
super();
|
||||
}
|
||||
public String get(int i) {
|
||||
final @val java.lang.String result = super.get(i);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
public ValAnonymousSubclassWithGenerics() {
|
||||
super();
|
||||
}
|
||||
void bar() {
|
||||
final @val int k = super.hashCode();
|
||||
int x = k;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// ignore
|
||||
// issue 205: val inside anonymous inner classes is a bit tricky in javac, this test ensures we don't break it.
|
||||
import java.util.*;
|
||||
import lombok.val;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//issue 694: In javac, resolving the RHS (which is what val does) can cause an entire class to be resolved, breaking all usage of val inside that class. This tests that we handle that better.
|
||||
class ValWithLocalClasses1 {
|
||||
{
|
||||
lombok.val f2 = new ValWithLocalClasses2() {};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
17 The serializable class does not declare a static final serialVersionUID field of type long
|
||||
Reference in new issue
Block a user