src/share/classes/com/sun/tools/javac/code/Types.java
Print this page
@@ -371,11 +371,12 @@
case TYPEVAR:
return isSubtypeNoCapture(t.getUpperBound(), s);
case BOT:
return
s.tag == BOT || s.tag == CLASS ||
- s.tag == ARRAY || s.tag == TYPEVAR;
+ s.tag == ARRAY || s.tag == TYPEVAR ||
+ s.tag == FUNCTION;
case NONE:
return false;
default:
throw new AssertionError("isSubtype " + t.tag);
}
@@ -444,10 +445,34 @@
&& isSubtypeNoCapture(sup.getEnclosingType(),
s.getEnclosingType());
}
@Override
+ public Boolean visitMethodType(MethodType t, Type s) {
+ if (s.tsym == syms.objectType.tsym || s.tsym == syms.methodHandleType.tsym)
+ return true;
+
+ if (s.tag != FUNCTION)
+ return false;
+
+ //check covariance/contravariance
+ MethodType mType = (MethodType) s;
+ if (!(isSubtypeNoCapture(t.restype, mType.restype)))
+ return false;
+
+ List<Type> lt = t.argtypes;
+ List<Type> lmType = mType.argtypes;
+ while (lt.nonEmpty() && lmType.nonEmpty()) {
+ if (!(isSubtypeNoCapture(lmType.head, lt.head)))
+ return false;
+ lt = lt.tail;
+ lmType = lmType.tail;
+ }
+ return lt.isEmpty() && lmType.isEmpty();
+ }
+
+ @Override
public Boolean visitArrayType(ArrayType t, Type s) {
if (s.tag == ARRAY) {
if (t.elemtype.tag <= lastBaseTag)
return isSameType(t.elemtype, elemtype(s));
else
@@ -1095,10 +1120,23 @@
return isCastable(t.bound, s, warnStack.head);
}
}
@Override
+ public Boolean visitMethodType(MethodType t, Type s) {
+ if (isSubtype(t, s))
+ return true;
+ if (s.tsym == syms.methodHandleType.tsym) {
+ warnStack.head.warnUnchecked();
+ return true;
+ }
+ if (s.tag != METHOD)
+ return false;
+ return isCastable(s, t);
+ }
+
+ @Override
public Boolean visitErrorType(ErrorType t, Type s) {
return true;
}
};
// </editor-fold>
@@ -1268,10 +1306,21 @@
@Override
public Boolean visitTypeVar(TypeVar t, Void ignored) {
return false;
}
+
+ @Override
+ public Boolean visitMethodType(MethodType t, Void ignored) {
+ if (!isReifiable(t.restype))
+ return false;
+ for(List<Type> l = t.argtypes; l.isEmpty(); l = l.tail) {
+ if (!isReifiable(l.head))
+ return false;
+ }
+ return true;
+ }
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Array Utils">
public boolean isArray(Type t) {
@@ -1583,10 +1632,17 @@
public Type visitTypeVar(TypeVar t, Boolean recurse) {
return erasure(t.bound, recurse);
}
@Override
+ public Type visitMethodType(MethodType t, Boolean recurse) {
+ if (t.tag == FUNCTION)
+ return syms.methodHandleType;
+ return super.visitMethodType(t, recurse);
+ }
+
+ @Override
public Type visitErrorType(ErrorType t, Boolean recurse) {
return t;
}
};
@@ -2007,11 +2063,11 @@
throw new AssertionError();
}
@Override
public Boolean visitMethodType(MethodType t, Type s) {
- return s.tag == METHOD
+ return (s.tag == METHOD || s.tag == FUNCTION)
&& containsTypeEquivalent(t.argtypes, s.getParameterTypes());
}
@Override
public Boolean visitForAll(ForAll t, Type s) {
@@ -2098,11 +2154,11 @@
if (argtypes == t.argtypes &&
restype == t.restype &&
thrown == t.thrown)
return t;
else
- return new MethodType(argtypes, restype, thrown, t.tsym);
+ return new MethodType(t.tag, argtypes, restype, thrown, t.tsym);
}
@Override
public Type visitTypeVar(TypeVar t, Void ignored) {
for (List<Type> from = this.from, to = this.to;