aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/lombok/javac/JavacResolution.java62
1 files changed, 58 insertions, 4 deletions
diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java
index 9a0077a7..98bf3c4b 100644
--- a/src/core/lombok/javac/JavacResolution.java
+++ b/src/core/lombok/javac/JavacResolution.java
@@ -28,7 +28,10 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.Map;
+import java.util.NoSuchElementException;
import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
@@ -40,6 +43,7 @@ import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.code.Type.CapturedType;
import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.TypeVar;
import com.sun.tools.javac.code.Type.WildcardType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.Attr;
@@ -59,6 +63,7 @@ import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
import lombok.Lombok;
import lombok.core.debug.AssertionLogger;
@@ -314,6 +319,37 @@ public class JavacResolution {
return result;
}
+ private static Iterable<? extends Type> concat(final Type t, final Collection<? extends Type> ts) {
+ if (t == null) return ts;
+
+ return new Iterable<Type>() {
+ @Override public Iterator<Type> iterator() {
+ return new Iterator<Type>() {
+ private boolean first = true;
+ private Iterator<? extends Type> wrap = ts == null ? null : ts.iterator();
+ @Override public boolean hasNext() {
+ if (first) return true;
+ if (wrap == null) return false;
+ return wrap.hasNext();
+ }
+
+ @Override public Type next() {
+ if (first) {
+ first = false;
+ return t;
+ }
+ if (wrap == null) throw new NoSuchElementException();
+ return wrap.next();
+ }
+ };
+ }
+ };
+ }
+
+ private static int compare(Name a, Name b) {
+ return a.compareTo(b);
+ }
+
private static JCExpression typeToJCTree0(Type type, JavacAST ast, boolean allowCompound, boolean allowVoid, boolean allowCapture) throws TypeNotConvertibleException {
// NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too.
// -- so we write our own take on that here.
@@ -335,12 +371,30 @@ public class JavacResolution {
if (symbol.name.length() == 0) {
// Anonymous inner class
if (type instanceof ClassType) {
- List<Type> ifaces = ((ClassType) type).interfaces_field;
+ Type winner = null;
+ int winLevel = 0; // 100 = array, 50 = class, 20 = typevar, 15 = wildcard, 10 = interface, 1 = Object.
Type supertype = ((ClassType) type).supertype_field;
- if (isObject(supertype) && ifaces != null && ifaces.length() > 0) {
- return typeToJCTree(ifaces.get(0), ast, allowCompound, allowVoid, allowCapture);
+ List<Type> ifaces = ((ClassType) type).interfaces_field;
+ for (Type t : concat(supertype, ifaces)) {
+ int level = 0;
+ if (t instanceof ArrayType) level = 100;
+ else if (t instanceof TypeVar) level = 20;
+ else if (t instanceof WildcardType) level = 15;
+ else if (t.isInterface()) level = 10;
+ else if (isObject(t)) level = 1;
+ else if (t instanceof ClassType) level = 50;
+ else level = 5;
+
+ if (winLevel > level) continue;
+ if (winLevel < level) {
+ winner = t;
+ winLevel = level;
+ continue;
+ }
+ if (compare(winner.tsym.getQualifiedName(), t.tsym.getQualifiedName()) < 0) winner = t;
}
- if (supertype != null) return typeToJCTree(supertype, ast, allowCompound, allowVoid, allowCapture);
+ if (winner == null) return createJavaLangObject(ast);
+ return typeToJCTree(winner, ast, allowCompound, allowVoid, allowCapture);
}
throw new TypeNotConvertibleException("Anonymous inner class");
}